Asp.net mvc 不能同时使用TypeConverter和自定义显示/编辑器模板? 情景

Asp.net mvc 不能同时使用TypeConverter和自定义显示/编辑器模板? 情景,asp.net-mvc,asp.net-mvc-3,typeconverter,editortemplates,Asp.net Mvc,Asp.net Mvc 3,Typeconverter,Editortemplates,假设我有以下两个模型类: 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 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);
        }
    }
}
现在,提交请求可以正常工作,但自定义编辑器模板不再工作。它就是不能被调用。系统认为我的类型基本上类似于字符串,只生成一个文本框

问题 我不能让两个人都工作。要么我有一个类型转换器,在这种情况下我没有下拉列表(因为自定义编辑器模板从未被调用),要么我没有类型转换器,在这种情况下,提交请求时验证失败

正确的解决方案是什么?

  • 而不是

    @Html.EditorFor(model => model.ProductColor)
    
    请参阅ID字段:

    @Html.EditorFor(model => model.ProductColorId)
    
  • 使用包含类型名称(更准确地说,是自定义编辑器模板的名称)的
    UIHint
    属性注释该ID字段:

  • 更改自定义编辑器模板,使其使用
    long?
    作为模型类型:

    @model long?
    @using (var db = new MyProject.Models.MyDbContext())
    {
        @Html.DropDownList("",
            new SelectList(db.ProductColors, "Id", "Name", Model))
    }
    
  • 摆脱类型转换器

@model long?
@using (var db = new MyProject.Models.MyDbContext())
{
    @Html.DropDownList("",
        new SelectList(db.ProductColors, "Id", "Name", Model))
}