2

シナリオ

次の 2 つのモデル クラスがあるとします。

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

リクエストの送信は期待どおりに機能するようになりましたが、カスタム エディター テンプレートは機能しなくなりました。呼び出されないだけです。システムは、私のタイプが基本的に文字列のようなものであると考え、テキスト ボックスを生成するだけです。

問題

両方を機能させることはできません。型コンバーターがある場合はドロップダウンが表示されない (カスタム エディター テンプレートが呼び出されないため)、または型コンバーターがない場合は、要求が送信されたときに検証が失敗します。 .

これに対する正しい解決策は何ですか?

4

1 に答える 1

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 を取り除きます。

于 2012-02-15T17:21:39.753 に答える