4

I had some html that was being generated in multiple views in trying to keep up with DRY principles, I moved it into a Display Template.

Because the different views have different Models, how could I make the Display Template generic? The property names are the same.

Say I have these 2 models:

public class ListModel
{
 public bool Prop1 {get;set;}
 public bool Prop2 {get;set;}
}

public class DisplayModel 
{
 public bool Prop1 {get;set;}
 public bool Prop2 {get;set;}
}

Here is my Display Template - How can I make this more generic - I need it to be able to accept any Model with the same property names?

@model ListModel
{
 if(Model.Prop1)
 {
  <div>Prop1!</div>
 }
 if(Model.Prop2)
 {
  <div>Prop2!</div>
 }

}

And these are my 2 views: List and Display

List:

@model ListModel

@DisplayFor(@Model, "CustomDisplayTemplate")

Display:

@model DisplayModel

@DisplayFor(@Model, "CustomDisplayTemplate") //will currently break as the custom display template expects a ListModel
1
  • You might be better of have a base (abstract) model class or interface that both view models inherit from and base the template on that. Commented Jul 16, 2014 at 8:36

2 Answers 2

6

Make an Interface with the two properties:

public interface ISameModel
{
 bool Prop1 { get; }
 bool Prop2 { get; }
}

public class ListModel : ISameModel
{
 public bool Prop1 {get;set;}
 public bool Prop2 {get;set;}
}

public class DisplayModel : ISameModel
{
 public bool Prop1 {get;set;}
 public bool Prop2 {get;set;}
}

and afterwards use this interface as the model in your template

@model ISameModel
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, nice easy and elegant solution
4

One option is to use the UIHint attribute. When this attribute is added to a model property, Razor will look for a view template with the same name.

[UIHint("MyCustomView")]
public class ListModel
{

    public bool Prop1 {get;set;}
    public bool Prop2 {get;set;}
}

[UIHint("MyCustomView")]
public class DisplayModel 
{
    public bool Prop1 {get;set;}
    public bool Prop2 {get;set;}
}

And you can put your custom view here Views/DisplayTemplates/MyCustomView.cshtml, note that the model type is now dynamic:

@model dynamic

@if(Model.Prop1)
{
    <div>Prop1!</div>
}
@if(Model.Prop2)
{
    <div>Prop2!</div>
}

You could also add a view for the editor template here Views/EditorTemplates/MyCustomView.cshtml.

1 Comment

It's a handy option if you are unable to change your base classes. The answer from @zahorak is probably preferable in this situation, though you could use both answers combined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.