2017-04-01 201 views
0

我是新来的MVC不会被保存。我有显示连接到一个Quote(该QuoteDetails)产物的图。我也有一个“添加产品”,它加载时,要输入其他产品的局部视图的Ajax.ActionLink)_。问题在于,加载部分视图时,不会保存对不在局部视图中的其他产品的编辑。如果没有加载部分视图,则对所列产品的编辑会保存得很好。编辑时,局部视图加载MVC

这里是主视图相关代码:

@model CMSUsersAndRoles.Models.QuoteViewModel 
.... 
@Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js") 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
<script src="~/Scripts/jquery.mask.min.js"></script> 
@using (Html.BeginForm()) 
{ 
    .... 
    @Html.HiddenFor(model => model.CustomerId) 

    @Html.LabelFor(model => model.QuoteId) 
    @Html.EditorFor(model => model.QuoteId, new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" } }) 
    @Html.ValidationMessageFor(model => model.QuoteId) 

    .... // more controls for properties of Quote 

    @Html.LabelFor(model => model.QuoteDetail) 
    <div id="QuoteDetails"> 
     @for (int i = 0; i < Model.QuoteDetail.Count; i++) 
     { 
      @Html.HiddenFor(model => model.QuoteDetail[i].QuoteId, new { htmlAttributes = new { @class = "form-control" } }) 
      ....  
      @Html.EditorFor(model => model.QuoteDetail[i].SKU, new { htmlAttributes = new { @readonly = "readonly", @id = "SKU", @class = "form-control", style = "width: 100px" } }) 
      @Html.EditorFor(model => model.QuoteDetail[i].Amount, new { htmlAttributes = new { @class = "form-control amount", style = "width: 95px" } }) 
      @Html.ValidationMessageFor(model => model.QuoteDetail[i].Amount) 

      .... // more for controls for properties of QuoteDetail 

      @Ajax.ActionLink(" ", "DeleteProduct", "QuoteViewModel", new { quoteId = Model.QuoteDetail[i].QuoteId, quoteDetailId = (Model.QuoteDetail[i].QuoteDetailId) }, 
       new AjaxOptions 
       { 
        HttpMethod = "POST", 
        Confirm = "Are you Sure You Want to Delete " + Model.QuoteDetail[i].ProductName, 
       }, new { @class = "btn btn-danger glyphicon glyphicon-trash" }) 
        </div> 
      } 
      @Html.EditorFor(model => model.Subtotal, new { htmlAttributes = new { @class = "form-control subTotal", style = "width: 100px; float:right; clear:left; text-align:right" } }) 

      @Ajax.ActionLink("Add product", "AddProduct", "QuoteViewModel", new { quoteId = Model.QuoteId, quoteDetailId = (Model.QuoteDetail.Count + 1) }, 
       new AjaxOptions 
       { 
        UpdateTargetId = "QuoteDetails", 
        InsertionMode = InsertionMode.InsertAfter 
       }) 
      } 

下面是部分观点:

@model CMSUsersAndRoles.Models.QuoteDetail 

@{ 
    ViewBag.Title = "EditQuoteDetail"; 
    Layout = null; 
} 
<!DOCTYPE html> 
<html> 
<head> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
    <script src="~/Scripts/jquery-1.10.2.min.js"></script> 
</head> 
<body> 
    <div id="row" class="row"> 
     <table> 
      @using (Html.BeginCollectionItem("quoteDetail")) 
      { 
       <tr> 
        @Html.HiddenFor(model => model.QuoteId, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.EditorFor(model => model.SKU, new { htmlAttributes = new { @readonly = "readonly", @id = "SKU", @class = "form-control", style = "width: 100px" } }) 
        @Html.DropDownListFor(model => model.ProductId, new SelectList(ViewBag.ProductData, "ProductId", "Name"), "---Select one---", new { style = "width: 300px !important", htmlAttributes = new { @id = "ProductName", @class = "ProductList" } }); 

        .... // more controls for properties of QuoteDetail 

        @Ajax.ActionLink(" ", "DeleteProduct", "QuoteViewModel", new { quoteId = Model.QuoteId, quoteDetailId = (Model.QuoteDetailId) }, 
          new AjaxOptions 
          { 
           HttpMethod = "POST", 
           Confirm = "Are you Sure You Want to Delete " + Model.ProductName, 
          }, new { @class = "btn btn-danger glyphicon glyphicon-trash" }) 
       </tr> 
      } 
     </table> 
    </div> 

,这里是控制器动作:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit(QuoteViewModel qvm, 
    [Bind(Include = "CustomerId,SalesRep,FirstName,LastName,Company,Address1,Address2,City,State,PostalCode,WorkPhone,CellPhone,Email,Discount,PaymentTerms")] Customer customer, 
    [Bind(Include = "QuoteId,QuoteDetailId,ProductId,ProductName,Amount,ListPrice,Discount,Price")] List<QuoteDetail> quoteDetails, 
    [Bind(Include = "QuoteId,CustomerId,Subtotal,Tax,Total,QuoteDate,GoodUntil,QuoteSent,DateApproved,DateOrdered")] Quote quote)  
{ 
    .... 
} 

任何人都可以帮助这个?任何帮助都感激不尽。

回答

1

你使用2种不同的技术在这里生成您的收藏这是造成问题。

在主视图中,您有一个for循环来生成控件,用于生成基于零的连续索引器的现有项目,这是DefaultModelBinder默认使用的项目。你的HTML将包括name属性是例如

<input name="QuoteDetail[0].QuoteId"..../> 
<input name="QuoteDetail[1].QuoteId"..../> 
<input name="QuoteDetail[2].QuoteId"..../> 

但你使用它产生的收集索引作为GuidBeginCollectionItem辅助方法,使新的投入将增加新的项目(其中xxxGuid

<input name="QuoteDetail[xxxx].QuoteId"..../> 

并且还包括

<input name="QuoteDetail.Index" value="xxxx" ... /> 

这是使用的DefaultModelBinder匹配非从零开始连续非索引。你不能使用这两种技术。

为了解决这个问题,你可以在for

@for (int i = 0; i < Model.QuoteDetail.Count; i++) 
{ 
    .... 
    <input type="hidden" name="QuoteDetail.Index" value="@i" /> 
} 

添加输入为索引或改变循环使用含有BeginCollectionItem方法的局部视图,在每次迭代中

@foreach(var item in Model.QuoteDetail) 
{ 
    @Html.Partial("xxxx", item) // replace xxxx with the name of your partial 
} 
+0

我使用了解决方案2,它像一个魅力。谢谢! –