1
votes

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?

1

1 Answers

4
votes

How can the lambda expression here ( m => m.CurrentPage.MainBody ) know what m is?

The Html.DisplayFor helper is defined like this:

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

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 the Html.DisplayFor helper because Html on which you are invoking this extension method is simply HtmlHelper and not HtmlHelper<TModel>.

So inside your view when you have a model:

@model MyViewModel

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 for Html.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.