3
I saw some HTML Helpers like this: @Html.LabelFor(x => x)
and @Html.LabelFor(model => model.Propriedade)
, however, I do not understand this parameter that I must pass, x => x
, what is this?
3
I saw some HTML Helpers like this: @Html.LabelFor(x => x)
and @Html.LabelFor(model => model.Propriedade)
, however, I do not understand this parameter that I must pass, x => x
, what is this?
6
x => x.
...This parameter is used so that the helper, in the case LabelFor
know what is the property of your object Model
for which it must render a label. From that moment on, LabelFor
is able to obtain the metadata of the specified property. In case it will be interested in a metadata called DisplayName
.
case 1:
@Html.LabelFor(x => x)
This means: render a label to the object Model
as a whole. The rule for obtaining metadata from the root model depends on a rendering hierarchy. This form is most common within Editor Templates and Display Templates, because within the templates this hierarchy is available.
case 2:
@Html.LabelFor(x => x.MinhaPropriedade)
This means: render a label to the property MinhaPropriedade
. The method LabelFor
knows how to extract this information from the property metadata, one of the ways is to place the attribute Display(Name = "Label da propriedade)"
on the property.
LabelFor
get the display name?Now that I have explained the purpose of lambda being passed to the helper, I will explain how a helper works to get to the metadata of the property in question.
The helper, when called, will have access to the object HtmlHelper<TModel>
, and lambda passed per parameter. Here is the definition of the method LabelFor
:
public static MvcHtmlString LabelFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression)
HtmlHelper<TModel>
: that object is the Html
(of expression @Html.
...) on which the Extension-method LabelFor
is being applied (for any other html-helper). This is a generic object, where TModel
is the type of model being used by view.
This object has in its structure, all the metadata of the model being worked: html.ViewData.ModelMetadata
.
lambda: this parameter is passed as a lambda, but actually the type of the object that the LabelFor
receives is Expression<Func<TModel, TValue>>
. This guy is able to represent the lambda passed in the form of a AST (Abstract Syntax Tree) which will contain in its structure the property must be used in the form of a PropertyInfo
(Reflection). From there, the helper is able to associate the PropertyInfo
the available metadata in the object html.ViewData.ModelMetadata
and get the DisplayName
.
C# does this through a type inference process.
We know the method LabelFor
is generic with the types TModel
and TValue
, and also that it gets two arguments, both using these generic types:
this HtmlHelper<TModel> html
Expression<Func<TModel, TValue>> expression
Imagine the following view containing cshtml, whose model type is MeuModelo
and own a property MinhaProp
of the kind string
:
@model MeuModelo
@Html.LabelFor(x => x.MinhaProp)
C#, you know that the LabelFor
is an extension method, and will translate the method call to:
System.Web.Mvc.Html.LabelExtensions.LabelFor(Html, x => x.MinhaProp)
As the above code does not define generic types TModel
and TValue
for the method LabelFor
, then C# will have to infer ("guess") which are the types. This is done through the arguments being passed to the method:
The argument html
is receiving the value of Html
. Does that mean that HtmlHelper<TModel>
is equal to HtmlHelper<MeuModelo>
. It is possible to see that TModel
has to be MeuModelo
.
parâmetro | html | HtmlHelper<TModel>
valor passado | Html | HtmlHelper<MeuModelo>
conclusão: TModel = MeuModelo
The argument expression
is the type Expression<Func<TModel, TValue>>
... just like C# already knows that TModel
is equal to MeuModelo
, then you can replace in the type of parameter that looks like this:
Expression<Func<MeuModelo, TValue>>
That guy means "expression it receives MeuModelo
and returns TValue
". Now we just need to know what kind of TValue
.
The parameter is receiving x => x.MinhaProp
. That lambda gets x
and returns x.MinhaProp
. Then it is possible to construct the following table to analyze the types:
| Expression<Func<MeuModelo, TValue>> | x => x.MinhaProp
----------+---------------------------------------+---------------------
recebe | MeuModelo | x
retorna | TValue | x.MinhaProp
In the first line it is possible to see that x
type MeuModelo
. So, x.MinhaProp
is the type string
. And finally TValue
is the type string
.
The inference of types ended with the following conclusions:
TModel
is the guy MeuModelo
x
is the type MeuModelo
TValue
is the guy string
And now it is possible to fill in the generic types of LabelFor
:
System.Web.Mvc.Html.LabelExtensions.LabelFor<MeuModelo, string>(Html, x => x.MinhaProp)
Got it. Thanks for your help.
1
Labelfor uses its configured Model in the View to render a Label.
Example:
// Model
public class SeuModel
{
[DisplayName("Propriedade do model")]
public string SuaPropriedade { get; set; }
}
Generates a Label in your View related to your Model property:
// View
@model SeuModel
@Html.LabelFor(m => m.SuaPropriedade)
"m" is the Seumodel. The form parameter m => m.SuaPropriedade
is a lambda expression.
Result in html:
<label for="SuaPropriedade">Propriedade do model</label>
1
The idea here was to give a general idea about lambda that which was used in that parameter. Read the other answers for more complete information about the entire feature, especially Miguel Angelo’s.
That’s called lambda. See the C# documentation on the subject. It is an unnamed function that is used as an expression. It is a way of passing actions that must be performed by some other algorithm at any given time. This way when you declare the lambda You’re not running anything, you’re just defining what she should do. The code it receives at the appropriate time will call it as if it were a normal method and at this point that action will be executed. The exact execution of this is somewhat different from a normal call, but this way it becomes easy for you to understand. This way you pass information in a slightly richer way, you’re not simply passing values, you pass a whole data structure.
In this case you are saying that you are simply taking the parameter x
that the lambda is receiving and using this value as Label
in that place. This x
will receive a value passed by engine of ASP.Net MVC. He knows what to go through and he knows when to use it, he just doesn’t know what to do with this information before using it. In case neither is doing anything important but could perform a lot of things with it.
In the second example already does a little more. The parameter is model
but you don’t want to use the model
purely and simply, probably wouldn’t even, you’re picking up a member of model
. You’re getting model.Propriedade
and it is the value of this member that will be used in the Label
.
In C#, a lambda can be converted into two things: Delegate
or Expression<TDelegate>
. His explanation considers the first case, and is fully valid to understand both. It occurs that LabelFor
(of ASP.NET MVC
) if using the second case, in which the lambda is converted into an AST, from which metadata can be extracted (e.g. label, if required, format, etc.), where x
is the type of the model itself, which is defined by the user within the view file. P.S. I hate to be critical, especially of someone who helps so much! Plus, I liked the reference to the mathematical origin of the Amblas.
@Miguelangelo you are right, I gave an improved one. You must be critical, this is quality and not defect. Anyway I’ll leave more as a complement, yours is much better for the context.
Browser other questions tagged c# html asp.net-mvc .net lambda-expressions
You are not signed in. Login or sign up in order to post.
Got it, but where does Displayname come into it? The result in HTML shouldn’t be: <label for="Your property">Model property</label>?
– andré
I added an answer showing how the
LabelFor
reaches up to theDisplayName
of the property indicated by lambda. If there is any doubt just talk! Abç– Miguel Angelo
I still don’t understand the use of lambda, for me, it would make more sense like this: @Html.Labelfor(Model.Property)
– andré
This way, you would be passing the value of the property to the helper. Imagine that there is this property in the model class:
[Display(Name="Nome da pessoa")] public string Name { get; set; }
, with the value"Miguel Angelo"
attributed to her... If it were the way you said, there would be no difference between@Html.LabelFor(Model.Name)
and@Html.LabelFor("Miguel Angelo")
. It is not the value of property that we want to pass on, but something that is able to identify of what property get theDisplayName
, which is information given through the attributeDisplay
:"Nome da pessoa"
.– Miguel Angelo
I was able to understand the result of this, but I can’t understand the lambda syntax, which means x => x.Property, why X? why not Y? How does C# recognize X as the Model?
– andré
The variable name, you invent. It can be
x
,y
,m
,model
... anything. C# knows the type, because it is able to "guess" through a type inference process. I’ll edit my reply showing how C# does it step by step.– Miguel Angelo
@Take a look at [tour]. You can accept an answer if it solved your problem. You can vote for all the posts on the site as well. Did any help you more? You need something to be improved?
– Maniero