Using BeginCollectionItem for adding/deleting Line

2019-08-18 19:52发布

问题:

I'm trying to add/delete EnquiryLineItems into Quotation View. Tried to follow

  • MVC 5 Dynamic Rows with BeginCollectionItem
  • BeginCollectionItem partial within partial not behaving correctly
  • MVC 5 BeginCollectionItem with Partial CRUD

But while clicking on Add it throws error

Failed to load resource: the server responded with a status of 500 (Internal Server Error)

and probably constructing wrong URl ( http://localhost:53363/Enquiries/CreateLineItem?_=1505728151541 - as per the error message )

Using Partialview and Single Controller .

ViewModels :

 public class EnquiryVM
    {
        public int ID { get; set; }

        public DateTime? PreparedDate { get; set; }
        [StringLength(12)]
        public string EnquiryNumber { get; set; }
        public DateTime? ClosingDate { get; set; }
        public int ClientID { get; set; }
        public IEnumerable<SelectListItem> Clients { get; set; }//DDL in main view
        public Client Client { get; set; }
        public DateTime? RFQSentDate { get; set; }

        public int ItemID { get; set; }
        public List<EnquiryLineItem> LineItems { get; set; }// this is added/deleted dynamically

    }
 public class EnquiryLineItemVM
    {
        public int ID { get; set; }
        public string ItemDesc { get; set; }
        public int Quantity { get; set; }
        public int ManufacturerId { get; set; }
        public SelectList ManufacturerList { get; set; }
    }

Controller:

 // GET: Enquiries/Create
        public ActionResult Create()
        {
            var viewModel = GetAllCategories();
            return View(viewModel);
        }
  //Create View Population method - for dropdownlists
        private EnquiryVM GetAllCategories()
        {
            var model = new EnquiryVM();
            var clients = db.Clients.ToList();
            model.Clients = clients.Select(s => new SelectListItem
            {
                Value = s.ID.ToString(),
                Text = s.Name
            });

           var LineItems = new List<EnquiryLineItem>();//added to avoid null exception, 
            model.LineItems = LineItems;

           return model;
        }
//to render partialView
 public PartialViewResult CreateLineItem()
        {
            return PartialView(new EnquiryLineItemVM());
        }

MainView ( Enquiry- create) - only added relevant code

@model EnquiryVM

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.EnquiryNumber, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.EditorFor(model => model.EnquiryNumber, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.EnquiryNumber, "", new { @class = "text-danger" })
            </div>
        </div>

         <div class="form-group">
            @Html.LabelFor(model => model.ClientID, "Client", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-3">

                @Html.DropDownListFor(u => u.ClientID, (IEnumerable<SelectListItem>)Model.Clients, "--Select--")
                @Html.ValidationMessageFor(model => model.ClientID, "", new { @class = "text-danger" })
            </div>
        </div>


        </div>

        <div id="LineItems">
            @using (Html.BeginForm())
            {
                <div id="editorRowsLineitems">
                    @foreach (var item in Model.LineItems)
                    {
                        @Html.Partial("_CreateEnquiryItem", item)
                    }
                </div>
                @Html.ActionLink("Add Items", "CreateLineItem", null, new { id = "addItem", @class = "button" });
            }
        </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 () {
        $('#addItem').on('click', function () {
            $.ajax({
                url: '@Url.Action("CreateLineItem")',
                    cache: false,
                    success: function (html) { $("#editorRowsLineitems").append(html); }
                });
                return false;
            });
        $('#editorRowsLineitems').on('click', '.deleteRow', function () {
                $(this).closest('.editorRow').remove();
            });

        });
</script>
}

partialViews - _createEnquiryItem.cshtml

@model .EnquiryLineItemVM

<div class="editorRow">
    @using (Html.BeginCollectionItem("ItemList"))
    {
        <table class="table">

            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            <tr>
                <td>
                    @Html.EditorFor(model => model.ItemDesc)
                    @Html.ValidationMessageFor(model => model.EnquiryLineItem.ItemDesc, "", new { @class = "text-danger" })
                </td>
                <td>
                    @Html.EditorFor(model => model.Quantity)
                    @Html.ValidationMessageFor(model => model.EnquiryLineItem.Quantity)
                </td>

                <td>
                    @Html.DropDownListFor(model => model.ManufacturerId, Model.ManufacturerList, "--Please Select--")
                    @Html.ValidationMessageFor(model => model.ManufacturerId, "", new { @class = "text-danger" })
                </td>
            </tr>
        </table>
        <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>

What might be I'm doing wrong here. Also, whether this can be done with a better or easier approach using single partial view? Please help. Thanks in advance.