ASP.NET MVC 3 Generic DisplayTemplates

落爺英雄遲暮 提交于 2019-12-19 18:31:38

问题


I've just started a project using ASP.NET MVC 3. I'm building on top of an existing object system, so one of the first things I have to do is define display and editor templates for the various types that exist.

Is it possible in MVC to define a DisplayTemplate with a generic argument? For example, we have a BitString<T> class which takes an enumeration as the generic argument and represents a list of options wrapping the supplied enumeration. I'm hoping I can define a single Display/Editor template that handles all BitString instances.

I'm currently using Razor for my views, but I don't mind mixing and matching with ascx (or straight C# if there is a way to do it) to achieve this

Thanks

EDIT: I think this might be a dup of this question... But it's a year and a half old, so maybe someone has a better answer at this point? Generic partial view: how to set a generic class as model?


回答1:


The problem you're describing is a fundamental principal of generics.

ICollection<Object> is not the base class of ICollection<String> even if String is a child class of Object. This is done at compile time, so you basically get two different ICollection class definitions. Therefore they cannot be casted. (Smart people of SO please feel free to correct me on any inaccuracies)

In MVC3 I have worked around this by doing the following:

class Container{
  /* Stuff here */
}

class Container<T> : Container{
 T Data {get;set;}
}

Then in your view

@model Container 

When you need just the common stuff without knowing the generic type.

@model Container<SomeDataType>

When you need the generic type data.

Use Case:

I create a "ModelContainer" class that stores my Model inside, together with an array of Error Messages that can be displayed the page in a partial. Since the partial can be used on every page, it does not know what the Generic type will be, so this workaround is needed.

This cannot be used if you are trying to access the generic data without knowing its type. Hopefully this solves your problem.




回答2:


I agree with Daryl's answer, but I would just add a small improvement.

interface IContainer{
  dynamic Data {get;}
}

class Container<T> : IContainer{
  T Data {get;set;}
  dynamic IContainer.Data
  {
     get { return this.Data; }
  }
}

Then in your view do the following:

@model IContainer



回答3:


No, it is not possible to have views with generic type if this generic type is not known. You cannot define a model like this:

@model AppName.Models.BitString<T>

T has to be known:

@model AppName.Models.BitString<SomeEnum>

This being said I would recommend you instead of trying to reuse some models you had in your old system to think of what view models you might put in place and which will be passed to the views.




回答4:


This might be less than ideal, but you should be able to use

@model BitString<dynamic>


来源:https://stackoverflow.com/questions/5286706/asp-net-mvc-3-generic-displaytemplates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!