【问题标题】:Cannot use TypeConverter and custom display/editor template together?不能同时使用 TypeConverter 和自定义显示/编辑器模板?
【发布时间】:2012-03-07 00:59:49
【问题描述】:

场景

假设我有以下两个模型类:

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);
        }
    }
}

现在提交请求可以正常工作,但自定义编辑器模板不再正常。它只是没有被调用。系统认为我的类型基本像字符串,只是生成一个文本框。

问题

我不能让两者都工作。要么我有一个类型转换器,在这种情况下我没有得到下拉菜单(因为自定义编辑器模板永远不会被调用),或者我没有一个类型转换器,在这种情况下,提交请求时验证失败.

解决这个问题的正确方法是什么?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 typeconverter editortemplates


    【解决方案1】:
    • 代替

      @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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2011-02-18
      • 2016-03-19
      • 1970-01-01
      相关资源
      最近更新 更多