ASP.NET MVC 视图/带有泛型的部分

发布于 2024-08-16 18:40:18 字数 1928 浏览 4 评论 0原文

我已经编写了一个 List`1 编辑器模板,用于与 EditorFor 扩展方法 (MVC2) 一起使用,但是在使用泛型 + null 对象时遇到了问题。

给定 /Views/Shared/EditorTemplates/List`1.ascx 中的模型

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

和模板,

<%@ 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”。但是,如果我将“null”作为 SomeFooList 中的对象之一,则我不会得到任何渲染,因为模型的类型为“object”,而不是列表通用参数中的 Foo 或更通用的 T。

本质上我想实现类似的目标,

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

这样我就知道我的列表的类型。

我还可以考虑在 null 的情况下更改 ModelMetaData.ModelType 字段(通过创建一个新对象,因为这是只读的)——但这是我想避免的那些令人讨厌的黑客行为之一。

另一个想法是使用 .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

I have written a List`1 editor template for use with the EditorFor extension methods (MVC2), however I am running into issues when using generics + null objects.

Given a model

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

and a template in /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));
        }
    }
%>

I get the expected editor for SomeFoo, and any elements of SomeFooList which are not null, as the type in ModelMetaData will be "Foo". However, if I have "null" as one of the objects in SomeFooList, I get nothing rendered as model is of type "object" and not Foo or more generically T from my list's generic arguments.

Essentially I would like to achieve something like

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

so I know the types of my list.

I could also look at changing the ModelMetaData.ModelType field in the case of a null (by creating a new object, as this is readonly) -- but this is one of those nasty hacks I would like to avoid.

Another thought is calling the EditorFor method with .Invoke and passing typeof(T) into there, but again, I would like to avoid this type of code if possible.

Any thoughts?

Update:

Trying to get the type into model meta data was looking a little trickier than I first expected. I have updated my code with the following which seems to work, but I am still not too keen on the solition:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

涙—继续流 2024-08-23 18:40:18

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

Maybe you could think about creating a custom structure similar to Nullable<T> to contain your entity? Nullable<T> contrains T to be a struct which is why you'd have to create your own one. That way you can check a HasValue property rather than having the problem with checking null and not knowing the type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文