As you might know, ASP.NET MVC has support for custom view overrides for model fields within views. There are special folders in the Views folder called Views\Shared\EditorTemplates, Views\Shared\DisplayTemplates and so on, and these folders can contain files like Views\Shared\EditorTemplates\String.cshtml, which will override the default view used when calling @Html.EditorFor in a view with a model with a String field.
What I want to do is to use this functionality for a custom kind of templates. I want to have a folder like Views\Shared\GroupTemplates that may contain e.g. Views\Shared\GroupTemplates\String.cshtml and Views\Shared\GroupTemplates\Object.cshtml, and I want to create a HtmlHelper method that allows me to call for example Html.GroupFor(foo => foo.Bar), which will load the template in String.cshtml if Bar is a String property, and the template in Object.cshtml otherwise.
Full example of the expected behavior; if Views\Shared\GroupTemplates\String.cshtml contains this:
@model String
This is the string template
… and Views\Shared\GroupTemplates\Object.cshtml contains this:
@model Object
This is the object template
I have a model like:
class Foo
{
public bool Bar { get; set; }
public String Baz { get; set; }
}
And a view in Views\Foo\Create.cshtml like:
@model Foo
@Html.GroupFor(m => m.Bar)
@Html.GroupFor(m => m.Baz)
When I render the view Create.cshtml, the result should be this:
This is the object template
This is the string template
How should GroupFor be implemented?
The thing is that you can easily specify your view location like that
or even override default behaviour by implementing custom view engine, for an example see this blog A Custom View Engine with Dynamic View Location
But you also want to reuse the logic which determines the view name based on its model type. So that if a view with String name doesn’t exist an Object view is picked up. Which means going through parent classes.
I’ve had a look how EditorFor is implemented:
It uses TemplateFor method which is internal and you can’t just reuse it.
So I can only see of two options:
Hope it helps!