在我的MedicalProductController
中,我尝试通过将Create
传递到视图,使我的Delete
和IEnumerable<ViewModel>
操作能够在一个页面上创建和删除多个对象。我使用Create
操作时使用的方法适用于this stack overflow question中的Edit
操作。但它不能用我的create
动作,所以我怀疑有些事情是不对的。
问题是页面上没有字段。该页面简单地说:该页面上的“创建”,“保存”(按钮),“返回列表”(可点击链接)。在“创建”和“保存”之间,应该有由下面显示的MedicalProductViewModel.cshtml创建的html编辑器字段和标签。
以下是我的设置。
@model IEnumerable<MvcMedicalStore.Models.MedicalProductViewModel>
@{
ViewBag.Title = "Create";
}
<h2>Create</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")
}
@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.ID)
</div>
<div class="editor-field">
@Html.DropDownListFor(item => Model.BrandID, Model.BrandSelectListItem)
@Html.ValidationMessageFor(item => Model.BrandID)
</div>
public class MedicalProductController : Controller
{
private MvcMedicalStoreDb _db = new MvcMedicalStoreDb();
public ActionResult Index()
{
var productList = _db.Products.ToArray();
var viewModelList = GetMedicalProductViewModelList(productList);
return View(viewModelList);
}
public IEnumerable<MedicalProductViewModel> GetMedicalProductViewModelList(IEnumerable<MedicalProduct> productList)
{
var brandList = _db.Brands.ToArray();
var mapper = new MedicalProductMapper();
return mapper.MapMedicalProductViewModel(productList, brandList);
}
public IEnumerable<MedicalProduct> GetMedicalProductList(IEnumerable<MedicalProductViewModel> viewModelList)
{
var mapper = new MedicalProductMapper();
return mapper.MapMedicalProductList(viewModelList);
}
//
// GET: /MedicalSupply/Create
public ActionResult Create()
{
return View();
}
//
// POST: /MedicalSupply/Create
[HttpPost]
[ValidateAntiForgeryToken]
//public ActionResult Create(MedicalProduct medicalProduct)
public ActionResult Create(IEnumerable<MedicalProductViewModel> productViewModelList)
{
var productList = GetMedicalProductList(productViewModelList);
if (ModelState.IsValid)
{
foreach (MedicalProduct product in productList)
_db.Products.Add(product);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(productViewModelList);
}
}
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 = viewModel.BrandID
});
return modelList;
}
}
我的编辑视图与我的创建视图非常相似:
@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")
}
答案 0 :(得分:2)
您的Create()控制器方法将null传递给您的视图,因此editortemplate不会触发。
public ActionResult Create()
{
return View();
}
如果您传入新的列表&lt;&gt;,那么它将像您的编辑一样工作。
public ActionResult Create()
{
return View(new List<MedicalProductViewModel>() { new MedicalProductViewModel() });
}
你有没有理由不只是传递一个视图模型而不是列表?您将能够以相同的方式使用编辑器模板。
另外需要注意的是,传入IEnumerable&lt;&gt;可能不是一个好主意。作为你的viewmodel。如果您需要将其他非MedicalProduct属性传递给您的视图,该怎么办?
我会提倡复合视图模型,就像这样。
public class EditMedicalProductViewModel
{
public IEnumerable<MedicalProductViewModel> MedicalProducts { get; set; }
}
public class CreateMedicalProductViewModel
{
public MedicalProductViewModel MedicalProduct { get; set; }
}
在您的修改视图中,您可以执行此操作
@Html.EditorFor(m => m.MedicalProducts)
对于您的创建视图,您可以执行此操作
@Html.EditorFor(m=> m.MedicalProduct)
在您的创建方法中,您应该创建一个新的医疗产品
return View(new CreateMEdicalProductViewModel() { MedicalProduct = new MedicalProductViewModel() } );
答案 1 :(得分:1)
它不起作用,因为您的模型是IEnumerable<MedicalProductViewModel>
,但您的编辑器模板适用于MedicalProductViewModel
你可以试试这个:
<fieldset>
<legend>MedicalProduct</legend>
@foreach(var item in Model)
{
Html.EditorFor(model => item)
}
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
但是这可能不会按照你想要的方式格式化字段,因为它会创建大量的编辑器。最简单的方法是重构控制器,以便它允许一次编辑一条记录。