I have seen some HTML Helpers like this: @Html.LabelFor(x => x)
and @Html.LabelFor(model => model.Propriedade)
, however, I do not understand this parameter that I should pass, x => x
, what is this?
I have seen some HTML Helpers like this: @Html.LabelFor(x => x)
and @Html.LabelFor(model => model.Propriedade)
, however, I do not understand this parameter that I should pass, x => x
, what is this?
x => x.
... This parameter is used so that the helper, in LabelFor
, knows what is the property of its Model
object to which it should render a label. From that moment, LabelFor
is able to get the metadata of the indicated property. In case he will be interested in a metadata called DisplayName
.
Case 1:
@Html.LabelFor(x => x)
That is to say: render a label for the object Model
as a whole. The rule for getting the root model metadata 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 for the MinhaPropriedade
property. The LabelFor
method knows how to extract this information from the property metadata, one of which is to put the Display(Name = "Label da propriedade)"
attribute in the property.
LabelFor
get display name? Now that I have explained the purpose of lambda being passed to the helper, I will explain the operation, ie how a helper does to get to the metadata of the property in question.
The helper, when called, will have access to the object HtmlHelper<TModel>
, and to lambda passed by parameter. Here is the LabelFor
method definition:
public static MvcHtmlString LabelFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression)
HtmlHelper<TModel>
: This object is the Html
(of the expression @Html.
...) on which the extension-method LabelFor
is being applied (valid for other html- helper any). This is a generic object, where TModel
is the type of model being used by the view.
This object has in its structure all metadata of the model being worked: html.ViewData.ModelMetadata
.
lambda: This parameter is passed as a lambda, but in fact the type of object that LabelFor
receives is Expression<Func<TModel, TValue>>
. This type is able to represent the past lambda in the form of a AST (Abstract Syntax Tree) that 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
with the available metadata on the html.ViewData.ModelMetadata
object and get the DisplayName
.
C # does this through a type inference process.
We know that the LabelFor
method is generic with the types TModel
and TValue
, and also that it receives 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 has a MinhaProp
property of type string
:
@model MeuModelo
@Html.LabelFor(x => x.MinhaProp)
C # knows that 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 the generic types TModel
and TValue
for the LabelFor
method, then C # will have to infer ("guess") what the types are. This is done through the arguments being passed to the method:
The argument html
is getting the value of Html
. This means that HtmlHelper<TModel>
is equal to HtmlHelper<MeuModelo>
. You can 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 of type Expression<Func<TModel, TValue>>
... but since C # already knows that TModel
is equal to MeuModelo
, then you can substitute in type of parameter that looks like this:
Expression<Func<MeuModelo, TValue>>
This type means "expression that receives MeuModelo
and returns TValue
" . Now we only need to know what kind of TValue
.
The parameter is receiving x => x.MinhaProp
. This lambda receives 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 you can see that x
is d type MeuModelo
. Therefore, x.MinhaProp
is of type string
. And finally TValue
is of type string
.
Type inference is over, with the following conclusions:
TModel
is type MeuModelo
x
is of type MeuModelo
TValue
is type string
And now it's possible to populate generic types of LabelFor
:
System.Web.Mvc.Html.LabelExtensions.LabelFor<MeuModelo, string>(Html, x => x.MinhaProp)
LabelFor uses your configured Model in the View to render a Label.
Example:
// Model
public class SeuModel
{
[DisplayName("Propriedade do model")]
public string SuaPropriedade { get; set; }
}
Generate a Label in your View related to your Model's property:
// View
@model SeuModel
@Html.LabelFor(m => m.SuaPropriedade)
The "m" is YourModel. The parameter in m => m.SuaPropriedade
is a lambda expression .
html result:
<label for="SuaPropriedade">Propriedade do model</label>
The idea here was to give an overview of lambda that is what was used in the referenced parameter. Read the other answers for more complete information about the whole feature, especially Miguel Angelo's.
This is 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 are not running anything, you are just defining what it should do. The code that receives it at the appropriate time will call it as if it were a normal method and at that moment that action will be executed. Executing this is a bit different from a normal call, but this way it's easy for you to understand. This way you pass information in a slightly richer way, you are not simply passing values, you pass a whole structure of data.
In this case you are saying that you are simply taking the x
parameter that lambda is receiving and using this value as Label
in that place. This x
will receive a value passed by the engine of ASP.Net MVC. He knows what to pass and he knows when to use it, he just does not know what to do with this information before using it. In case you are not doing anything important but could do a lot of things with it.
In the second example, do a little more. The parameter is model
but you do not want to use model
purely and simply, probably would not, you're getting a member of model
. You are getting model.Propriedade
and it is the value of this member that will be used in Label
.