Сценарий
Предположим, у меня есть следующие два класса моделей:
public class ProductColor
{
public long Id { get; set; }
public string Name { get; set; }
}
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
public long ProductColorId { get; set; }
public virtual ProductColor ProductColor { get; set; }
}
Теперь в форме для создания нового продукта у меня может быть эта строка для поля цвета...
@Html.EditorFor(model => model.ProductColor)
Я хочу, чтобы это генерировало раскрывающийся список цветов, поэтому я создаю собственный шаблон редактора...
@model MyProject.Models.ProductColor
@using (var db = new MyProject.Models.MyDbContext())
{
@Html.DropDownList("", new SelectList(db.ProductColors, "Id", "Name", Model))
}
До сих пор это работает. Но теперь, если я отправляю эту форму создания, я получаю эту ошибку проверки:
Преобразование параметра из типа «System.String» в тип «MyProject.Models.ProductColor» завершилось неудачно, так как ни один преобразователь типов не может преобразовать эти типы.
Конечно, это связано с тем, что HTTP-запрос содержит идентификатор цвета в виде строки (например, "1"
), и потребуется некоторый код, чтобы превратить его в фактический экземпляр ProductColor
. Поэтому я написал TypeConverter
...
[TypeConverter(typeof(ProductColor.PCTypeConverter))]
public class ProductColor
{
public long Id { get; set; }
public string Name { get; set; }
public class PCTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value.GetType() == typeof(string))
using (var db = new MyDbContext())
return db.ProductColors.Find(Convert.ToInt64(value));
return base.ConvertFrom(context, culture, value);
}
}
}
Теперь отправка запроса работает нормально, как и ожидалось, но шаблон пользовательского редактора больше не работает. Просто не вызывается. Система считает, что мой тип в основном похож на строку, и просто генерирует текстовое поле.
Проблема
Я не могу заставить оба работать. Либо у меня есть преобразователь типов, и в этом случае я не получаю раскрывающийся список (поскольку шаблон пользовательского редактора никогда не вызывается), либо у меня нет преобразователя типов, и в этом случае проверка не выполняется при отправке запроса. .
Каково правильное решение этого?