5

Just mucking around with Razor in the ASP.NET MVC 3 RC released today.

Now, we have a concept of a "Layout Page", which i presume is the replacement of the "View Master" in the ASPX view engine.

But i do not understand the "View" property of the layout page.

Here is the example which is created when you create a new Razor View:

_Layout.cshtml

<html>
<head>
   <title>@View.Title</title>

...

MyView.cshtml

@model Mvc3FunParty.Models.Post

@{
   View.Title = "Some Title";
   Layout = "~/Views/Shared/_Layout.cshtml";
}

Which results in "Some Title" being inserted into the <title> tag of the rendered HTML.

How on earth does this work? When i hover over the "View" property, it's of type "dynamic".

So what exactly should this property be used for? Can we stuff anything in there? Is this supposed to be the Razor implementation of ViewData?

And if so, shouldn't it be of type "ViewDataDictionary"? Why the "dynamic" type for the View property?

RPM1984
  • 72,246
  • 58
  • 225
  • 350
  • and also, on a side note - has anyone had problems with intellisense? Im using Resharper, but checked the setting in VS2010 (statement completion). I get intellisense when i do `Model.` but not as im typing. – RPM1984 Nov 10 '10 at 05:58
  • Unless you define the type of your model (via `@model MyModel`) the Model property will be typed as dynamic (at least in C#) – marcind Nov 10 '10 at 06:25
  • Also, the Razor tooling does not always work with Resharper. – marcind Nov 10 '10 at 06:27
  • Yes im using @model MyModel (as in question). The Model is strongly-typed to the object Post. So that's not an issue. But i would have though if i type Model.Po .. i would get intellisense for any properties that contain "Po". I have to hit CTRL+. to get it. Oh well, better than nothing i guess. :) – RPM1984 Nov 10 '10 at 08:29
  • For anyone who cares, the Razor intellisense is a bug with Resharper: http://blogs.jetbrains.com/dotnet/2010/11/razor-intellisense-and-resharper/ A fix will come soon - for now, CTRL-Space. :( – RPM1984 Nov 11 '10 at 23:16
  • Razor intellisense does not seem to be coming to ReSharper anytime soon - read on their site it would only be ready with R# 6 around Spring. Until then they suggest either invoking intellisense manually or switching to VS intellisense entirely. – Dav Nov 29 '10 at 20:51
  • @Dav - yes, i manually invoke (CTRL-Space). But this sucks, because we can't see the method overload intellisense. So if i do `@Html.LabelFor(` CTRL-Space, i don't see the overloads for the method. – RPM1984 Nov 29 '10 at 21:07

2 Answers2

4

The View property is an alias for the ViewData property. That means that the following code

View.Title

is equivalent to

ViewData["Title"]

This works by using the new 'dynamic' feature of the C# language introduced in .NET 4. Basically it allows you to write late-bound code in what has until now been a statically-typed language. There's plenty of resources on the web if you want to learn more.

The ViewData property is still available and you can use both interchangaebly. They both use the same backing storage so changes made one way will be available the other way.

The advantage of using View is more concise syntax. The disadvantage is that you do not get IntelliSense support.

The reason why you can set View.Title in your view page and the correct value shows up in the layout page is due to the rendering order of Razor pages. We call it the inside-out rendering, which means that your view page gets executed first, it's HTML output gets collected into a buffer, then the layout page gets executed, and the buffered view page output gets injected where you call RenderBody.

marcind
  • 52,944
  • 13
  • 125
  • 111
  • That makes sense. I guess im getting confused with TempData and ViewData.Model too - my understanding is that ViewData.Model allows you to dynamically set the model rendered to the view, instead of doing return View(model). Is that correct? Thanks for your response. :) – RPM1984 Nov 10 '10 at 08:33
1

Yes, "View" is really ViewData and they're using dynamic so as to have the syntax you're seeing (View.Title)

It translates to

ViewData["Title"]

Lots of little nuggets like this in MVC and specially in MVC 3 that will confuse you :).

Liam
  • 27,717
  • 28
  • 128
  • 190
Shiv Kumar
  • 9,599
  • 2
  • 36
  • 38
  • Okay, but we never used `ViewData["Title"]` to **create data** in the markup, we used it before rending the result in the controller, and display the value in the View. That's why im confused, because it's actually creating the data in the View itself (or so it seems) – RPM1984 Nov 10 '10 at 06:07
  • In ASP.NET Web Pages (standalone version of Razor, like what WebMatrix uses) there's no controller so the values have to be set inline – John Sheehan Nov 10 '10 at 06:12
  • And also, i added `ViewModel.Title = "Foo"` to the controller action, and left it out from the view page, and it took the value "Foo". If i leave the code int he view page, it overrides the value set by the controller. Interesting... – RPM1984 Nov 10 '10 at 06:13
  • You can set ViewData values inside the view. The ViewData is passed from the controller to the view, so the view has the final say when it comes to overwriting values. – Omar Nov 10 '10 at 06:18
  • 1
    It's "the last one" that wins. That is, the order or sequence is Controller, View, Layout. So if you set a value in your ViewData in the controller, and then set it to something else in your View, the value you set in your View overwrites what you had before. Finally, your layout page gets the value and uses it to display it. Doe that make sense? – Shiv Kumar Nov 10 '10 at 07:04
  • @Shiv Kumar - I was waiting to see which of the 2 answers had the most votes, as both were correct. However, since both have 1 vote, and you got in first, i'll give it off to you. Thanks for your help. :) – RPM1984 Nov 10 '10 at 23:29