ASP.NET MVC 视图/局部视图与泛型

3

我已经为使用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

1个回答

1
也许你可以考虑创建一个类似于 Nullable 的自定义结构来包含你的实体?Nullable 限制 T 必须是一个结构,这就是为什么你需要创建自己的结构。这样你就可以检查 HasValue 属性,而不必担心检查 null 并且不知道类型的问题。

顺便说一下,如果有人能向我展示如何在此Markdown中正确地编写Nullable< T >而不必输入空格,我将不胜感激! - Charlie
1
将其放在反引号(\``)中,你就得到了 Nullable<T>`。 - LukeH
那听起来很公平,我明天会试着玩一下看看能不能从中得到什么。谢谢。 - amarsuperstar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接