displaying public virtual property in MVC - c#

Hi I have the following model:
public class ActiveProducts
{
public int ID { get; set; }
public virtual Product Product { get; set; }
}
and for data context I have:
public DbSet<ActiveProduct> ActiveProducts { get; set; }
I wanted to create a controller and views to do the CRUD operations
How would I be able to generate a view for the create and edit so that I have a drop down list of products?
I used the standard method of creating a controller using the model, with the CRUD operations and it didn't render out anything for the create.

Okay, since Product_ID holds the primary key value of the Products table, then this should work in your controller:
public ActionResult Create()
{
ViewBag.Product_ID = new SelectList(db.Product, "ID", "Product");
}
[HttpPost]
public ActionResult Create([Bind(Include = "ID, Product_ID" /*etc*/)] ActiveProducts activeProducts)
{
ViewBag.Product_ID = new SelectList(db.Product, "ID", "Product", activeProducts.Product_ID);
}
then in your Create View:
<div class="form-group">
#Html.LabelFor(model => model.Product_ID, "Product:", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Product_ID", null, "-- Select Product --", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Product_ID, "", new { #class = "text-danger" })
</div>
</div>

Related

Populating DropDownList in ASP.NET MVC

Following code is to create users. I have a user class, I need to create users here. But I have department id's on a person and that department id refers to another table in the database whose name is Department.
public ActionResult Create()
{
// disable lazy because of error it creates
_db.Configuration.LazyLoadingEnabled = false;
var data = _db.Departments.OrderBy(a => a.DepartmentId).ToList();
ViewData["DepartmentList"] = data;
return View();
}
Here is View:
#{
var departmentLists = ViewData["DepartmentList"]; // Cast the list
}
<div class="form-group">
#Html.LabelFor(model => model.Department, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.Department, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Department, "", new { #class = "text-danger" })
</div>
</div>
This model.department part is the where i lost. I need to list my department in order of the list, when user select, i want to select the id of the department.
Like this;
So I want the user to see
Department Name + SubDepartment name
and when they choose from the list, the chosen thing is
departmentid
so I can add in the database like that.
Here is my Create Post method:
public ActionResult Create([Bind(Include = "ID,LastName,FirstMidName,EnrollmentDate,Email,Department,Position,Active")] User user)
{
if (ModelState.IsValid)
{
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
Her is my User class;
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int DepartmentId { get; set; }
// Other fields removed for brevity
}
Here is Department class;
public class Department
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public string SubDepartmentName { get; set; }
}
Write your Create GET method as follows:
public ActionResult Create()
{
// disable lazy because of error it creates
_db.Configuration.LazyLoadingEnabled = false;
var departmentList = _db.Departments.Select(d => new
{
d.DepartmentId,
DepartmentName = d.DepartmentName + " " + d.SubDepartmentName
}).OrderBy(a => a.DepartmentId).ToList();
ViewBag.DepartmentList = new SelectList(departmentList,"DepartmentId","DepartmentName");
return View();
}
Then in the view:
<div class="form-group">
#Html.LabelFor(model => model.DepartmentId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("DepartmentId", ViewBag.DepartmentList as SelectList, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.DepartmentId, "", new { #class = "text-danger" })
</div>
</div>
Another problem is in your Create POST method. You are not allowing you DepartmentId to pass in your Bind include list. Please update you Create POST method as follows:
public ActionResult Create([Bind(Include = "ID,LastName,FirstMidName,EnrollmentDate,Email,DepartmentId,Position,Active")] User user)
{
if (ModelState.IsValid)
{
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}

In asp.net, MVC, how to show content of original data after clicked EDIT method

I don't know if you can understand my question but I am trying to making this clear.
For now, I have some methods in my controller. And When I click Edit, it supposed to show the original things like the following. But instead of that, I got Nothing in the text boxes. I hope someone could me some advice, thanks!
Here is my Edit Method in the controller.
[HttpGet]
public ActionResult Edit(string programid)
{
Program program = db.Programs.Find(programid);
return View(program);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ProgramID,SerialNo,ProgramName,SubmissionDeadline,LevelID,DepartmentID,HierachyL1,HierachyL2,R1,R2,R3,R4,R5,AwardAmount,DateReleased,DatePosted,DateOpen,InternalDueDate,Area1,Area2,Area3,Weblink,Word,AgencyID")]Program program)
{
try
{
if (ModelState.IsValid)
{
db.Entry(program).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("All");
}
return View(program);
}
catch(DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again");
PopulateDepartmentDropDownList(program.DepartmentID);
}
return View(program);
}
For the Model, I just have some variables.
[Table("[RP_Program]")]
public class Program
{
[Key]
public string ProgramID { get; set; }
public string SerialNo { get; set; }
public string ProgramName { get; set; }
public DateTime? SubmissionDeadline { get; set; }
public int AgencyID { get; set; }
}
For the view, Here is part of it, most codes are the same.
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Program</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ProgramID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProgramID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProgramID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SerialNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SerialNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SerialNo, "", new { #class = "text-danger" })
</div>
</div>
What you need to fix is changing argument name to match controller action method argument in ActionLink helper:
View
#Html.ActionLink("Edit", "Edit", "ControllerName", new { programid = item.ProgramID })
Controller
public ActionResult Edit(string programid)
{
Program program = db.Programs.Find(programid);
return View(program);
}
The previous setup tries to pass the value into id argument which doesn't actually exist in Edit action method:
// incorrect
#Html.ActionLink("Edit", "Edit", new { id = item.ProgramID })
The problem is the parameter names don't match. ASP.NET matches the names to see which parameter gets which value. So in using:
#Html.ActionLink("Edit", "Edit", new { id = item.ProgramID })
You are sending a parameter with name id, but your Edit routine is looking for a parameter called programid:
public ActionResult Edit(string programid)
You need to change one of the parameter names so that they match.

Update ViewModel after dynamically updating the view

I am trying to define ViewModels that faithfully represent the view (to make strict use of that concept).
Some of the elements of the ViewModel are updated dynamically. The problem I have, is that when I do the Post, the ViewModel returns without the elements that were updated dynamically.
The update is done through jQuery, when an event is performed. An action is invoked through Url.Action, and a Div is updated.
I made an example to clarify the scenario. An application that only stores a location (state and city). For this I have three ViewModels: one to represent the States in a SelectList, one to represent the Cities in a SelectList, and finally one to represent the Location (formed by the two ViewModel that I mentioned first).
Models:
public class State
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int StateId { get; set; }
public virtual State State { get; set; }
}
ViewModels:
public class CitySelectListViewModel
{
public CitySelectListViewModel() { }
public CitySelectListViewModel(IEnumerable<Models.City> cities)
{
this.Cities = cities;
}
[Display(Name = "Cities")]
[Required]
public int? SelectedCityId { get; set; }
public IEnumerable<City> Cities { get; }
}
public class StateSelectListViewModel
{
public StateSelectListViewModel() { }
public StateSelectListViewModel(IEnumerable<State> states)
{
this.States = states;
}
[Display(Name = "States")]
[Required]
public int? SelectedStateId { get; set; }
public IEnumerable<State> States { get; }
}
public class LocationCreateViewModel
{
public LocationCreateViewModel() { }
public LocationCreateViewModel(ICollection<State> states)
{
this.StateSelectListViewModels = new StateSelectListViewModel(states);
this.CitySelectListViewModel = new CitySelectListViewModel();
}
public StateSelectListViewModel StateSelectListViewModels { set; get; }
public CitySelectListViewModel CitySelectListViewModel { set; get; }
}
Location [Controller]:
public class LocationController : Controller
{
private DALDbContext db = new DALDbContext();
// GET: Location/Create
public ActionResult Create()
{
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel(db.States.ToList());
return View(locationCreateViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(LocationCreateViewModel pLocationCreateViewModel)
{
if (ModelState.IsValid)
{
//db.States.Add(state);
//db.SaveChanges();
return RedirectToAction("Index", "Home");
}
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel(db.States.ToList());
return View(locationCreateViewModel);
}
public ActionResult CitySelectList(int? stateId)
{
CitySelectListViewModel citySelectListViewModel = new CitySelectListViewModel(db.Cities.Where(c => c.StateId == stateId).ToList());
return View(citySelectListViewModel);
}
}
Create [View]:
#model ViewModelExample.ViewModels.LocationCreateViewModel
....
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>State</h4>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StateSelectListViewModels.SelectedStateId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.StateSelectListViewModels.SelectedStateId, new SelectList(Model.StateSelectListViewModels.States, "Id", "Name"), "Select a State", htmlAttributes: new { #class = "form-control", #id = "StateSelectList" })
#Html.ValidationMessageFor(model => model.StateSelectListViewModels.SelectedStateId, "", new { #class = "text-danger" })
</div>
</div>
<div id="CityContainer">
#Html.Action("CitySelectList")
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
// Fill City DropDownList
$('#StateSelectList').change(function () {
var selectedStateId = this.value;
$('#CityContainer').load('#Url.Action("CitySelectList")?stateId=' + selectedStateId);
});
});
</script>
}
CitySelectList [View]:
#model ViewModelExample.ViewModels.CitySelectListViewModel
....
<div class="form-group">
#Html.LabelFor(model => model.SelectedCityId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedCityId, new SelectList(Model.Cities, "Id", "Name"), "Select a City", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SelectedCityId, "", new { #class = "text-danger" })
</div>
</div>
I will show the execution of my example, and I will show the problem through the inspection of the ViewModel that I receive after the Post:
I select a State and a City, and I press Create.
I inspect the ViewModel received after the Post. We can see how CitySelectListViewModel is null, and what I want is to bring the last ViewModel that was updated through jQuery.
I admit that I have provided a long example, but it is the only way I found to explain what I need. Thanks in advance.
VS-Project of the example
I'ts because you are preventing the modelBinder to accurately bind to LocationCreateViewModel in your Create action when replacing the inner HTML of <div id="CityContainer"> (thats what you do with $('#CityContainer').load(...). You instruct the model binder to bind to
#model ViewModelExample.ViewModels.CitySelectListViewModel and as a result you get this HTML for the city select list:
One way of solving this is modifying CitySelectList.cshtml to:
#model ViewModelExample.ViewModels.LocationCreateViewModel
#{
Layout = null;
}
<div class="form-group">
#Html.LabelFor(model => model.CitySelectListViewModel.SelectedCityId,
htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model =>
model.CitySelectListViewModel.SelectedCityId, new
SelectList(Model.CitySelectListViewModel.Cities, "Id", "Name"), "Select a City", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CitySelectListViewModel.SelectedCityId, "", new { #class = "text-danger" })
</div>
</div>
and your CitySelectList action to:
public ActionResult CitySelectList(int? stateId)
{
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel();
locationCreateViewModel.CitySelectListViewModel = new CitySelectListViewModel(db.Cities.Where(c => c.StateId == stateId).ToList());
return View(locationCreateViewModel);
}
But I would recommend custom model binding as well.

DropDownList To be Selected on Edit using ViewModel [duplicate]

This question already has answers here:
MVC5 - How to set "selectedValue" in DropDownListFor Html helper
(5 answers)
Closed 5 years ago.
I'm trying to populate the edit view with data which has dropdownlists using ViewModel . The data populates but the Dropdownlists are not selected as per the data.
Have checked similar issues in SO like [SO1][1] , SO2 , SO3 but not able to resolve . Know it might be something silly I'm missing but unable to find.
Code:
Viewmodel:
public class ProductVM
{
public int ID { get; set; }
[Required]
[DisplayName("Product Name")]
public string ProductName { get; set; }
public int SupplierID { get; set; }
public IEnumerable<SelectListItem> Suppliers { get; set; }
public Supplier Supplier { get; set; }
public int UnitID { get; set; }
public IEnumerable<SelectListItem> Units { get; set; }
public Unit Unit { get; set; }
public int ItemCategoryID { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
[DisplayName("Categories")]
public ItemCategory ItemCategory { get; set; }
}
Controller Edit :
public ActionResult Edit(int id)
{
var productVM = GetProductById(id);
return View(productVM);
}
private ProductVM GetProductById(int id)
{
Product product = db.Products.Find(id);
var productVM = new ProductVM();
var suppliers = new SelectList(db.Suppliers, "ID", "SupplierName", product.SupplierID);
productVM.Suppliers = suppliers.ToList();
var categories = new SelectList(db.ItemCategories, "ID", "Name", product.ItemCategoryID);
productVM.Categories = categories.ToList();
var units = new SelectList(db.Units, "ID", "Name", product.UnitID);
productVM.Units = units.ToList();
}
View :
<div class="form-group">
#Html.LabelFor(model => model.ProductName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductName, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SupplierID, "SupplierID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(u => u.SupplierID, Model.Suppliers, "--Select--")
#Html.ValidationMessageFor(model => model.SupplierID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.UnitID, "UnitID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(u => u.UnitID, (IEnumerable<SelectListItem>)Model.Units, "--Select--")
#Html.ValidationMessageFor(model => model.UnitID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ItemCategoryID, "ItemCategoryID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(u => u.ItemCategoryID, (IEnumerable<SelectListItem>)Model.Categories, "--Select--")
#Html.ValidationMessageFor(model => model.ItemCategoryID, "", new { #class = "text-danger" })
</div>
</div>
Appreciate any help. Thanks in advance.
[1]: Binding Viewmodel Property to dropdown selected item in razor
to-dropdown-selected-item-in-razor
Whatever you set in the selectedValue parameter in the SelectList is going to be ignored. Why? Because you have a strongly typed view and you are binding SupplierID property of ProductVM to the dropdown. In your GetProductById method, you are not actually populating the productVM.SupplierID, UnitID and ItemCategoryID. So they will have the default int value, 0.
So you can change you method to this:
private ProductVM GetProductById(int id)
{
Product product = db.Products.Find(id);
var productVM = new ProductVM
{
// No need to pass the 4th parameter "selectedValue" in SelectList.
Suppliers = new SelectList(db.Suppliers, "ID", "SupplierName"),
Categories = new SelectList(db.ItemCategories, "ID", "Name"),
Units = new SelectList(db.Units, "ID", "Name"),
// Populate these properties
SupplierID = product.SupplierID,
ItemCategoryID = product.ItemCategoryID,
UnitID = product.UnitID
};
return productVM ;
}
The optional selectedValue parameter is usually used when we're not using strongly typed views. If you were to change your View to the following, then your dropdown would have pre selected the value:
#Html.DropDownList("Supplier", Model.Suppliers, "--Select--")
You would want to set an initial value into your selected values in the controller before passing the model to the view if you want the dropdownlists to load with a pre-selected value. For example:
public ActionResult Edit(int id)
{
var productVM = GetProductById(id);
//Set your pre-determined values here and they will show up on the view once binded
productVM.SupplierID = 1;
productVM.UnitID = 1;
productVM.ItemCategoryID = 1;
return View(productVM);
}
This question does a great job of breaking that process down: How to get DropDownList SelectedValue in Controller in MVC

C# visual studio asp.net adding an item to a list attribute NullAttribute Exception: [duplicate]

I am currently working on a project to model a bikestore. In my 'Order' object, I have a lis object for the Bike items on the order. How would I add bikes to this list? I.E I want to display a list of availiable bikes in the Create view, an add one or more of them to the order.
My Controller:
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderNumber,CustomerName,OrderDate,PickupDate,TotalCost,PaymentMethod")] Order order)
{
if (ModelState.IsValid)
{
db.Orders.Add(order);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(order);
}
My Inventory model
public class Inventory
{
public int Id { get; set; }
public string SerialNumber { get; set; }
public virtual Store Store { get; set; }
public int? StoreId { get; set; }
public string Model { get; set; }
public string Description { get; set; }
public Decimal InventoryCost { get; set; }
public Decimal RecSalePrice { get; set; }
public Decimal SalePrice { get; set; }
public string PaymentMethod { get; set; }
public virtual BikeCategory Category { get; set; }
public int? CategoryId { get; set; }
}
My Order model:
namespace BikeStore.Models
{
public class Order
{
public Order()
{
OrderedItems = new List<Inventory>();
}
public string CustomerName { get; set; } //FROM CONTROLLER User.Identity.Name
public virtual List<Inventory> OrderedItems { get; set; }
[Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int OrderNumber { get; set; }
In the create view for orders:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Order</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.CustomerName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CustomerName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CustomerName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OrderDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PickupDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PickupDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PickupDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TotalCost, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TotalCost, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TotalCost, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PaymentMethod, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PaymentMethod, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PaymentMethod, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Start by creating view models to represent what you want to display/edit in the view (add display and validation attributes as appropriate)
public class InventoryVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class OrderVM
{
public string PaymentMethod { get; set; }
public List<InventoryVM> Inventory { get; set; }
}
Note that CustomerName, OrderDate and Total are not appropriate (you don't want a user editing these - they should be set in the POST method immediately before saving the order). Not sure what PickupDate represents but if its the actual date then that's not appropriate either (it would be set separately when the order is collected). I would also suggest that PaymentMethod be an enum or collection of PaymentType's and that you and use a dropdownlist in the view for selection.
Then the GET method would be
public ActionResult Create()
{
// Get all available bikes, for example
var inventory = db.Inventory;
OrderVM model = new OrderVM
{
Inventory = inventory.Select(i => new
{
ID = i.ID,
Name = i.Model // modify this to suit what you want to display in the view
}).ToList()
};
return View(model);
}
And in the view
#model yourAssembly.OrderVM
#using (Html.BeginForm())
{
for(int i = 0; i < Model.Inventory.Count; i++)
{
#Html.HiddenFor(m => m.Inventory[i].ID)
#Html.CheckBoxFor(m => m.Inventory[i].IsSelected)
#Html.LabelFor(m => m.Inventory[i].IsSelected, Model.Inventory[i].Name)
}
#Html.TextBoxFor(m => m.PayentMethod)
<input type="submit" value="Create" />
}
And the POST method would be
public ActionResult Create(OrderVM model)
{
// Initialize a new Order and map properties from view model
var order = new Order
{
CustomerName = User.Identity.Name,
OrderDate = DateTime.Now,
....
PaymentMethod = model.PaymentMethod
}
// Save the order so that you now have its `ID`
IEnumerable<int> selectedItems = model.Inventory.Where(i => i.IsSelected).Select(i => i.ID);
foreach(var item in selectedItems)
{
// You have not shown the model for this so just guessing
var orderItem = new OrderItem{ OrderID = order.Id, InventoryId = item };
db.OrderItems.Add(orderItem);
}
db.SaveChanges();
}
Side notes:
If you want to be able to allow users to select more that one of any
item, the you could change bool IsSelected to say int Quantity
If you you want to display additional information about the items,
say Description and Cost you can include additional properties
in the InventoryVM view model and display them with
#Html.DisplayFor(m => m.Inventory[i].Description)
If you want to display a total cost for all selected items in the
view, you will need to use javascript/jquery
If ModelState could be invalid, you will need to repopulate the
properties of InventoryVM before you return the view (as shown
only the ID and IsSelected properties post back) or include
hidden inputs for the other properties in the view

Categories

Resources