3

Lets take this line: @Html.LabelFor(m => m.UserName) which is on a page with this line: @model CurrencyMvc.Models.RegisterModel

I assume that when the page view renders LabelFor is called automatically with a reference to the model described, and that the Lambda function tells it how to get the info it needs from the model?

Its not clear to me why we're passing a function in when we could pass the actual value e.g. m.Username.

Oh and when this helper is called where does "m" come from?

0

3 Answers 3

6

There are 2 classes that are used for razor pages (the second derives from the first):

  1. System.Web.Mvc.WebViewPage
  2. System.Web.Mvc.WebViewPage<T>

So when you use a strongly typed view by specifying a model, your view derives from the generic version and the Html property is a generic HtmlHelper<TModel>. Since it is a good practice to always use strongly typed views I will no longer talk about the first class since it is of no interest.

Let's take a look at the signature of the LabelFor extension method:

public static MvcHtmlString LabelFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression
)
{
    ...
}

As you can see from this definition the LabelFor method is an extension method for the HtmlHelper<TModel> class which takes 1 argument. This method is available only when you have a strongly typed view. The argument represents a lambda expression which is limited only to a member access expressions (the helper will throw an exception if you try to use some fancy stuff). It takes the model as argument and a property of this model must be returned.

Thanks to this information the helper is capable of determining the name of the member that is being specified and thus generate the correct markup. And since the argument is a lambda expression it is also capable of determining the metadata of this property (you might have decorated your view model property with attributes such as [DisplayName], ... allowing you to specify additional metadata). If the helper took only a value as you asked: Html.LabelFor(Model.SomeValue) you understand that inside this LabelFor method all you are going to get is this value. You will never be able to access the metadata of the view model which is a fundamental notion in ASP.NET MVC.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you that - I wish that I could give you credit, however the other answer came first and I'm too new to be able to vote up. Your post was equally useful. Thanks again.
4

I assume that when the page view renders LabelFor is called automatically with a reference to the model described, and that the Lambda function tells it how to get the info it needs from the model?

I'm not entirely sure I get what you mean with this part, I guess you mean how @LabelForknows which model to use?

Well yes, if you look at the syntax which is like this:

public static MvcHtmlString LabelFor<TModel, TValue>(
    this HtmlHelper<TModel> html,
    Expression<Func<TModel, TValue>> expression
)

You can see the first parameter starts with this which makes it an extention method. When you add the line @model CurrencyMvc.Models.RegisterModel this HtmlHelper<TModel> becomes your RegisterModel.

Its not clear to me why we're passing a function in when we could pass the actual value e.g. m.Username.

Most of the time a "lambda expression" is simply a Func<T> but with the razor @Html.xfor (such as @Html.LabelFor) you pass in an Expression<Func<TModel, TValue>> which is a tree data structure for a lambda expression. In layman's terms; kind of an uncompiled Func.

If you'd pass in m.Username the method would simply have "Dale Burrell". But for example, html textbox is generated as

<input type="text" name="Username" value="Dale Burrell">

So as you can see, it actually needs the m.Username variable name

Oh and when this helper is called where does "m" come from?

That's just a variable. Just like foreach(var m in dataset){} "where does the m come from?" -- you made it up. You can replace the m with anything

3 Comments

OK, I think that is starting to make sense to me... its been a long day with lots of new information. So just to clarify, and I paraphrase for simplicity here, I can sort of consider the LabelFor method as being called as a method (extended) on my RegisterModel class. Then within the LabelFor method it uses/calls 'expression' to get the value required AND (big and here) also deconstructs 'expression' to work out which property(ies) in the class the value are associated with? And thereby which attributes to take into account, validation etc etc Am I on the right track?
Umm.. yes, besides the "(extended) on my RegisterModel"; this HtmlHelper<TModel> is an extention for HtmlHelper, where TModel is your model. In razor you can use the HtmlHelper like @Html. So if you would not use it as extention, you'd do HtmlHelper(RegisterModel, m => m.UserName) instead. -- but the rest, yes that sounds right. Just for terminology; it does not deconstructs the expression, it compiles it with the Expression.Compile() method.
Yeah I think I'm getting my head around that, so because its a HtmlHelp<RegisterModel> it will have a reference to an instance of my RegisterModel from within? So when I call Html.LabelFor() it knows about my RegisterModel object. (And when no RegisterModel exists it creates a blank one?) Sorry if I seem stupid about this, just trying to get it clear in my head. Also when I say deconstruct, I mean as well as compiling the Lambda expression it must also use the expression tree to determine which object property to query the attributes of e.g. [Display(Name)]?
3

I know it has been some time but I think the link below will be quite helpful for the ones still looking for a good explanation. http://odetocode.com/blogs/scott/archive/2012/11/26/why-all-the-lambdas.aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.