What is the difference between mvc HTML.Control and ControlFor (TextBox, checkbox etc)..
One is strongly typed. If you have a view that expects a model of type Customer with a property "CustomerName", you can render the value with either way
<%=Html.Label("CustomerName") %>
<%=Html.LabelFor(a => a.CustomerName) %> //strongly typed
With the second method (lambda expression), you avoid magic strings. You also have the ability to inspect ModelMetadata to perform additional customizations.
Read about Model metadata here:
http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-2-modelmetadata.html
The For versions of the HTML helper methods take properties as strongly-typed lambda expressions instead of strings.
For example, the following to statements are equivalent:
<%=Html.TextBox("Description") $>
<%=Html.TextBoxFor(m => m.Description) $>
However, if you rename the Description property, the TextBoxFor call will give a compiler error, whereas the TextBox call will not fail until you visit that page.
The following article explains the difference in general:
http://weblogs.asp.net/scottgu/archive/2010/01/10/asp-net-mvc-2-strongly-typed-html-helpers.aspx
Simply put, HTML.ControlFor is strongly typed, which allows use of lambda expressions and automatically takes the nameof the property specified as the name/id of the control.
Related
I understand if I put #model Product in my view then in the expression #Html.TextBoxFor(x => x.ProuctId) the type of type lambda is Func<Product, int>. I can understand how the framework uses the lambda to get the value simply by just calling it but how does it get the string "ProductId" to use in the for the id and name properties of the input that is rendered? Can this somehow be obtained using reflection, if so how?
I've just noticed that the type of the parameter for TextBoxFor is actually Expression<Func<Product, int>> so am guessing Expression has something to do with the magic. It also raised the question of how does the lambda get automatically wrapped in an Expression object?
While using Html Helpers in Views. If I try to write a lambda expression like "m=>...." . Small m automatically changes into "Model". It usually happens If I choose helper without "For" word in it. like DropdownList insted of DropdownListFor . Also if I use any other letter for lambda expression it changes into something else.
And m=>m.name and Model.name also gives the same result if I am not wrong.
Why?
If you do something like this:
#Html.TextBoxFor(m => m.Name)
And this:
#Html.TextBoxFor(Model => Model.Name)
In Asp.Net MVC at Views, we have a property called Model, which access the Model (capital M) you are getting from the controller. It is case sensitive.
Html Helper without the For word in the name like Html.TextBox() or Html.DropDownList() are helpers to generate html tags for any other field that is not in the model. Actually, in the first version of asp.net mvc, we did not have the strongly typed view, so, we could not have the Html.TextBoxFor for sample, so, we used to use this weakly helpers.
Out of the ontext of MVC, in terms of lambda expression, the name of argument does not matter.
that happens because of intellisense of visual studio.DropDownList expects you to supply a parameter that is string not lambda expression. When you try to enter lambda expression it chooses one of the word in the intellisense list. For example if you write b and enter = it automatically gonna change it to base=. To use lambda expression use DropDownlistFor.
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.
I’ve got a question about the default account model, view and controller generated when creating a new MVC 3 project in Visual Studio 2010 (using razor).
The generated AccountController uses this to load the view:
public ActionResult LogOn()
{
return View();
}
And the corresponding view (LogOn.cshtml) contains code like this:
#Html.LabelFor(m => m.UserName)
My question is where is this variable “m” defined? How does it know that this refers to the model? There is no model being passed to the view but "m" still works. If I change all the references to “m” to another letter it still works! Could someone explain what’s going on here?
Thanks
This is a C# 3.0 feature called "Lambda Expression".
You can check these nice articles to know what it is (by the way, it's amazingly useful).
http://blogs.msdn.com/b/ericwhite/archive/2006/10/03/lambda-expressions.aspx
http://blah.winsmarts.com/2006/05/19/demystifying-c-30--part-4-lambda-expressions.aspx
For the 2nd part of your question, if you notice, all the methods under #Html are model-related methods, which mean that all of them are expecting to work on your passed model.
And if you check the first line in your Logon view, you will find this line:
#model YOUR_APP_NAME.Models.LogOnModel
Which defines that the model type of this view is of type logonModel. (Which can be found inside your Models folder.)
This way, the weird m is represening the passed Logon model, and so we can access the properties under the passed model easily like typing m.UserName
The 'm' in this situation if a variable name that is supplied as part of a lamda expression.
From the link:
All lambda expressions use the lambda
operator =>, which is read as "goes
to". The left side of the lambda
operator specifies the input
parameters (if any) and the right side
holds the expression or statement
block. The lambda expression x => x *
x is read "x goes to x times x."
Lambda expressions are just shorthand C# delegates. Delegates are functions that can be passed as parameters, much like javascript functions, like callbacks.
x => x.Name is really just shorthand for creating one of these delegates, that takes some variable x as a parameter, and returns this variables Name property.
(parameters) => (expression)
Is shorthand for
Function(parameters) {
return expression;
}
So LabelFor takes one of these shorthand functions as parameters, and runs it against the model context you have specified.
I'm using ASP.NET MVC RC1 and trying to bind a textbox to an object property like so:
<%= Html.TextBox("Comments.Contacts[0].ContactName") %>
It seems like it should work, since this does:
<%= ((MuralProject)ViewData.Model).Comments.Contacts[0].ContactName %>
But alas, the result in the textbox is an empty string. Am I doing something wrong?
The first argument for the text box extension method sets the name of the input element that's eventually created and also tries to get an entry from ViewData/Model (for the model it uses TypeDescriptors / reflection) based on that argument.
The way it does this is just by splitting up the input string at the dots then checking the ViewDataDictionary for specific keys and the Model via reflection so in the case you give it'll try and look for Contacts[0] rather than Contacts and won't pick up your property.
To get around this you just need to supply the actual value of the object e.g.
Html.TextBox("Comments.Contacts[0].ContactName",
Model.Comments.Contacts[0].ContactName)
You can see this yourself if you look at the MVC source and take a peek at the ViewDataDictionary class.