I have a question that probably is quite basic but I don’t really get it. So here it comes.
If I have a view template file ( .cshtml ) and have a codeline like this:
@Html.DisplayFor(m => m.CurrentPage.MainBody)
If I look on the declaration for DisplayFor it looks like this:
public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression);
So this is an extension method that takes an Expression parameter but TModel and TValue seems to be generic ( and apparently you can send in a lambda expression to an Expression).
How can the lambda expression here ( m => m.CurrentPage.MainBody ) know what m is?
If I have a lamdba expression like this:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
Then the context for (n => n % 2 == 1) is logic, the lamdba expression is used to evaluate each element in numbers.
But in the case above with @Html.DisplayFor(m => m.CurrentPage.MainBody) what is the context here? What is m referring to? Is that somehow “magically” connected to the @model in this particular view? ( which in this case is@model PageViewModel<ArticlePage> “).
So to sum up, what is m referring to in the expression ( m => m.CurrentPage.MainBody ) ? Is it assumed somehow that it is refering to the model provided in the view via the @model?
The Html.DisplayFor helper is defined like this:
Notice how this helper can only be invoked on a strongly typed
HtmlHelper<TModel>. If you do not have a strongly typed view with a model you cannot use theHtml.DisplayForhelper becauseHtmlon which you are invoking this extension method is simplyHtmlHelperand notHtmlHelper<TModel>.So inside your view when you have a model:
The Html property is of type
HtmlHelper<MyViewModel>so the DisplayFor helper knows about your model.Basically when you have a strongly typed view,
Html.DisplayFor(m => m.CurrentPage.MainBody)is a shortcut forHtml.DisplayFor<MyViewModel, TheTypeOfYourMainBodyProperty>(m => m.CurrentPage.MainBody)where the compiler could infer the generic arguments from the context and you don’t need to write them explicitly.