简体   繁体   中英

MVC.Net binding complex models?

I have the following code, with an existing customer. I need to create a form that created an Order, and pass it to my Controller.

I tried changing my model type on that page to Order instead of Customer, but then I'm gonna have to pass the Order object as well, or at least the OrderId.

Models

public class Customer
{
   public int Id { set; get; }
   public string FirstName { set; get; }
   public string LastName { set; get; }
   public List<Order> Orders { get; set;}
}

public class Order
{
   public int Id { set; get; }
   public string ItemName { set; get; }
   public DateTime SomeDate { set; get; }
}

Controller

public class OrderController : Controller
{
   [HttpPost]
   public Create ActionResult(Customer customer)
   {
      // Customer doesn't have the values that it suppose to have
      // All fields including the array of orders are null
      customerStorage.UpdateOrders(customer);

      return ("ItemListPartial", customer.orders);
   }
}

View

@model Company.Application.Model.Customer;

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" }))
{
    // How can I bind this to Order object ?
    // I can't define model as Order, because then I need to pass Customer Separately
    @Html.TextBoxFor(o => o.Orders[0].ItemName)
    @Html.TextBoxFor(o => o.Orders[0].SomeDate)
    <input type="submit" value="Add" />
}

I suppose you're looking for what this blog article describes: ASP.NET MVC Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries

Quote from the blog:

If the signature looks like this:

 public ActionResult Blah(IDictionary<string, Company> stocks) { // ... } 

And we are given this in HTML:

 <input type="text" name="stocks[0].Key" value="MSFT" /> <input type="text" name="stocks[0].Value.CompanyName" value="Microsoft Corporation" /> <input type="text" name="stocks[0].Value.Industry" value="Computer Software" /> <input type="text" name="stocks[1].Key" value="AAPL" /> <input type="text" name="stocks[1].Value.CompanyName" value="Apple, Inc." /> <input type="text" name="stocks[1].Value.Industry" value="Consumer Devices" /> 

Which like this:

 stocks[0].Key = "MSFT" stocks[0].Value.CompanyName = "Microsoft Corporation" stocks[0].Value.Industry = "Computer Software" stocks[1].Key = "AAPL" stocks[1].Value.CompanyName = "Apple, Inc." stocks[1].Value.Industry = "Consumer Devices" 

Then it will be just as if we had written:

 stocks = new Dictionary<string, Company>() { { "MSFT", new Company() { CompanyName = "Microsoft Corporation", Industry = "Computer Software" } }, { "AAPL", new Company() { CompanyName = "Apple, Inc.", Industry = "Consumer Devices" } } }; 

This IMO is how you should be handling this:

Pass customerID in your viewbag if you're really not wanting to make a viewmodel (ps It is ok to make a viewmodel!)

public class OrderController : Controller
{
   public ActionResult Create(int customerID)
   {
      ViewBag.CustomerID = customerID
      Order ord = new Order(o);
      return View(ord);
   }
}

your post method:

[HttpPost]
public ActionResult Create(int CustomerID, Order order)
{
  //create your order
}

your cshtml

@model Company.Application.Model.Order;

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" }))
{
    @Html.TextBoxFor(o => o.ItemName)
    @Html.TextBoxFor(o => o.SomeDate)
    @Html.Hidden("CustomerID",ViewBag.CustomerID)
    <input type="submit" value="Add" />
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM