ASP.NET MVC 从下拉列表中选择值

发布于 2024-11-29 23:36:58 字数 1338 浏览 1 评论 0原文

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

public class CarType
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }
}

public class Car
{
    [Required]
    public string Model { get; set; }

    [Required]
    public CarType Type { get; set; }

    [Required]
    public decimal Price { get; set; }
}

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

ViewBag.Types = _context.CarTypes.ToDictionary(carType => carType.Name);

并在页面中选择它:

@Html.DropDownListFor(model => model.Type, new SelectList(ViewBag.Types, "Value", "Key"))

但在 POST 方法中,我总是使用 null 构造 Car 对象在 Type 属性中。

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

    return View(car);
}

是否可以使用 DropDownList 选择自定义对象?因为选择像 intstring 这样的值可以正常工作。

我有一个想法,使用 int ID 而不是 CarType 编写 ViewModel,并在保存到数据库之前通过 ID 查找类型。但这样我需要将所有 Car 属性及其属性复制到我的 ViewModel 中,最后 - 将所有值复制到新的 Car 对象。对于小班来说可能还可以,但对于一些更复杂的课程 - 不要这么认为......

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

I have next model (simplified):

public class CarType
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }
}

public class Car
{
    [Required]
    public string Model { get; set; }

    [Required]
    public CarType Type { get; set; }

    [Required]
    public decimal Price { get; set; }
}

I want let user to choose car type from the drop-down list on the Create page.
I tried to pass the dictionary of types from database and their names through ViewBag:

ViewBag.Types = _context.CarTypes.ToDictionary(carType => carType.Name);

and select it in the page:

@Html.DropDownListFor(model => model.Type, new SelectList(ViewBag.Types, "Value", "Key"))

But in the POST method I always get constructed Car object with null in Type property.

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

    return View(car);
}

Is it possible to select custom objects with DropDownList? Because selecting values like int, string works fine.

I had an idea to write ViewModel with int ID instead of CarType and find Type by ID before saving to database. But in that way I need to duplicate all Car properties and their attributes to my ViewModel and in the end - copy all values to the new Car object. For small class its maybe OK, but for some more complex - don't think so...

This is a small example. What is the common approach to solve such problems? How to write flexible and simple code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

任谁 2024-12-06 23:36:58

这是我在这些场合使用的可靠的 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);
}

它将让您编写如下代码:

@Html.DropDownListForEnum(model => model.Type)

并为您提供一个完全填充的选择元素,并选择传入的 Type

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

Here's a trusty HtmlHelper extension method I use for these occassions:

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

Which will let you write code like this:

@Html.DropDownListForEnum(model => model.Type)

And give you a fully populated select element with the passed in Type selected.

The above method can be extended with htmlAttributes and whatever else, but it's a good start

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文