【发布时间】:2013-08-06 05:48:20
【问题描述】:
(这篇文章是糖果混淆的;混淆是因为我必须这样做,糖果给 lulz。相信我,真正的东西实际上是值得的。)
使用 ASP.NET MVC 4 和 EF 5,我正在尝试创建一个页面,该页面同时显示数据库中当前存在的实体列表和底部的简单创建字段。我有一种可行的方法,但我想知道是否有更好的方法,因为我目前的方法感觉很迂回。我会上传一张我所拥有的图片,但我必须至少有 10 个声望,所以...继续发帖。
我传入的模型是这样的:
public class CandyBrand
{
public int ID { get; set; }
[Required(ErrorMessage = "Brand name is required.")]
[Display(Name = "Brand Name")]
public string Name { get; set; }
}
控制器看起来像这样,包括 GET 和 POST 方法:
public ActionResult CandyBrands()
{
return View(context.CandyBrands);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CandyBrands(CandyBrand brand)
{
if (ModelState.IsValid)
{
context.CandyBrands.Add(brand);
context.SaveChanges(); //try/catch block removed for brevity
}
return View(db.CandyBrands);
}
我的看法:
@model IEnumerable<CandyDatabase.Models.CandyBrands>
@{
ViewBag.Title = "Brands";
}
<h2>Brands</h2>
<p>@Html.DisplayNameFor(m => m.Name)</p>
@foreach (var brand in Model)
{
<p>@Html.DisplayFor(m => brand.Name)</p>
}
<h3>Create New</h3>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<p>@Html.EditorFor(m => m.FirstOrDefault().Name) <input type="submit" value="Create" /></p>
<p>@Html.ValidationMessageFor(m => m.FirstOrDefault().Name)</p>
}
<p>@Html.ActionLink("Back to Candy List", "Index", "Home")</p>
@section Scripts{
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("/Scripts/clear-inputs.js")
}
因为我传递的是糖果品牌列表,所以模型采用 IEnumerable 类型。这对前半部分来说不是问题——foreach 循环会处理这个问题。但是,这会在页面下方产生其他问题。因为模型是 IEnumerable,所以 Html.EditorFor 不喜欢它。目前,为了解决这个问题,我调用了 FirstOrDefault,它将它归结为一个条目。这本身就很烦人,但并不止于此。然后 MVC 会自动(并且不希望地(可能是也可能不是单词))用模型中第一个实体的数据填充编辑器!如果您在底部注意到,则会调用“clear-inputs”脚本;这个脚本的存在只是为了通过运行来解决这个问题
$("input[type!='submit']").val("");
在页面加载时清除所有字段。
有没有更好的方法来做到这一点?我并没有接受“使用视图模型,dangit!”的答案,但是拥有一个具有 CandyBrand 实体和 CandyBrand 实体列表的视图模型似乎很愚蠢。
【问题讨论】:
-
在您的 POST 中,我不会返回视图,而是重定向到 GET。这将解决明显的问题。
-
ViewModel 是这里实际、简单和清晰的解决方案。没什么可笑的。
-
老兄,使用视图模型,dangit!您甚至还想如何编写一个实际工作的 ASP.NET MVC 应用程序?没有视图模型?我还从来没有见过这样的野兽在野外放生。因为这不会发生。甚至在从应用程序中编写一行代码之前,您首先应该考虑的是您的视图模型的外观。
标签: c# asp.net-mvc-4