3

EditorFor拡張メソッド(MVC2)で使用するList`1エディターテンプレートを作成しましたが、ジェネリックス+nullオブジェクトを使用すると問題が発生します。

与えられたモデル

class MyModel {
   public Foo SomeFoo { get;set; }
   public List<Foo> SomeFooList { get;set; }
 }

および/Views/Shared/EditorTemplates/List`1.ascxのテンプレート

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<%
    IEnumerable enumerableModel;
    if (Model != null && (enumerableModel = Model as IEnumerable) != null)
    {
        foreach (var v in enumerableModel)
        {
            var model = v;
            Response.Write(Html.EditorFor(m => model));
        }
    }
%>

ModelMetaDataのタイプは「Foo」になるため、SomeFooに期待されるエディターと、nullではないSomeFooListの要素を取得します。ただし、SomeFooListのオブジェクトの1つとして「null」がある場合、モデルは「object」タイプであり、リストの一般的な引数からFooまたはより一般的にはTではないため、何もレンダリングされません。

基本的に私は次のようなことを達成したいと思います

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<T>> where T : class" %>

だから私は私のリストの種類を知っています。

nullの場合にModelMetaData.ModelTypeフィールドを変更することも検討できます(これは読み取り専用であるため、新しいオブジェクトを作成することによって)-しかし、これは避けたい厄介なハックの1つです。

もう1つの考えは、.Invokeを使用してEditorForメソッドを呼び出し、そこにtypeof(T)を渡すことですが、可能であれば、このタイプのコードは避けたいと思います。

何かご意見は?

アップデート:

型をモデルのメタデータに取り込もうとすると、最初に予想したよりも少し注意が必要でした。私はコードを次のように更新しましたが、これは機能しているようですが、それでもソリトンにはあまり熱心ではありません。

if (Model != null && (enumerableModel = Model as IEnumerable) != null)
    {
        Type listType = null;

        if (enumerableModel.GetType().IsGenericType)
        {
            listType = enumerableModel.GetType().GetGenericArguments()[0];
        }

        foreach (var v in enumerableModel)
        {
            var model = v;
            if (model == null && listType != null)
                model = Activator.CreateInstance(listType);
            Response.Write(Html.EditorFor(m => model));
        }
    }

アマール

4

1 に答える 1

1

Nullable<T>エンティティを含むのと同様のカスタム構造を作成することを考えることができるかもしれません。Nullable<T>Tを構造体に制限するため、独自の構造体を作成する必要があります。そうすれば、nullのチェックやタイプがわからないという問題を抱えることなく、HasValueプロパティをチェックできます。

于 2010-01-07T15:51:59.297 に答える