开发者

ASP.NET MVC Selecting value from dropdownlist

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?


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜