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));
}
}
アマール