Сценарий
Предположим, у меня есть следующие два класса моделей:
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);
}
}
}
Теперь отправка запроса работает нормально, как и ожидалось, но пользовательский шаблон редактора больше не работает.Это просто не вызывается.Система считает, что мой тип в основном похож на строку, и просто генерирует текстовое поле.
Проблема
Я не могу заставить обоих работать.Либо у меня есть конвертер типов, в этом случае я не получаю раскрывающийся список (потому что пользовательский шаблон редактора никогда не вызывается), либо у меня нет конвертера типов, и в этом случае проверка не выполняется при отправке запроса.
Каково правильное решение этого вопроса?