How to make a CREATE view & controller method for a model that has a list field?

偶尔善良 提交于 2021-02-11 13:50:09

问题


I have these 2 models:

public class Invoice 
{
   public string InvoiceID {get; set; }

   public List<InvoiceElement> InvoiceElements {get; set;}

   [...other fields...]
}


public class InvoiceElement
{
   public string InvoiceElementID {get; set; }

   [ForeignKey("Invoice")]
   public string InvoiceID { get; set; }
   public virtual Invoice Invoice { get; set; }

   public string Item {get; set;}

   [...other fields...]
}   

I am unable to make a CREATE view for new Invoices that lets me add InvoiceElements.

I want to have a "CurrentInvoiceElements" table where to dinamically add rows.


回答1:


Just trying to making it simple. You can use the name attribute (the attribute that asp.net uses for modal binding) and post a list along with other properties of the class. You can use javaScript to append new elements to your form. Using the above modals you've provided, I have written a simple example using simple jQuery functions.

Razor View:

<button class="btn btn-success" id="add_btn">Add Invoice Element</button>
@using (@Html.BeginForm("SaveInvoice", "Invoice", FormMethod.Post))
{
  <!--Other modal attributes inputs goes here -->
  <!--You can use normal html helper extensions -->
  <table id="element_table">
    <thead>
      <tr>
        <td>Element Id</td>
        <td>Item</td>
      </tr>
    </thead>
    <tbody>
        <tr>
          <td><input name="invoice.InvoiceElements[0].Item" id="InvoiceElements[0].Item" /></td>
          <td><input name="invoice.InvoiceElements[0].InvoiceElementID" id="InvoiceElements[0].InvoiceElementID" /></td>
        </tr>
    </tbody>
  </table>
  <input type="submit" />
}

JavaScript:

<script type="text/javascript">
  $("#add_btn").on('click', function (e) {
    var table = $("#element_table");
    var idx = $(table).find("tbody>tr").length;
    var htmlToAppend = `<tr>
                            <td><input name="invoice.InvoiceElements[${idx}].Item" id="InvoiceElements[${idx}].Item" /></td>
                            <td><input name="invoice.InvoiceElements[${idx}].InvoiceElementID" id="InvoiceElements[${idx}].InvoiceElementID" /></td>
                        </tr>`;
    $(table).find("tbody").append(htmlToAppend);
  });
</script>

Controller / Action:

[HttpPost]
public ActionResult SaveInvoice(Invoice invoice)
{
    /* your logic here */
    if(ModelState.IsValid)
       _invoiceBusiness.SaveInvoice(invoice);
    return View();
}

Please make sure the variable name in the parameter of the action method matches the name used in the name attribute of the input tag. i.e. name = "invoice.***" public ActionResult SaveInvoice(Invoice invoice)




回答2:


I followed this solution: https://github.com/danludwig/BeginCollectionItem some years ago, and worked fine.

If I'm not mistaken, at the time I managed to do it using only the HTML Helper: HtmlPrefixScopeExtensions. Then just make sure the name you give on your View when you do Html.BeginCollectionItem("name") is exactly the same as your collection on your ViewModel.

That's for binding back to the controller.

With this, you can dynamically add rows using AJAX per example.

I hope it's clear enough. If you don't understand it I may make a Github repository with this.



来源:https://stackoverflow.com/questions/61850072/how-to-make-a-create-view-controller-method-for-a-model-that-has-a-list-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!