Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use EditorFor over PartialView to render a partial view in MVC 4.5+

I'm using ASP.NET MVC 4.5+, and I'm trying to understand why one would want to render a partial view utilizing Html.EditorFor rather than Html.PartialView.

What I've found is that EditorFor "respects the model hierarchy", which I've gather to mean that, for an input in a view rendered by EditorFor, input names/ids reflect the nested levels of the calling model, and that PartialViews don't do this.

However, in the following partial view:

@model someModel
...
@Html.TextboxFor(m => m.complexObject.property)
...

will render the textbox as

<input id="complexObject_property" name="complexObject.property" ... >

when rendered via Html.PartialView, at least in MVC 4.5+. Which seems to me to be respecting the model hierarchy pretty well.

I understand that DisplayFor and EditorFor will tell the framework to automagically look into the ~/*Templates folder to return views for views called by these controls. So, the only thing I can think of at the moment is that we'd use Display/EditorFor to allow for this sort of file/folder structure & automagic rendering that is a bit more semantic than looking in a "Shared" folder for a specifically named partial.

As it stands now, even Microsoft's docs seem to imply that Html.EditorFor is intended to be used only to render a single input, not a view: https://msdn.microsoft.com/en-us/library/system.web.mvc.html.editorextensions.editorfor(v=vs.118).aspx

like image 390
Thomas Preston Avatar asked Apr 16 '15 15:04

Thomas Preston


People also ask

What is the use of EditorFor in MVC?

EditorFor: This control is bit smart. It renders HTML markup based on the datatype of the property. E.g. suppose there is a boolean property in model. To render this property in the view as a checkbox either we can use CheckBoxFor or EditorFor.

Which HtmlHelper is used to render partial?

RenderPartial(HtmlHelper, String, Object) Renders the specified partial view, passing it a copy of the current ViewDataDictionary object, but with the Model property set to the specified model.

Which of the following methods are used to render partial view?

Rendering a Partial View You can render the partial view in the parent view using the HTML helper methods: @html. Partial() , @html. RenderPartial() , and @html. RenderAction() .

How do you render a partial view inside a view in MVC?

In order to add Partial View, you will need to Right Click inside the Controller class and click on the Add View option in order to create a View for the Controller.


1 Answers

Assume you have a model, like so:

public class ExampleModel
{
    public int ID { get; set; }
    public string Name { get; set; }
}

Furthermore, assume you have this view, called ExampleModel.cshtml, in the EditorTemplates folder, in /Shared:

@model ExampleModel

@Html.LabelFor(m => m.Name)
@Html.TextBoxFor(m => m.Name)
@Html.HiddenFor(m => m.ID)

To continue our assumptions, let's say you have this model as well:

public class ExampleListModel
{
    public ICollection<ExampleModel> Examples { get; set; }
}

With a view for ExampleListModel, you can do something like this:

@model ExampleListModel

@Html.EditorFor(m => m.Examples)

The Razor engine will look for (and find, in this case) a view that matches the name of the "item" class (in my example, ExampleModel). When it does, it will iterate through the collection, generating a row for each item in ExampleListModel.Examples. As a side effect, it also names the controls in such a way that the collection can be posted to the controller in a manner that the default model binder understands. So the generated markup may look like

<label for="Examples[0].Name">Name</label>
<input id="Examples[0].Name" name="Examples_0__Name" value="Fee" />
<input id="Examples[0].ID" name="Examples_0__ID" value="1" />

<label for="Examples[1].Name">Name</label>
<input id="Examples[1].Name" name="Examples_1__Name" value="Fi" />
<input id="Examples[1].ID" name="Examples_1__ID" value="2" />

<label for="Examples[2].Name">Name</label>
<input id="Examples[2].Name" name="Examples_2__Name" value="Fo" />
<input id="Examples[2].ID" name="Examples_2__ID" value="3" />

and so on, with the indexes incrementing accordingly.

like image 59
Tieson T. Avatar answered Oct 19 '22 17:10

Tieson T.