Hug*_*ner 4 c# asp.net asp.net-mvc
这是Add New Scaffolded Item...在创建新控制器时从VS获取的.
在控制器中:
// GET: Drivers/Create
public ActionResult Create()
{
ViewBag.Tenant = new SelectList(db.Tenants, "TenantID", "TenantName");
return View();
}
Run Code Online (Sandbox Code Playgroud)
然后该视图呈现一个下拉列表:
@Html.DropDownListFor(model => model.Tenant, null, htmlAttributes: new { @class = "form-control" })
Run Code Online (Sandbox Code Playgroud)
相关型号信息:
public partial class Driver
{
public int DriverID { get; set; }
public int Tenant { get; set; }
public virtual Tenant Tenant1 { get; set; }
}
public partial class Tenant
{
public Tenant()
{
this.Drivers = new HashSet<Driver>();
}
public int TenantID { get; set; }
public string TenantName { get; set; }
public virtual ICollection<Driver> Drivers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么这有效吗?
我查看了其他问题和文档,找不到答案.我怀疑它是"约定优于配置"的东西,它是从ViewBag使用属性的名称拉出来的.事实上,我将ViewBag属性更改为Tenantz并获得以下异常:
没有类型为"IEnumerable"的ViewData项具有"租户"键.
那么设置属性名称是否与ViewBag您想要更新的模型属性相同?似乎没问题,但我总是听到你应该如何避免ViewBag和动态类型.
正如您已经发现的那样,有一个惯例.您视图中的以下行:
@Html.DropDownListFor(model => model.Tenant, null, htmlAttributes: new { @class = "form-control" })
Run Code Online (Sandbox Code Playgroud)
与此行完全相同:
@Html.DropDownList("Tenant", null, htmlAttributes: new { @class = "form-control" })
Run Code Online (Sandbox Code Playgroud)
现在,如果你看一下如何DropDownList在源代码中实现帮助器,你会注意到它只是这样做:
object obj = htmlHelper.ViewData.Eval(name) as IEnumerable<SelectListItem>;
Run Code Online (Sandbox Code Playgroud)
name传递给DropDownList帮助器的第一个参数在哪里.你猜怎么着?它会发现您在控制器中设置的相应值:ViewBag.Tenant = ....
据说使用ViewBag是绝对的,灾难性的,非常糟糕的做法.你已经找到了原因.它可以像狗一样咬你,甚至不知道发生了什么.防止这些狗(ViewBag)的最佳方法是在你的解决方案中搜索它们并给它们毒药.只需完全删除ViewBag代码中的任何调用并使用视图模型.然后你不会得到不好的惊喜,一切都会有一个合理的解释,在StackOverflow上没有必要这样的问题.
例如,您可以编写普通视图模型:
public class DriverViewModel
{
public int? SelectedTenantID { get; set; }
public IEnumerable<SelectListItem> Tenants { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和一个正常的控制器操作,它将查询您的数据存储区以获取所需信息并将您的实体模型投影到视图模型:
// GET: Drivers/Create
public ActionResult Create()
{
var viewModel = new DriverViewModel();
viewModel.Tenants = new SelectList(db.Tenants, "TenantID", "TenantName");
return View(viewModel);
}
Run Code Online (Sandbox Code Playgroud)
最后是相应的强类型视图:
@model DriverViewModel
...
@Html.DropDownListFor(
model => model.SelectedTenantID,
Model.Tenants,
htmlAttributes: new { @class = "form-control" }
)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您使用强类型视图,具有强类型视图模型和帮助程序.不再有任何疑虑(和狗咬).代码是可读的,你不能问,为什么这个约定超过配置正在做这个或那个.因此,只要您的应用程序中没有ViewBag的痕迹,就不会有这样的问题.
| 归档时间: |
|
| 查看次数: |
2469 次 |
| 最近记录: |