我已经为使用EditorFor扩展方法(MVC2)编写了一个List`1编辑器模板,但是当使用泛型+空对象时会遇到问题。
假设有一个模型
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));
}
}
%>
我得到了SomeFoo的预期编辑器,以及SomeFooList中任何不为null的元素,因为ModelMetaData中的类型将是"Foo"。然而,如果我在SomeFooList中有一个"null"对象,由于模型的类型为"object"而不是Foo或更一般地从列表的泛型参数中获取T,因此没有任何东西被渲染。
本质上,我想实现类似于
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<T>> where T : class" %>
所以我知道我的列表类型。
如果为null,我也可以考虑更改ModelMetaData.ModelType字段(通过创建一个新对象,因为它是只读的)--但这是一种我想避免的恶劣hack。
另一个想法是使用.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));
}
}
Amar
\``)中,你就得到了
Nullable<T>`。 - LukeH