MVC - Missing Property Data in Details, Edit, and Delete Views - c#

I'm new to programming and having some trouble with a MVC 5 project. Specifically, within the auto-generated views details, edit and delete. Data is missing for fields which pull data from another model/table.
A have a table with form data known as "Shoutouts." Include is the user's first and last name, and a class known as "Level" which contains a weighted value with a name and an Id.
I was able to work around this by discovering how to use .Inlcude() in the ActionResult for the Index.
public ActionResult Index(string sortOrder)
{
var allShoutouts = db.Shoutouts
.Include(s => s.User)
.Include(s => s.Level);
return View(allShoutouts);
}
But I don't understand how to do it in the other views as well since they need the ShoutoutId to passed through the return.
public ActionResult Details(int? id)
{
ShoutoutFormViewModel SFVM = new ShoutoutFormViewModel();
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Shoutout shoutout = db.Shoutouts.Find(id);
if (shoutout == null)
{
return HttpNotFound();
}
return View(shoutout);
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Shoutout shoutout = db.Shoutouts.Find(id);
if (shoutout == null)
{
return HttpNotFound();
}
return View(shoutout);
}
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Shoutout shoutout = db.Shoutouts.Find(id);
if (shoutout == null)
{
return HttpNotFound();
}
return View(shoutout);
}
Here's what the page looks like for delete as an example of the issue.
I couldn't find any similar questions on Stack Overflow or Google so any help is appreciated.

since you have the id:
var shoutout = db.Shoutouts
.Include(s => s.User)
.Include(s => s.Level)
.Single(s => s.Id == id);
return View(allShoutouts);

Related

using same ActionLink call two function master and details in same Controller c#

i am new in MVC5. I am trying to load master and details data using ActionResult for retrieving master data and JsonResult for Details retrieving data single click in ActionLink.
public JsonResult getOrderDetails(int? id)
{
List<OrderDetail> OrderDetail = new List<OrderDetail>();
OrderDetail = db.OrderDetails.Where(a => a.OrderID==id).OrderBy(a => a.OrderDetialsID).ToList();
return new JsonResult { Data = OrderDetail, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
OrderMaster OrderMaster = db.OrderMasters.Find(id);
return View(OrderMaster);
}
No, this won't work. It will throw an exception explaining that a link must point to exactly one resource (a.k.a one Controller, one Action). Also, that's not how you normally think of doing it in MVC. This is not WebForms where you load the master and detail separately.
You should be doing something like this instead:
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var orderMaster = db.OrderMasters
.Where(om => om.OrderMasterId == id)
.Include(om => om.OrderDetails) // include the details here
.Single();
return View(orderMaster);
}

DeleteOnSubmit() and SubmitChanges() don't work. No exception or error. InsertOnSubmit() works fine

I got this code to Delete a Category row from a Database. The Category has only 2 columns: Id and Name.
It doesn't announce any errors. It just doesn't work.
If it worked, it should Redirect to Categories/Index. Instead, it shows Categories/Delete but now without any Category as parameter.
public ActionResult Delete(int id)
{
var category = db.Categories.Where(r => r.Id == id).SingleOrDefault();
return View(category);
}
[HttpPost]
public ActionResult Delete(Category category)
{
try
{
Category c = db.Categories
.Where(r => r.Id == category.Id)
.Single<Category>();
db.Categories.DeleteOnSubmit(c);
db.SubmitChanges();
return RedirectToAction("Index");
}
catch
{
return View(category);
}
}
But this code for the Create action works just fine:
public ActionResult Create()
{
Category c = new Category();
return View(c);
}
[HttpPost]
public ActionResult Create(Category category)
{
try
{
Category x = new Category
{
Name = category.Name
};
db.Categories.InsertOnSubmit(x);
db.SubmitChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Turns out the row I wanted to test the Delete functionality on was referenced as a foreign key by another table in the database.
I tested deleting a row that was not referenced by any other table. Works just fine.

Viewmodel returning no data

Been trying to follow some online examples, with the aim of moving away from using models for my views, to using viewmodels.
I have a model called 'Property' and i have created a ViewModel called 'PropertyIndexViewModel', which my view is now referencing.
My controller action is:
// GET: Property ***TEST***
public async Task<ActionResult> Index1(int? id, PropertyIndexViewModel viewModel)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Property property = await db.Property.FindAsync(id);
if (property == null)
{
return HttpNotFound();
}
return View(viewModel);
}
My view isn't throwing any errors, but it's also not returning the expected data from the model?
You have to initialize the view model, fill it with the Property model data and return it.
// GET: Property ***TEST***
public async Task<ActionResult> Index1(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Property property = await db.Property.FindAsync(id);
if (property == null)
{
return HttpNotFound();
}
var viewModel = new PropertyIndexViewModel {
Prop1 = property.Prop1
// your stuff
};
return View(viewModel);
}
In your view you have to specify the model:
#model PropertyIndexViewModel

Fix error with route url in Asp.Net MVC 5

I have this datamodel:
so one Project has many Milestones.
What I did is this: when I go to the detail of a specific Project, I can add/create Milestones for it, like in the picture:
When I click "Create Milestone" I navigate to the View where I can create the milestone for this specific Project, when I click save, it will automatically be saved for this project. Here the HttpPost method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateMilestone([Bind(Include = "Name,Description,FromDate,DueDate,Finished,ProjectID")] Milestone milestone, int? id)
{
if (ModelState.IsValid)
{
var forProject = db.Projects.Where(x => x.ID == id).FirstOrDefault();
if (forProject != null)
{
milestone.Project = forProject;
db.Milestones.Add(milestone);
db.SaveChanges();
return RedirectToAction("Details", forProject);
}
else
{
return HttpNotFound();
}
}
else
{
return View(milestone);
}
}
Here is a screenshot of the CreateMilestone View, and focus on the url (it's localhost:xxxxx/Projects/CreateMilestone/3002). The id parameter in the CreateMilestone method is for the Project ID, and in the url the id (3002) is also for the project.
I'm trying to make the app to navigate to the Details view of that specific Project I just added a milestone, which I do actually!
And as you see it works:
But: look at the url! Instead of being localhost:xxxxx/Projects/Details/3002 it is: http://localhost:55623/Projects/Details/3002?Milestones=System.Collections.Generic.HashSet%601%5BTheProjectManager.Models.Milestone%5D&Users=System.Collections.Generic.HashSet%601%5BTheProjectManager.Models.ApplicationUser%5D&ProjectName=Testing&Description=Testing%20data
So, how can I make the url be like: localhost:xxxxx/Projects/Details/3002 when I navigate to the details view after adding a new milestone?
UPDATE:
the Get Details:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return View(project);
}
and the Get CreateMilestone:
public ActionResult CreateMilestone(int? id)
{
var forProject = db.Projects.Where(x => x.ID == id).FirstOrDefault();
if (forProject != null)
{
return View();
}
else
{
return HttpNotFound();
}
}
In this line
return RedirectToAction("Details", forProject);
you are redirecting to Details action and as parameter you send "Project" object which is serialized to query string. Instead of full object you can use only id. But you also need to change Details action to accept int as parameter instead of Project class
Instead of return RedirectToAction("Details",forProject);
try this return RedirectToAction("Details", new { id = id });

Edit order details in ASP.NET MVC

The standard way to edit a record in ASP.NET MVC is the following:
//
// GET: /Movies/Edit/5
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
//
// POST: /Movies/Edit/5
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
The problem is that I need to edit order details (1 order, many details) and therefore based on two IDs (the order and the product ones). It does not work (I cannot get an OrderDetail item as action parameter). How can I solve this problem?
Thanks.
//
// GET: /Orders/EditDetails
public ActionResult EditDetails(int id, string productID)
{
OrderDetail od = GetOrderDetail(id, productID);
return View(od);
}
//
// POST: /Orders/EditDetails
[HttpPost]
public ActionResult EditDetails(OrderDetail od)
{
if (ModelState.IsValid)
{
context.Entry(od).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
return View(od);
}
EDIT: Here is the code requested by Shimmy:
#using (Html.BeginForm("EditDetails", "Orders", FormMethod.Post))
{
#Html.LabelFor(m => m.quantity)
#Html.TextBoxFor(m => m.quantity)
#Html.LabelFor(m => m.productID)
#Html.DropDownListFor(m => m.productID, new SelectList((IEnumerable)ViewBag.productList, "productID", "fullProductName"))
#Html.HiddenFor(model => model.orderID)
}
Make sure the OrderDetail.Id itself as well as the OrderDetail.OrderId and the OrderDetail.MovieId properties are all present in the form as a hidden field.
In that way, when you post it back to the server you have track on what Movie and Order this OrderDetail is of, in the action.

Categories

Resources