Using HTML.EditorFor Vs using HTML.CheckBox - asp.net-mvc

I have the following model class which contains a bool value:-
Public class Server
{
public bool IsIPUnique { get; set; }
}
Currently i am using the following to display the check box inside my Razor view:-
<input type="CheckBox" name="IsIPUnique" value="true" #(Html.Raw(Model.IsIPUnique ? "checked=\"checked\"" : ""))/> IP Unique.
but i read about the EditorFor template, and it can automatically create the check box and check/uncheck it based on the model values so i tried the following :-
#Html.EditorFor(model=>model.IsIPUnique)<span>test</span>
so my question is if i can replace my old code with the new one that uses the EditorFor ?, or asp.net mvc might deal with these values differently ?
Thanks

Basically you have 3 possibilities:
Write HTML manually (as you have done)
I would avoid writing the HTML manually if there is a HTML helper available.
Manually written HTML is prone to errors which can cause problems with model binding.
Use the specific HTML helpers (Html.CheckBoxFor)
The specific HTML helpers add a layer of abstraction to all controls.
It's easy to modify the template of all controls that use the same HTML helper and it makes your views more readable.
Use the general EditorFor
The EditorFor HTML helper is great if your model datatypes change often.
The EditorFor will adjust the input fields automatically to the new datatype and won't throw an error (as with the specific HTML helpers).
It is also a bit harder to add HTML attributes to the EditorFor while the specific HTML helpers often have overloads for them.
However, this is fixed in MVC 5.1: http://weblogs.asp.net/jongalloway/looking-at-asp-net-mvc-5-1-and-web-api-2-1-part-3-bootstrap-and-javascript-enhancements
Conclusion: in your case I would use the CheckBoxFor HTML helper because the datatype won't change likely and it will make the view cleaner

Related

Custom UIHint attribute

Is it possible to create a custom version of the UIHint attribute?
When my company first adopted MVC, we used a lot of Html.* helper methods. We are in the process of redesigning out MVC template to make use of the full power of MVC. One way we are doing this is with Display and Editor Templates.
However, one popular HTML extension method we had was to generate dropdowns for Enums. One of the options we had was to sort by the int value or the description or text of the EnumMember.
I would like to see about creating a EnumDropdown attribute that accepts several parameters that can customize the output of the HTML dropdown. However, I don't think it's possible to do this while still retaining the benefits of the UIHint attribute. Meaning, that I won't be able to simply call #Html.EditorFor(m => Model)
I had found that there is a System.Web.UI.IAutoFieldGenerator interface but it doesn't appear to do what I want. Any suggestions?
The newer versions of MVC have this built in now:
EnumDropDownListFor HTML Helper
The only thing UIHint does is suggest a Display or Editor template name. MVC will then add this name to the search path when looking for that template.
You can just use UIHint as is and have your generator create these for you in the correct folders and not have to customize it.

Custom EditorTemplate not being used in MVC4 for DataType.Date

I'm upgrading an MVC3 application to MVC4 using the instructions from Microsoft. Everything went fairly smoothly - except a few of my date model properties are now rendering differently. For example, one of these properties is defined in the viewmodel like this:
[Required(ErrorMessage = "Required")]
[DataType(DataType.Date)]
[RegularExpression(#"([1-9]|0[1-9]|1[012])...",
ErrorMessage = "Format is mm/dd/yyyy")]
[FormatHint("mm/dd/yyyy")]
[InputSize("small")]
public string Date { get; set; }
Before upgrading to MVC4, this would be rendered via calling #Html.EditorFor(m => m.Date) which would use a custom EditorTemplate - the String.cshtml template (since it's a string!). I have some custom data annotations that formats the html so it utilizes a field layout, jQueryUI, and twitter Bootstrap on the client side. The validation is done via jquery validation unobtrusive. Anyhow, this is how it previously rendered:
Now that I'm using MVC4, the String.cshtml editor template is not being called for this property any longer. It renders like this (in Chrome using the HTML5 editor stuff, I assume):
The input element looks pretty much the same - all the jQuery validation bits are in there - the only difference seems to be the type attribute is now type="date", where before it was type="text".
I'd like to continue using the String.cshtml EditorTemplate for this datatype. I'm thinking there might be a data annotation that I can put on the ViewModel property to provide a TemplateHint for #Html.EditorFor(...). If not this, I'd like to know the custom EditorTemplate that I can write to hijack MVC4's formatting (I've already tried DateTime.cshtml - it's not being called either). If not either of those, then I'm open to suggestions on how to get my property rendering like it used to.
In MVC4, the used template is determinated from :
The UIHintAttribute if any
The DataTypeAttribute if any
The type of the property
In MVC3, the DataTypeAttribute was not used.
Your property has a
[DataType(DataType.Date)]
so the template Date.cshtml is used. If it does not exists, default rendering is executed.
You have two options to resolve your problem :
Add a UIHint("String") on your property, or
Rename your editor template from String.cshtml to Date.cshtml

best practice for mvc razor view layout

I am looking for best practices for design razor view with MVC.
which would be better option:
HtmlHelper extension methods
#Html.TextBox("txtName")
or
write the html directly
<input type"text" id="txtName" name="txtName" />
I found 2 diferent links.
The first one http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx says DO use HTMLHelper extension methods.
and the second one http://codeclimber.net.nz/archive/2009/10/27/12-asp.net-mvc-best-practices.aspx says 10 – Write HTML each time you can
so i am a little cofused
Even the name HtmlHelper should already give you a hint whether you should use it or not. Do you want help? If not, just write html from the scratch. It does not really matter how the html was generated: from the scratch or using html helper. What matter is that it was generated with correct names of the inputs so that model binder can bind these inputs to the model.
For example, suppose you have the following Model that will be passed to the view and that will be received on the POST:
public class SomeModel
{
public Customer Customer { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
In order to make sure that your inputs will be binded to the model you need three inputs on your page:
<input type="hidden" id="whatever" name="Customer.Id" />
<input type="text" id="whatever" name="Customer.FirstName" />
<input type="text" id="whatever" name="Customer.LastName" />
Having this html markup will assure proper model minding. However, you can achieve this markup by using HtmlHelpers, which is a lot easier:
#Html.HiddenFor(m => m.Customer.Id)
#Html.TextBoxFor(m => m.Customer.FirstName)
#Html.TextBoxFor(m => m.Customer.LastName)
This will not only give you proper name attributes on every input, but also assign id attributes accordingly so you don't have to do that all by your self.
It appears that the author from the second article suggests to never use HtmlHelpers for two reasons:
the learning purposes: I assume by saying "web developers have to be
comfortable writing HTML" he means that developer should know
exactly what html markup is required for proper model binding.
the fear of black box: It seem that author is afraid that improper html
markup will be generated by using HtmlHelpers or he just does not
know what html will be generated.
I disagree with his phrase: "HtmlHelpers whose only reason of living is hiding the HTML away". I'd rather say "HtmlHelpers whose only reason of living is helping writing Html markup"
Summary:
HtmlHelpers help you write proper html markup, which is why I suggest you using it.
Since you're using Razor, I would make the most of what it has to offer, and the HtmlHelper extensions allow you to write html quicker and easier in a lot of places.
There may be times when you have to use Html instead, where you might want to include tags in an anchor and cannot use #Html.ActionLink, for example.
But where you can achieve the same result with either approach, I'd recommend you go with Razor.
Html helpers are not cosmetic code snippets that just save time. Consider choosing the appropriate editor based on model property types, and - what is also very important - they help in client validation, provided you include jquery.unobtrusive-ajax.js and jquery.validate.js.
The last cannot be achieved by simply writing HTML.
From what I said it can be easily derived that Html helpers "know" about the model, while plain markup does not.
At the end it is up to you to decide what to use, but knowing more about Html helpers is better when making a decision.

MVC4 Razor - #Html.DisplayFor not binding to model

I am trying to find me feet with MVC4 Razor and I'm stuck with this simple problem.
When I use #Html.DisplayFor the model is always sent back as NULL, but when I use #Html.TextBoxFor this model is fully populated, what am I missing?
Thanks in advance
This is a common issue that many people miss in the asp.net mvc framework. Not just the difference in the helpers such as HiddenFor, DisplayFor, TextBoxFor - but how exactly the framework sets up automatically collecting and validating these inputs. The magic is all done with HTML5's data-* attributes. You will notice when looking at the input tag generated that there are going to be some extra properties in the form of data-val, data-val-required, and perhaps some additional data properties for types, for example numerics would be data-val-number.
These data attributes allow the jQuery extension jquery.validate.unobtrusive.js to parse the DOM and then decide which fields to validate or generate error messages.
The actual collection of posted data is reflected from the name property. This is what should map up to the model that is in the c# or vb [HttpPost] method.
Use HiddenFor when you want to provide posted data that the user does not need to be aware of.
Use DisplayFor when you want to show records but not allow them to be editted.
Use TextBoxFor when you want to allow user input or allow the user to edit a field.
EDIT
"the purpose of this view is to enable the user to view the data before submitting it to the database. Any ideas how I can achieve this?"
You could accomplish this with a duo of HiddenFor and DisplayFor. Use HiddenFor to have the values ready to be posted, and DisplayFor to show those values.
DisplayFor will not do the Model binding. TextBoxFor will do because it creates a input element in the form and the form can handle it when it is being posted. If you want to get some data in the HttpPost action and you dont want to use the TextBoxFor, you can keep that pirticulare model proeprty in a hidden variable inside the form using the HiddenFor HTML helper method like this.
#using(Html.BeginForm())
{
<p>The Type Name is</p> #Html.DisplayFor(x=>x.TypeName)
#Html.HiddenFor(x=>x.TypeName)
<input type="submit" value="Save" />
}
Use both DisplayFor and HiddenFor. DisplayFor simply displays the text and is not an input field, thus, it is not posted back. HiddenFor actually creates <input type="hidden" value="xxxx"/>
DisplayFor builds out a HTML label, not an input. Labels are not POSTed to the server, but inputs are.
I know this is a bit of an old question but you can roll your own, custom combined display control as shown below. This renders the model value followed by a hidden field for that value
#Html.DisplayExFor(model => Model.ItemCode)
Simply use what the framework already has in place
public static MvcHtmlString DisplayExFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex)
{
var sb = new StringBuilder();
sb.Append(htmlHelper.DisplayFor(ex));
sb.Append(htmlHelper.HiddenFor(ex));
return MvcHtmlString.Create(sb.ToString());
}
Do you mean during a form post? If you use DisplayFor, this creates a element which does not contain any form values. Typically you use these in conjunction with each other to create a label for your textbox, then using the Html.TextBoxFor to allow users to modify the data element.
Example:
#Html.DisplayFor(x=>x.Item)
#Html.TextBoxFor(x=>x.Item)
Will Render
Item <a text input field following>
Or in HTML
<label for="Item">Item</label><input type="Text" id="Item" name="Item"/>

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

Resources