Visual Studio 2012 デバッガーを実行していますが、productViewModelList パラメーターに、ビューが [HTTPPOST] Edit アクションに渡すすべての値が含まれていないことがわかりました。理由がわかりません。ブレークポイントを挿入し、productViewModelList の値を確認した場所については、以下のコード サンプルのコメントを参照してください。
以下の値が productViewModelList に与えられます。
BrandId = 0、BrandName = "6"、BrandSelectListItem = null、ID = 5、Name = "クラッチ"、Price = 10.0
- BrandID が正しくありません。DropDownList のビューで、「Catatonics Inc.」を割り当てます。データベースで確認した ID は 6 です。
- BrandName は、BrandID にあるはずの「6」を示しています。BrandName は「Catatonics Inc.」である必要があります。
- BrandSelectList アイテムは SelectListItem タイプのオブジェクトであり、ビューの DropDownList アイテムに入る値が含まれています。DropDownList には値が正しく表示されますが、BrandSelectList は
null
[httpPost] 編集アクションが実行されたときです。DropDownList の Selected 項目にアクセスする必要があります。 - 他のすべての値、ID、名前、および価格は正しいです。
ここに私のコードのいくつかのクラスがあります。
MedicalProductController
public class MedicalProductController : Controller
{
private MvcMedicalStoreDb _db = new MvcMedicalStoreDb();
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(IEnumerable<MedicalProductViewModel> productViewModelList)
{
// I have a breakpoint inserted here, and check productViewModelList with debugger.
var modelList = GetMedicalProductList(productViewModelList);
if (ModelState.IsValid)
{
foreach (var model in modelList)
_db.Entry(model).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(productViewModelList);
}
}
MedicalProductMapper
public class MedicalProductMapper
{
public IEnumerable<MedicalProductViewModel> MapMedicalProductViewModel(IEnumerable<MedicalProduct> productList, IEnumerable<Brand> brandList)
{
var brandSelectListItem = brandList.Select(b => new SelectListItem()
{
Text = b.Name,
Value = b.ID.ToString()
});
var viewModelList = productList.Select(p => new MedicalProductViewModel()
{
BrandID = p.BrandID,
BrandName = brandList.SingleOrDefault(b => b.ID == p.BrandID).Name,
BrandSelectListItem = brandSelectListItem,
ID = p.ID,
Price = p.Price,
Name = p.Name
});
return viewModelList;
}
public IEnumerable<MedicalProduct> MapMedicalProductList(IEnumerable<MedicalProductViewModel> viewModelList)
{
var modelList = viewModelList.ToArray().Select( viewModel => new MedicalProduct()
{
Name = viewModel.Name,
Price = viewModel.Price,
BrandID = Convert.ToInt32(viewModel.BrandSelectListItem.Select(b => b.Value.ToString()))
});
return modelList;
}
}
EDIT.cshtml
@model IEnumerable<MvcMedicalStore.Models.MedicalProductViewModel>
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>MedicalProduct</legend>
@Html.EditorFor(m => m)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
EditorTemplates/MedicalProductViewModel.cshtml
(これは、Edit.cshtml のディレクトリのサブディレクトリにあります。)
@model MvcMedicalStore.Models.MedicalProductViewModel
@Html.HiddenFor(item => Model.ID)
<div class="editor-label">
@Html.LabelFor(item => Model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(item => Model.Name)
@Html.ValidationMessageFor(item => Model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(item => Model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(item => Model.Price)
@Html.ValidationMessageFor(item => Model.Price)
</div>
<div class="editor-label">
@Html.LabelFor(item => Model.BrandName)
</div>
<div class="editor-field">
@Html.DropDownListFor(item => Model.BrandName, Model.BrandSelectListItem)
@Html.ValidationMessageFor(item => Model.BrandName)
</div>
編集:
ブランド
public class Brand
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(30)]
public string Name { get; set; }
}
医療製品
public class MedicalProduct
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
public double Price { get; set; }
// is a foreign key
public int BrandID { get; set; }
}
MedicalProductViewModel
public class MedicalProductViewModel
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
public double Price { get; set; }
public int BrandID { get; set; }
[DisplayFormat(NullDisplayText="[Generic]")]
public string BrandName { get; set; }
public IEnumerable<SelectListItem> BrandSelectListItem { get; set; }
}