Asp.net mvc 3 ASP.NET MVC从下拉列表中选择值

Asp.net mvc 3 ASP.NET MVC从下拉列表中选择值,asp.net-mvc-3,drop-down-menu,viewmodel,Asp.net Mvc 3,Drop Down Menu,Viewmodel,我有下一个模型(简化): 我想让用户从创建页面的下拉列表中选择汽车类型。 我试图通过ViewBag传递数据库中的类型字典及其名称: ViewBag.Types = _context.CarTypes.ToDictionary(carType => carType.Name); 并在页面中选择它: @Html.DropDownListFor(model => model.Type, new SelectList(ViewBag.Types, "Value", "Key")) 但是在

我有下一个模型(简化):

我想让用户从创建页面的下拉列表中选择汽车类型。 我试图通过ViewBag传递数据库中的类型字典及其名称:

ViewBag.Types = _context.CarTypes.ToDictionary(carType => carType.Name);
并在页面中选择它:

@Html.DropDownListFor(model => model.Type, new SelectList(ViewBag.Types, "Value", "Key"))
但是在POST方法中,我总是在
Type
属性中使用
null
构造
Car
对象

[HttpPost]
public ActionResult Create(Car car)
{
    if (ModelState.IsValid)
    {
        _context.Cars.Add(car);
        _context.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(car);
}
是否可以使用DropDownList选择自定义对象?因为选择像
int
string
这样的值很好

我想用
int
ID而不是
CarType
来编写ViewModel,并在保存到数据库之前按ID查找类型。但这样我需要将所有
Car
属性及其属性复制到我的ViewModel,最后将所有值复制到新的
Car
对象。对于小班学生来说可能没问题,但对于一些更复杂的学生来说——别这么认为


这是一个小例子。解决这些问题的常用方法是什么?如何编写灵活而简单的代码?

以下是我在这些情况下使用的一种可靠的HtmlHelper扩展方法:

public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, SelectListItem initialItem)
    where TProperty : struct
{
    if (!typeof(TProperty).IsEnum)
        throw new ArgumentException("An Enumeration type is required.", "enum");

    IList<SelectListItem> items = Enum.GetValues(typeof(TProperty)).Cast<TProperty>()
            .Select(t => new SelectListItem { Text = (t as Enum).GetDescription(), Value = t.ToString() }).ToList();

    if (initialItem != null)
        items.Insert(0, initialItem);

    return SelectExtensions.DropDownListFor<TModel, TProperty>(helper, expression, items, null, null);
}
并为您提供一个完全填充的select元素,其中传入的
Type
selected


上述方法可以通过
htmlAttributes
或其他任何方式进行扩展,但这是一个良好的开端

以下是我在这些情况下使用的可靠的HtmlHelper扩展方法:

public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, SelectListItem initialItem)
    where TProperty : struct
{
    if (!typeof(TProperty).IsEnum)
        throw new ArgumentException("An Enumeration type is required.", "enum");

    IList<SelectListItem> items = Enum.GetValues(typeof(TProperty)).Cast<TProperty>()
            .Select(t => new SelectListItem { Text = (t as Enum).GetDescription(), Value = t.ToString() }).ToList();

    if (initialItem != null)
        items.Insert(0, initialItem);

    return SelectExtensions.DropDownListFor<TModel, TProperty>(helper, expression, items, null, null);
}
并为您提供一个完全填充的select元素,其中传入的
Type
selected


上面的方法可以用
htmlAttributes
和其他任何东西进行扩展,但这是一个好的开始

我是否正确理解,这个助手方法只是构建
SelectListItem
的列表,填充其
文本
属性,并为我的属性设置
DropDownListFor
?问题是
Value
是一个字符串。因此,这种方法将返回默认Id为的非空CarType对象(0表示int)。当我需要从数据库中获取Id为的CarType对象时。我看到您使用的是
CarType
enum,所以它很有意义。枚举是否映射到数据库表?您应该仍然能够强制转换该枚举以将其保存为int。我是否正确理解,此帮助器方法只是构造
SelectListItem
的列表,填充其
文本和
属性,并为我的属性设置
DropDownListFor
?问题是
Value
是一个字符串。因此,这种方法将返回默认Id为的非空CarType对象(0表示int)。当我需要从数据库中获取Id为的CarType对象时。我看到您使用的是
CarType
enum,所以它很有意义。枚举是否映射到数据库表?您应该仍然能够强制转换该枚举以将其保存为int。
@Html.DropDownListForEnum(model => model.Type)