ASP.NET MVC 3: New @model keyword in Razor

Two weeks ago we shipped the ASP.NET MVC 3 Beta Release.  It supports “go live” deployments, and includes a bunch of nice improvements/enhancements.  You can see a summary of the new ASP.NET MVC 3 features in my beta announcement post.  Also read my original ASP.NET MVC 3 Preview post to learn about other ASP.NET MVC 3 features that showed up with that initial preview release.

This post is the first of several “mini-posts” I’m going to do that talk about a few of the new ASP.NET MVC 3 Beta features in more detail.  In today’s post I’m going to discuss the new @model directive that is now supported with the new Razor view-engine, and which helps make view files more concise and cleaner.

Razor Basics

ASP.NET MVC 3 ships with a new view-engine option called “Razor” (in addition to continuing to support/enhance the existing .aspx view engine). 

You can learn more about Razor, why we are introducing it, and the syntax it supports from my Introducing Razor blog post.  If you haven’t read that post yet, take a few minutes and read it now (since the rest of this post will assume you have read it).

Once you’ve read the Introducing Razor post, also read my ASP.NET MVC 3 Preview post and look over the ASP.NET MVC 3 Razor sample I included in it. 

New @model directive

Let’s now look at a new feature we added with the ASP.NET MVC 3 Beta – the @model directive.  The @model directive provides a cleaner and more concise way to reference strongly-typed models from view files.

To see this in action, let’s look at a (super) simple scenario where we want to implement a /Products URL that lists product categories from a database:

image

Below is a simple ProductsController implementation that implements the /Products URL.  It retrieves a list of product categories from a database, and then passes them off to a view file to render an appropriate HTML response back to the browser:

image

Referencing the Model with the first ASP.NET MVC 3 Preview

If we had used Razor with the first ASP.NET MVC 3 Preview, our Index.cshtml view file would have had an @inherits statement at the top of the file that indicated that we wanted to derive the view from the “System.Web.Mvc.WebViewPage<TModel>” class.  We’d then indicate that we wanted our view file to be strongly-typed by passing the type of the view model to it:

image

This works (and is still supported with ASP.NET MVC 3) – but is a little verbose. 

Referencing the Model using the ASP.NET MVC 3 Beta and new @model syntax

We’ve added a new @model directive with the ASP.NET MVC 3 Beta that provides a cleaner and more concise way to indicate you want to use strongly-typed model classes within your view files.  You can now just write @model StrongModelType at the top of your Razor view file, and you do not need to have an @inherits or specify a view base class anymore:

image

The above syntax is conceptually the same as before (except with a lot fewer characters).  It is easier to read and type.

Below is what a complete Index.cshtml view implementation might look like to render our original screen-shot above:

image

One question you might ask is – so what does my view file derive from then if it isn’t specified?  By default, Razor will derive the view from the System.Web.Mvc.WebViewPage<TModel> base class.  You can optionally override this default base class (as well as the list of code namespaces that are imported by default within view files) by modifying the web.config file of your \Views directory.  This enables you to keep a clean (and DRY) syntax within your view files even if you have created a custom View base class that you want to use.

Note: Visual Studio Code/Markup Intellisense and Colorization within Razor files aren’t enabled yet with the Beta earlier this month.  You’ll see this show up in a few weeks though – and it will support full code intellisense for HTML, JavaScript, CSS and C#/VB code within Razor files.

Summary

One of the themes we’ve focused on with the ASP.NET MVC 3 and Razor releases has been to make the code you write cleaner and more concise.  The above @model keyword is a small feature, but contributes nicely towards making view files even easier to read and write. I’ll be covering other nice improvements like this that are new to the ASP.NET MVC 3 Beta in future posts.

Hope this helps,

Scott

44 Comments

  • Thanks for the post. When will be available the intellisense feature in Razor Views?

  • Nice post, I can never remember what I need to write in the inherits section on a view page!

    Will this be the default when we add in new Razor view page with a model in the future?

  • Simple clear and easy to use! There are no other words to describe this view engine

  • Loving the new Razor syntax, but PLEASE tell me you guys are almost done with full intellisense support, right? ;)

  • Razor gets better and better. Kudos to those working on it.

  • It'd be nice if there was a way, perhaps in web.config, to specify the default base type for a page that is declared in this manner. In many projects I've implemented, we always had a custom base type for the page universally and fighting the frequent failure to remember to update the inheritance type vs. what the tools (Visual Studio) always generated for us was our trouble spot. Seems with what you've shown here we made two steps forward and two steps back.

  • The fewer characters we need to type, the better it is! Any ideas when are you guys planning to ship the final version?

  • Nice to see some more improvements!

    Will there also be improved support for localization in the final version? Like fully supporting the implementation of different languages, both in the URL as in the content?

  • This is one of my favourite things about Razor in general. Simple concise ways of representing information. I know it's just syntactic sugar but it makes it much easier to pick up and comprehend. I've already started porting some sandbox MVC Projects to Razor, just to demo it to colleagues and they all just "get it" straight away. Great stuff Scott.

  • nice post!
    looking forward to the intellisense :D

  • To shiju: Scott wrote just above the summary this note:

    Note: Visual Studio Code/Markup Intellisense and Colorization within Razor files aren’t enabled yet with the Beta earlier this month. You’ll see this show up in a few weeks though – and it will support full code intellisense for HTML, JavaScript, CSS and C#/VB code within Razor files.

    So it'll take another several weeks.

    Grz, Kris.

  • That's a great feature of the Spark view engine you are adding to Razor. Thuis proves a point that it is about choosing the best ideas, and not always being the one that comes up with them (although Microsoft has a lot of great innovations).

  • Great!Intellisense ... intellisense ...intellisense ... I want

  • Will ability to update multiple divs in different regions of a page in one Ajax call be available in mvc3 final?

  • Thanks for the informative post. What is the difference between using the "@model StrongModelType" syntax you explain in this post and the "@model dynamic" syntax as a way to strongly type the data in the view?

  • With this go live license, does that mean I'm fairly safe to upgrade my MVC 2 project that'll be going live in a couple of months? With asking for a hard ETA, is RTM in our near future?

  • @Jon Davis
    There is a way to specify the default base class used. Open your web.config in your /Views folder and edit the 'pageBaseType' attribute in the following xml fragment.





  • Reply to Jon Davis:

    Mr Guthrie wrote about this specifically:

    "You can optionally override this default base class (as well as the list of code namespaces that are imported by default within view files) by modifying the web.config file of your \Views directory. This enables you to keep a clean (and DRY) syntax within your view files even if you have created a custom View base class that you want to use."

  • @Kevin Ortman

    I noticed

    ""

    Does this mean all Razor views inherit from Page and can not inherit from Control?

  • Very good improvement!

    +1 on localization!

  • @model is definitely an improvement over the @inherits syntax. For me, Razor is definitely THE killer feature in MVC 3. (Unobtrusive JS is also nice, but just doesn't get me as excited)

  • @shiju

    >>>>>>> Thanks for the post. When will be available the intellisense feature in Razor Views?

    That will show up in the next drop - within a few weeks now.

    Thanks,

    Scott

  • @chrishardy,

    >>>>>>> Nice post, I can never remember what I need to write in the inherits section on a view page! Will this be the default when we add in new Razor view page with a model in the future?

    Yep - that is the default now the the beta available today.

    Thanks,

    Scott

  • @Richard,

    >>>>>>>> Loving the new Razor syntax, but PLEASE tell me you guys are almost done with full intellisense support, right? ;)

    Yes - that will show up in the next drop (within next few weeks). Full intellisense will be supported.

    Thanks,

    Scott

  • @Jon,

    >>>>>>> It'd be nice if there was a way, perhaps in web.config, to specify the default base type for a page that is declared in this manner. In many projects I've implemented, we always had a custom base type for the page universally and fighting the frequent failure to remember to update the inheritance type vs. what the tools (Visual Studio) always generated for us was our trouble spot. Seems with what you've shown here we made two steps forward and two steps back.

    Not sure if you saw my bit about this in the post - that is definitely supported:

    "One question you might ask is – so what does my view file derive from then if it isn’t specified? By default, Razor will derive the view from the System.Web.Mvc.WebViewPage base class. You can optionally override this default base class (as well as the list of code namespaces that are imported by default within view files) by modifying the web.config file of your \Views directory. This enables you to keep a clean (and DRY) syntax within your view files even if you have created a custom View base class that you want to use."

    Hope this helps,

    Scott

  • @Jason Hooten

    >> Does this mean all Razor views inherit from Page and can not inherit from Control?

    Well, the 'pages' fragment has both 'pageBaseType' and 'userControlBaseType' defined, so I assume the 'system.web.webPages.razor' fragment has a similar construct, but I haven't verified.


  • @Ambuj Sinha,

    >>>>> Any ideas when are you guys planning to ship the final version?

    We are looking to ship the final release in the next few months.

    Hope this helps,

    Scott

  • @Rolf,

    >>>>>> Will there also be improved support for localization in the final version? Like fully supporting the implementation of different languages, both in the URL as in the content?

    You should be able to localize content inside Razor templates today. Is there an issue you are running into?

    Thanks,

    Scott

  • @Manning,

    >>>>>>> Will ability to update multiple divs in different regions of a page in one Ajax call be available in mvc3 final?

    I believe the team is looking at that feature now.

    Thanks,

    Scott

  • @Jim,

    >>>>>>>> What is the difference between using the "@model StrongModelType" syntax you explain in this post and the "@model dynamic" syntax as a way to strongly type the data in the view?

    "@model dynamic" indicates that the "Model" property of the view should be of type "dynamic" - which is a new .NET 4 feature. This enables late-bound access to whatever model object is passed to the view template.

    Hope this helps,

    Scott

  • @Kareem,

    >>>>>>>> With this go live license, does that mean I'm fairly safe to upgrade my MVC 2 project that'll be going live in a couple of months? With asking for a hard ETA, is RTM in our near future?

    You should find upgrading straight-forward. We aren't at final RTM quality yet - so there are some caveats - but we think the feature-set is now stable enough to build apps with. We are hoping to ship the final release in the next few months.

    Hope this helps,

    Scott

  • @Jason,

    >>>>>>> I noticed "" Does this mean all Razor views inherit from Page and can not inherit from Control?

    That class is actually a different class than the WebForms Page base class. With Razor all templates can derive from a common base class (there is no distinction between pages, controls and master pages).

    Hope this helps,

    Scott

  • Scott. are we sure that we can have intellisense in future for all view-engine who can be hosted in codeplex website or only for razor , spark.

  • When I use this:
    @if(ViewData["Title"]!=null) {
    You are here at @DateTime.Now
    } else {
    Are you here?

    }
    it causes an error!:
    Compiler Error Message: CS1002: ; expected
    Line 13: You are here at @DateTime.Now}

    But if I put it between tags for example:
    You are here at @DateTime.Now

    It works fine.
    Is it an issue or please explain me why it happen?!

  • @Salman Arab Ameri

    This is the correct behavior of the Razor View Engine.
    You began a code block by using @if(...){, if you don't put something that resembles XHTML the Razor engine thinks that you are still writing C# code.
    Since "You are here at" is not valid code, it throws a compile error.

    If you don't want to use , you can use the tag . This tag serves only to tell the Razor engine that you are writing XHTML and not code (i.e., it won't send the tag to the browser).

  • i see that i not use asp.net server tags from a long time and see everytime when i write html in my views. are i can remove them. if yes then tell me trick and about how i can do this.

  • Looks good. Good work)

  • Have we got rid of ViewModel in BETA3 to just have a common dynamic ViewData, or does ViewModel still exist?

  • Looks nice. Good post.

  • i see that i not use asp.net server tags from a long time and see everytime when i write html in my views. are i can remove them. if yes then tell me trick and about how i can do this.

  • Scott,

    can we get this directive in the WebForms view engine as well? Through the web.config we can already make the views inherit from System.Web.Mvc.ViewPage. The parser could be smart enough to make this generic when using something like:

    <%@ Model="IList" %>

    Looks cleaner than:

    <%@ Page Inherits="System.Web.Mvc.ViewPage<IList>" %>

    What do you think?

  • Hi, just downloaded and installed the MVC 3 Beta and it's looking pretty darn good, I must admit.
    However, support for localization is not ideal. For example:
    - it would be great if I could just provide the resource to use as string value in the code like this: (This would also require the Resource files to be public in stead of internal, which at current can't be set when creating resource files outside the project properties)
    [Required(ErrorMessage=Resources.Global.ERR_NameIsRequired)]
    [StringLength(ErrorMessage=Resources.Global.ERR_NameMaxLength)]
    [Display(Name=Resources.Global.Name)]
    pubblic string Name { get; set; }

  • the Razor has a bug. the @modle can only work on view file under the folder of "Views"

  • +1 on Localization

Comments have been disabled for this content.