Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3 Generic DisplayTemplates

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?

like image 656
LorenVS Avatar asked Mar 13 '11 00:03

LorenVS


2 Answers

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.

like image 184
Daryl Teo Avatar answered Sep 28 '22 07:09

Daryl Teo


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
like image 42
zlsmith86 Avatar answered Sep 28 '22 07:09

zlsmith86