Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a 'generic' control in Asp.Net MVC Razor?

I'm trying to write a generic (meaning useful in many places) control that I can reuse throughout my company.

I'm having problems with actual C# generics in my view and viewmodel.

Here is an example of what I'm trying to do:

Generic partial view: (_Control.cshtml)

@model SimpleExample<dynamic> 

@Model.HtmlTemplate(Model.Data)

ViewData: (SimpleExample.cs)

public class SimpleExample<T>
{
    public T Data;
    public Func<T, System.Web.WebPages.HelperResult> HtmlTemplate;
}

Example usage: (FullView.cshtml)

@model Foo.MyViewData

@Html.Partial("_Control", new SimpleExample<MyViewData>
{
    Data = Model,
    HtmlTemplate = @<div>@item.SomeProperty</div>
})

The important part of the functionality I'm looking for is that consumers get a typed object when writing their Html inline so they can use Intellisense (as in FullView.cshtml).

Everything compiles fine and the intellisense is working, but I'm getting the error an runtime:

The model item passed into the dictionary is of type 
'AnytimeHealth.Web.ViewData.SimpleExample`1[Foo.MyViewData]', 
but this dictionary requires a model item of type 
'AnytimeHealth.Web.ViewData.SimpleExample`1[System.Object]'.

I've read that I might be able to use covarience on my generic type to get this to work, but I'm not sure how to do that.

Could you please instruct me how I can get this working?

like image 431
jjnguy Avatar asked Jul 03 '13 05:07

jjnguy


1 Answers

Change the define in _Control.cshtml:

@model SimpleExample<dynamic> to @model dynamic.

It will work, but will lose the intellisense of SimpleExample, the intellisense of MyViewData will still work.

I think it's because the dynamic type will be known in runtime, but the type of generics

require an early time(maybe is compile time), at that point, only object is be known.

like image 60
Jarvan Avatar answered Nov 12 '22 07:11

Jarvan