繁体   English   中英

带有null selectList参数的Html.DropDownListFor

[英]Html.DropDownListFor with null selectList parameter

这是在创建新控制器时从VS Add New Scaffolded Item...

在控制器中:

// GET: Drivers/Create
public ActionResult Create()
{
    ViewBag.Tenant = new SelectList(db.Tenants, "TenantID", "TenantName");
    return View();
}

然后该视图呈现一个下拉列表:

@Html.DropDownListFor(model => model.Tenant, null, htmlAttributes: new { @class = "form-control" })

相关型号信息:

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; }
}

有人可以解释为什么这有效吗?

我查看了其他问题和文档,找不到答案。 我怀疑它是“约定优于配置”的东西,它是使用属性的名称从ViewBag提取的。 事实上,我将ViewBag属性更改为Tenantz并获得以下异常:

没有类型为“IEnumerable”的ViewData项具有“租户”键。

那么设置ViewBag的属性名称与您想要更新良好实践的模型属性相同吗? 看起来没问题,但我总是听说你应该如何避免使用ViewBag和动态类型。

正如您已经发现的那样,有一个惯例。 您视图中的以下行:

@Html.DropDownListFor(model => model.Tenant, null, htmlAttributes: new { @class = "form-control" })

与此行完全相同:

@Html.DropDownList("Tenant", null, htmlAttributes: new { @class = "form-control" })

现在,如果您看一下如何在源代码中实现DropDownList帮助器,您会注意到它只是这样做:

object obj = htmlHelper.ViewData.Eval(name) as IEnumerable<SelectListItem>;

其中name是传递给DropDownList帮助器的第一个参数。 你猜怎么着? 它会发现您在控制器中设置的相应值: ViewBag.Tenant = ...

据说使用ViewBag是绝对的,灾难性的,非常糟糕的做法。 你已经找到了原因。 它可以像狗一样咬你,甚至不知道发生了什么。 防止这些狗( ViewBag )的最佳方法是在你的解决方案中搜索它们并给它们毒药。 只需在代码中删除绝对任何ViewBag调用并使用视图模型。 然后你不会得到不好的惊喜,一切都会有一个合理的解释,在StackOverflow上没有必要这样的问题。

例如,您可以编写普通视图模型:

public class DriverViewModel
{
    public int? SelectedTenantID { get; set; }

    public IEnumerable<SelectListItem> Tenants { get; set; }
}

和一个正常的控制器操作,它将查询您的数据存储区以获取所需信息并将您的实体模型投影到视图模型:

// GET: Drivers/Create
public ActionResult Create()
{
    var viewModel = new DriverViewModel();
    viewModel.Tenants = new SelectList(db.Tenants, "TenantID", "TenantName");
    return View(viewModel);
}

最后是相应的强类型视图:

@model DriverViewModel
...
@Html.DropDownListFor(
    model => model.SelectedTenantID, 
    Model.Tenants, 
    htmlAttributes: new { @class = "form-control" }
)

在这种情况下,您使用强类型视图,具有强类型视图模型和帮助程序。 不再有任何疑虑(和狗咬)。 代码是可读的,你不能问,为什么这个约定超过配置正在做这个或那个。 因此,只要您的应用程序中没有ViewBag的痕迹,就不会有这样的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM