2017-04-01 145 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,它像一個魅力。謝謝! –