Direct Model.Property versus Html Helper DisplayFor in Razor - asp.net-mvc

Is there a reason to use preferably one of these:
#Model.Property
#Html.DisplayFor(m => m.Property)
I never arrived in a crossroad where one works differently from the other.
There is any difference?

Model.Property - as you know - will just write out the value of the property in question. Html.DisplayFor(m => m.Property), on the other hand, will call a display template, which can render out other markup around the property value.
For example, you might define a display template like so:
#model String
<div class="property-wrapper">
<p>#Model.Property</p>
</div>
The surrounding divs will be rendered around the value of the property when using DisplayFor (if the display template is selected, which typically means it has a filename matching the property's type, is specified in the UIHint attribute for the property, or is explicitly specified in the call to DisplayFor.
You also have access to model metadata in your display templates, meaning you can do something like this:
<div class="property-label">
#Html.DisplayNameForModel()
</div>
<div class="property-value">
#Model.Property
</div>
Display templates give you a huge amount of flexibility and reusability. The best way to explore this is to start building custom templates and see where it takes you.

Related

Should I use Html.Label helper?

In an MVC project I use an HTML.Label helper as follows:-
#Html.Label("FirstName", "First Name", New With {.class = "FieldLabel"})
Which outputs
<label class="FieldLabel" for="FirstName">First Name</label>
I've also got a corresponding input for this label.
This might sound like a stupid question, but if I was just to enter the direct output into my view instead of using the HTML helper is there absolutely any difference? So are there any advantages/disadvantages to using an HTML helper for a label?
There is no difference.
For simple stuff like labels, I don't really see the benefit of using html helpers. The helper code is longer than the actual html.
However, html helpers are great for model binding.
So if i want to bind a label or other form elements to my ViewModel i use
#Html.LabelFor(m => m.FirstName)
#Html.TextboxFor(m => m.FirstName)
This ensures that model binding works correctly. The form elements are outputted with the necessary attributes so that when the form is posted to the server, the model parameter is populated automatically on the server side.
It also takes sure of making sure that your labels are linked to the correct form elements.
The #Html.LabelFor helper will output the following html
<label for="Username">Username</label>
HtmlHelpers are designed to generate dynamic content; So, if you have such a scenario for your project those are necessary.
In your code
#Html.Label("FirstName", "First Name", New With {.class = "FieldLabel"})
everything is static, so there is no obligation to use HTMlHelper.
Html.Label gives you a label for an input whose name matches the specified input text

Is it possible to I create LabelTemplates for Html.Label and Html.LabelFor() in ASP.NET MVC?

For reasons that are questionable but practical, I'd like to create LabelTemplate defaults, just like EditorTemplates or DisplayTemplates.
So instead of this:
#Html.LabelFor(x => x.PropertyName, "Property Name")
or instead of this(the better way to do it in a View Model):
[DisplayName("Property Name")]
public string PropertyName{ get; set; }
I want this:
#Html.LabelFor(x => x.PropertyName)
With this (in a folder like this: /Views/Shared/LabelTemplates)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.String>" %>
//Display logic here
Can you help a coder out?
Create your own custom html helper.
http://develoq.net/2011/how-to-create-custom-html-helpers-for-asp-net-mvc-3-and-razor-view-engine/
This is the code you can use to convert your property names:
Regex.Replace("PropertyName", "[a-z][A-Z]", m => m.Value[0] + " " + m.Value[1]);
I know this isn't strictly an answer to your question, but since I still want to suggest a plan of action, I'll post it like this rather than in a comment.
Are you sure you want this?
If you manage to do this, you will set the label of a field to some value based on its type. This might seem tempting at first glance - you could possibly save yourself some key strokes every here and there.
But what happens if you e.g. have a type Address containing some properties for street name, number, zip code etc, and then want the user to fill in the home address and the work address in the same form - how would you label them differently and still use the same type? And even worse - do you really want the same label on all your strings? In order to avoid these two scenarios, you'll need to resort to Html.DisplayFor(m => m.PropertyName, "TemplateName") anyway, which means you'll be in just as sorry a situation as you already are. Furthermore, you'll have at least two places you have to look to find the correct display logic for your label, rather than just one.
Remember that there is no absolute requirement to use the LabelFor() helper - you can just as well just roll your own extension method on HtmlHelper, or even ignore them and output plane HTML:
<label for="Person_HomeAddress">Home address</label> <!-- the ID might be wrong -->
<%: Html.EditorFor(m => m.HomeAddress) %>
Since the EditorFor() outputs an ID matched to the name of the model and property names, you'll be fine.

MVC #Html.Display()

I have something like:
<input type="text" name="TerrMng" id="TerrMng"/>
in HTML. What is the equivalent of the above using #Html.Display?
I tried using: #Html.Display("TerrMng", TerrMng)
but was not successful. Note that I like to use #Html.Display but not sure how to translate the ID value so that it shows up.
The Display method is not for creating input boxes. You'd want to use:
#Html.TextBoxFor(m => m.TerrMng);
or the templated helper method:
#Html.EditorFor(m => m.TerrMng);
I'm assuming that you want to use modelbinding. If not, if you really just want to use a helper to simply make an input tag, use:
#Html.TextBox("TerrMng");
This would be sent to the client:
<input id="TerrMng" type="text" value="" name="TerrMng">
The first 2 methods above would result in the exact same html, if model.TerrMng was "" or String.Empty. If for some reason you don't want the value attribute, you'll need to type it out yourself.
This should do the trick if you are just wanting to display the data and not allow the user to edit the information.
#Html.DisplayFor(m => m.TerrMng);
Edit:
what-is-the-html-displayfor-syntax-for is another question on stackoverflow that may give you some more guidance.
Edit:
TerrMng does not exist on PageLoad so you cannot use the Html.Display in that way. You need to create it and fill its value with the value received from the jQuery. In this case where you would have to do the following:
HTML
#Html.Display("TerrMng"); // This creates the label with an id of TerrMng
jQuery
$("#TerrMng").val(TerrMng); // This puts the value of the javascript variable into the label
You could try something based on this. This is not exact but you could get some idea.
#Html.TextBoxFor(yourmodel => model.yourModelFieldname, null)
#Html.Display() is used instead of #Html.DisplayFor() when your model is not known at compile time, or if you prefer to work with strings, rather than with strong types. For example, these 2 are equivalents (given that your model is some class):
#Html.DisplayFor(m => m.MyProperty)
and
#Html.Display("MyProperty")
But the additional cool feature of the Display() method is that it can also do the lookup in the ViewData, and not just in your Model class. For example, here is a way to display the HTML for the property on a random object, given that we know it has a property named "Blah" (the type of the object doesn't really matter):
#{ ViewData["itsawonderfullife"] = SomeObject; }
<div>#Html.Display("itsawonderfullife.Blah")</div>
This way, we are telling HtmlHelper to look into the ViewData, instead of our Model, and to display the property Blah of a given SomeObject.

ASP.NET MVC 3 - Partial vs Display Template vs Editor Template

So, the title should speak for itself.
To create re-usable components in ASP.NET MVC, we have 3 options (could be others i haven't mentioned):
Partial View:
#Html.Partial(Model.Foo, "SomePartial")
Custom Editor Template:
#Html.EditorFor(model => model.Foo)
Custom Display Template:
#Html.DisplayFor(model => model.Foo)
In terms of the actual View/HTML, all three implementations are identical:
#model WebApplications.Models.FooObject
<!-- Bunch of HTML -->
So, my question is - when/how do you decide which one of the three to use?
What i'm really looking for is a list of questions to ask yourself before creating one, for which the answers can be used to decide on which template to use.
Here's the 2 things i have found better with EditorFor/DisplayFor:
They respect model hierarchies when rendering HTML helpers (e.g if you have a "Bar" object on your "Foo" model, the HTML elements for "Bar" will be rendered with "Foo.Bar.ElementName", whilst a partial will have "ElementName").
More robust, e.g if you had a List<T> of something in your ViewModel, you could use #Html.DisplayFor(model => model.CollectionOfFoo), and MVC is smart enough to see it's a collection and render out the single display for each item (as opposed to a Partial, which would require an explicit for loop).
I've also heard DisplayFor renders a "read-only" template, but i don't understand that - couldn't i throw a form on there?
Can someone tell me some other reasons? Is there a list/article somewhere comparing the three?
EditorFor vs DisplayFor is simple. The semantics of the methods is to generate edit/insert and display/read only views (respectively). Use DisplayFor when displaying data (i.e. when you generate divs and spans that contain the model values). Use EditorFor when editing/inserting data (i.e. when you generate input tags inside a form).
The above methods are model-centric. This means that they will take the model metadata into account (for example you could annotate your model class with [UIHintAttribute] or [DisplayAttribute] and this would influence which template gets chosen to generate the UI for the model. They are also usually used for data models (i.e. models that represent rows in a database, etc)
On the other hand Partial is view-centric in that you are mostly concerned with choosing the correct partial view. The view doesn't necessarily need a model to function correctly. It can just have a common set of markup that gets reused throughout the site. Of course often times you want to affect the behavior of this partial in which case you might want to pass in an appropriate view model.
You did not ask about #Html.Action which also deserves a mention here. You could think of it as a more powerful version of Partial in that it executes a controller child action and then renders a view (which is usually a partial view). This is important because the child action can execute additional business logic that does not belong in a partial view. For example it could represent a shopping cart component. The reason to use it is to avoid performing the shopping cart-related work in every controller in your application.
Ultimately the choice depends on what is it that you are modelling in your application. Also remember that you can mix and match. For example you could have a partial view that calls the EditorFor helper. It really depends on what your application is and how to factor it to encourage maximum code reuse while avoiding repetition.
You certainly could customize DisplayFor to display an editable form. But the convention is for DisplayFor to be readonly and EditorFor to be for editing. Sticking with the convention will ensure that no matter what you pass into DisplayFor, it will do the same type of thing.
Just to give my 2c worth, our project is using a partial view with several jQuery tabs, and each tab rendering its fields with its own partial view. This worked fine until we added a feature whereby some of the tabs shared some common fields. Our first approach to this was to create another partial view with these common fields, but this got very clunky when using EditorFor and DropDownListFor to render fields and drop downs. In order to get the ids and names unique we had to render the fields with a prefix depending on the parent partial view that was rendering it:
<div id="div-#(idPrefix)2" class="toHide-#(idPrefix)" style="display:none">
<fieldset>
<label for="#(idPrefix).Frequency">Frequency<span style="color: #660000;"> *</span></label>
<input name="#(idPrefix).Frequency"
id="#(idPrefix)_Frequency"
style="width: 50%;"
type="text"
value="#(defaultTimePoint.Frequency)"
data-bind="value: viewState.#(viewStatePrefix).RecurringTimepoints.Frequency"
data-val="true"
data-val-required="The Frequency field is required."
data-val-number="The field Frequency must be a number."
data-val-range-min="1"
data-val-range-max="24"
data-val-range="The field Frequency must be between 1 and 24."
data-val-ignore="true"/>
#Html.ValidationMessage(idPrefix + ".Frequency")
... etc
</fieldset>
</div>
This got pretty ugly so we decided to use Editor Templates instead, which worked out much cleaner. We added a new View Model with the common fields, added a matching Editor Template, and rendered the fields using the Editor Template from different parent views. The Editor Template correctly renders the ids and names.
So in short, a compelling reason for us to use Editor Templates was the need to render some common fields in multiple tabs. Partial views aren't designed for this but Editor Templates handle the scenario perfectly.
Use _partial view approach if:
View Centric Logic
What to keep all _partial view related HTML in this view only. In the template method, you will have to keep some HTML outside the Template View like "Main Header or any outer border/settings.
Want to render partial view with logic (From controller) using URL.Action("action","controller").
Reasons to use Template:
Want to remove ForEach(Iterator). Template is well enough to identify Model as a list type. It will do it automatically.
Model Centric Logic. If multiple views are found in the same displayfor Template folder, then rendering will depend on Passed Model.
Another difference that hasn't been mentioned so far is that a partialview doesn't add model prefixes while a template does
Here is the issue

Differences between Html.TextboxFor and Html.EditorFor in MVC and Razor

Why by default were these changed when adding a new "edit" view? What are advantages when using EditorFor() vs. TextboxFor()?
I found this
By default, the Create and Edit scaffolds now use the Html.EditorFor helper instead of the Html.TextBoxFor helper. This improves support for metadata on the model in the form of
data annotation attributes when the Add View dialog box generates a view.
Quoted from here.
The advantages of EditorFor is that your code is not tied to an <input type="text". So if you decide to change something to the aspect of how your textboxes are rendered like wrapping them in a div you could simply write a custom editor template (~/Views/Shared/EditorTemplates/string.cshtml) and all your textboxes in your application will automatically benefit from this change whereas if you have hardcoded Html.TextBoxFor you will have to modify it everywhere. You could also use Data Annotations to control the way this is rendered.
TextBoxFor: It will render like text input html element corresponding to specified expression. In simple word it will always render like an input textbox irrespective datatype of the property which is getting bind with the control.
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. Both will be generate the same markup.
What is the advantage of using EditorFor?
As we know, depending on the datatype of the property it generates the html markup. So suppose tomorrow if we change the datatype of property in the model, no need to change anything in the view. EditorFor control will change the html markup automatically.
The Html.TextboxFor always creates a textbox (<input type="text" ...).
While the EditorFor looks at the type and meta information, and can render another control or a template you supply.
For example for DateTime properties you can create a template that uses the jQuery DatePicker.
This is one of the basic differences not mentioned in previous comments:
Readonly property will work with textbox for and it will not work with EditorFor.
#Html.TextBoxFor(model => model.DateSoldOn, new { #readonly = "readonly" })
Above code works, where as with following you can't make control to readonly.
#Html.EditorFor(model => model.DateSoldOn, new { #readonly = "readonly" })
There is also a slight difference in the html output for a string data type.
Html.EditorFor:
<input id="Contact_FirstName" class="text-box single-line" type="text" value="Greg" name="Contact.FirstName">
Html.TextBoxFor:
<input id="Contact_FirstName" type="text" value="Greg" name="Contact.FirstName">

Resources