问题
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