ASP.NET MVC Выбор значения из выпадающего списка - PullRequest
1 голос
/ 17 августа 2011

У меня есть следующая модель (упрощенно):

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 я всегда получаю конструкциюCar объект с null в свойстве Type.

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

    return View(car);
}

Можно ли выбрать пользовательские объекты с DropDownList?Поскольку выбор значений типа int, string работает нормально.

У меня была идея написать ViewModel с int ID вместо CarType и найти Type by ID перед сохранением в базе данных.Но таким образом мне нужно продублировать все свойства Car и их атрибуты в моей ViewModel и в конце - скопировать все значения в новый объект Car.Для небольшого класса это может быть хорошо, но для некоторых более сложных - не думайте так ...

Это небольшой пример.Каков общий подход к решению таких проблем?Как написать гибкий и простой код?

1 Ответ

1 голос
/ 17 августа 2011

Вот надежный метод расширения 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)

и даст вам полностью заполненный элемент selectс выбранным значением Type.

Вышеупомянутый метод может быть расширен с помощью htmlAttributes и любым другим, но это хорошее начало

...