假设我有以下两个模型类:
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请求包含颜色ID作为字符串(例如"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);
}
}
}
现在提交请求可以正常工作,但自定义编辑器模板不再适用。它只是没有被调用。系统认为我的类型基本上像字符串,只是生成一个文本框。
我无法兼顾两者。我有一个类型转换器,在这种情况下我没有得到下拉列表(因为自定义编辑器模板永远不会被调用),或者我没有类型转换器,在这种情况下,验证在提交请求时失败
对此有什么正确的解决方案?
答案 0 :(得分:2)
而不是
@Html.EditorFor(model => model.ProductColor)
参考ID字段:
@Html.EditorFor(model => model.ProductColorId)
使用UIHint
属性注释该ID字段,该属性包含类型名称(更准确地说,是自定义编辑器模板的名称):
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
[UIHint("ProductColor")]
public long ProductColorId { get; set; }
public virtual ProductColor ProductColor { get; set; }
}
更改自定义编辑器模板,使其使用long?
作为模型类型:
@model long?
@using (var db = new MyProject.Models.MyDbContext())
{
@Html.DropDownList("",
new SelectList(db.ProductColors, "Id", "Name", Model))
}
摆脱TypeConverter。