How do strongly typed HTML helpers work in ASP.Net MVC? - asp.net-mvc

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?

Related

Is the Expression in an HtmlHelper For method's signature solely for type checking the View?

expression
Expression<Func<TModel,TProperty>>
An expression that identifies the object that contains the properties to display.
DropDownListFor<TModel,TProperty>(HtmlHelper<TModel>,
Expression<Func<TModel,TProperty>>,
IEnumerable<SelectListItem>, String, IDictionary<String,Object>)
It is here.
Is the Linq Expression there solely for the View and compilation or other typing needed in ASP.NET MVC? I know what TModel is, but TProperty doesn't really show me much in Visual Studio. SelectListItem and the rest are self-explanatory.
I am confused because of this SO question.
Difference between DropDownlist or DropDownListFor Html helper
It seems it is for that and more, but I am not sure. This is more of a question on how to read the signature in Microsoft's Documentation and its implications. Sometimes is seems the Expression is for the View and doesn't really mean too much in the SelectList as people pass in the ViewBag with elements for Value and Text. Other times is looks like it actually contributes to what something displays, like in DropDownDisplayFor.

Asp.Net MVC : difference between model and Model in Views

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.

How does .NET MVC know how to render a models attributes using lambda expressions?

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.

ASP.Net MVC, Dynamic Property and EditorFor/LabelFor

I am using MVC 3 w/ Razor and using the new dynamic ViewBag property. I would like to use the ViewBag property with the EditorFor/LabelFor Html helpers but can't figure out the syntax.
The View does have a #model set, but the object I am trying to use is not part of that model. I am aware I can create a ViewModel but that is not what I am after.
Can anyone help?
Controller:
var myModel= _repo.GetModel(id);
var newComment = new Comment();
ViewBag.NewComment = newComment;
return View(myModel);
View:
#model Models.MyModel
#(Html.EditorFor(ViewBag.NewComment.Comment))
I haven't tried it, but this should work I think.
#(EditorFor(m => ViewBag.NewComment)
It is possible to use a Linq-to-SQL syntax, but use a completely different object on the right side.
Not knowing what your Comment Model looks like, my gut reaction would be to just do:
#Html.EditorFor(ViewBag.NewComment)
However, because ViewBag is dynamic, you may need to cast NewComment before you use it, in order to get the EditorFor magic.
#Html.EditorFor(ViewBag.NewComment as Comment)
Update
Strike that, EditorFor can only accept an Expression as a parameter, and that Expression must return a property of the page model. I don't think EditorFor or EditorForModel are going to be of any use to you if you don't want to use a ViewModel. Have you considered switching the roles of whatever it is you're using the Model for, with that of the ViewBag?
If for some reason I need to use ViewData to pass the model into my view I do the following to allow for the Html.DisplayFor() helpers.
In the views code block I cast the ViewData model object to its underlying type
var newCommentModel = ( NewComment )ViewBag.NewComment;
Then I assign the following expression to the helper using the strong-typed reference
#Html.DisplayFor( model => newCommentModel )
The expression tree now contains a strongly-typed model and the DisplayTemplate is correctly displayed.

The difference between html control and controFor

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.

Resources