2017-04-18 4 views
0

私はMVCを初めて使用しています。私はユーザーが顧客のために見積を作成できるようにする親ビューを持っています。 AJAXリンクの "Add Product"では、部分的なビュー "EditQuoteDetail"が読み込まれ、ユーザーは見積もりに商品を追加できます。問題は、ModelStateがPOSTで有効でない場合(ユーザーが必要な電話番号を入力するのを忘れたとします)、製品の部分的なビューはビューに戻されません。 QuoteDetailsをユーザーに返すにはどうすればよいですか?ここモデル状態が有効でない場合、部分ビューは保持されません

はメインビューである:ここ

@model CMSUsersAndRoles.Models.QuoteViewModel 

@{ 
    ViewBag.Title = "Create"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
@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> 

<h2>Create</h2> 

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

    <div class="form-horizontal"> 
     <h4>Quote</h4> 
     <hr /> 
     <div class="form-group"> 
      <div class="col-md-10"> 
       @Html.HiddenFor(model => model.QuoteId) 
      </div> 
     </div> 
<div class="form-group"> 
      @Html.LabelFor(model => model.Company, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.DropDownListFor(model => model.CustomerId, new SelectList(ViewBag.Customers, "CustomerId", "Company"), "---Select one---", new { style = "width: 300px !important", htmlAttributes = new { @class = "company" } }); 
       @Html.HiddenFor(model => model.Company, new { @class = "companyName" }) 
       @Html.ValidationMessageFor(model => model.Company, "", new { @class = "text-danger" }) 

      </div> 
     </div> 

... //other Quote fields 

<div class="form-group"> 
      @Html.LabelFor(model => model.QuoteDetail, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10" id="QuoteDetails"> 
       @Html.ValidationMessageFor(model => model.QuoteDetail, "", new { @class = "text-danger"}) 

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

      </div> 

は部分図である:ここ

@model CMSUsersAndRoles.Models.QuoteDetail 

@{ 
    ViewBag.Title = "EditQuoteDetail"; 
    Layout = null; 
} 


    <div id="row" class="row"> 
     <table> 

      @using (Html.BeginCollectionItem("quoteDetail")) 

      { 

       <tr> 
        @Html.HiddenFor(model => model.QuoteId, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.HiddenFor(model => model.QuoteDetailId, 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", required = "required", htmlAttributes = new { @id = "ProductName", @class = "ProductList" } }) 
        @Html.HiddenFor(model => model.ProductName) 

        @Html.EditorFor(model => model.Amount, new { htmlAttributes = new { @id = "Amt", @class = "form-control amount", style = "width: 95px" } }) 
        @Html.EditorFor(model => model.ListPrice, new { htmlAttributes = new { @readonly = "readonly", @id = "LPrce", @class = "form-control listprice", style = "width: 95px" } }) 
        @Html.EditorFor(model => model.Discount, new { htmlAttributes = new { @id = "TotalDiscount", @class = "form-control discount", style = "width: 100px" } }) 
        @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @readonly = "readonly", @id = "FinalPrce", @class = "form-control price", style = "width: 100px" } }) 


        @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, 
           OnSuccess = "RemoveRow" 
          }, 
          new { @class = "btn btn-danger glyphicon glyphicon-trash" }) 
       </tr> 
      } 

     </table> 
    </div> 

がPOSTである:ここ

[HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create(QuoteViewModel qvm) 
     { 
      if (qvm.QuoteDetail == null) 
      { 
       qvm.QuoteDetail = new List<QuoteDetail>(); 
       qvm.QuoteDetail.Add(new QuoteDetail() { QuoteId = qvm.QuoteId, QuoteDetailId = (qvm.QuoteDetail.Count + 1) }); 
       var customerList = db.Customers.ToList(); 
       ViewBag.Customers = customerList; 
       return View(qvm); 
      } 

      if (ModelState.IsValid) 
      { 

      ... //process 

return RedirectToAction("Index"); 
      } 

      var customers = db.Customers.ToList(); 
      ViewBag.Customers = customers; 

      return View(qvm); 
     } 

は部分的にロードするためのコードであります表示:

私は何をしないのです

public class QuoteViewModel 
    { // Columns from QuoteDetail table 
     [Required(ErrorMessage ="Please add product(s) to quote ")] 
     [Display(Name = "Quote Detail")] 
     public List<QuoteDetail> QuoteDetail { get; set; } 
    } 

:3210

ここでのViewModelの関連セクションはありますか?どんな助けでも大歓迎です。

+0

を含めるべきではありません' - ' QuoteDetail'のコレクションである 'quoteDetail'という名前のプロパティを含んでいますか? –

+0

@StephenMuecke、上に追加されました。 –

答えて

1

メインビューには、既存のQuoteDetail(動的に追加したものを含む)のhtmlを生成するループが含まれている必要があります。

GETメソッドまたはQuoteViewModelのデフォルトのコンストラクタでは、を新しいコレクションに初期化してください(nullではなく)。次にビューで、注意点として、次のコード

@foreach(var detail in Model.QuoteDetail) 
{ 
    @Html.Partial("EditQuoteDetail", detail) 
} 

を追加し、あなたはQuoteDetailのビューモデルを使用する必要があり、それはあなたがQuoteViewModel `のためにモデルを表示する必要があるプロパティQuoteId

+0

ありがとう!それが問題を解決しました。 –

関連する問題