Released: Silverlight 3 Beta 1, ASP.NET MVC 1.0

Just two little quick announcements: Silverlight 3 Beta 1 and ASP.NET MVC 1.0 have been released. Here are the links:

On ASP.NET MVC

In this article, I want to give you some information about my experiences with the Beta-version of ASP.NET MVC. During December, I had the chance to build up an application for the administration of media elements with ASP.NET MVC and thus I got a good insight in various topics.

What is ASP.NET MVC?

ASP.NET MVC is Microsoft’s interpretation of the well-known MVC architectural pattern, bringing MVC to the ASP.NET world. It is MVC for the presentation layer, not for the whole application (that should be true for most applications). Furthermore, it is not a top part of classic ASP.NET, but it’s a completely new approach for designing/creating web applications. This implies many changes and makes ASP.NET MVC very different from classic ASP.NET in many ways.

Comparison to ASP.NET „classic“

The MVC pattern follows a strict separation of concerns principle. The Model should include the business logic and is being invoked through the Controller, which is responsible for retrieving data, choosing and calling Views with that data and handling user requests. Views include only view logic and are creating/formatting the output for a user.

ASP.NET MVC tries to overcome the disadvantages of web-forms based programming by ASP.NET. Those come mainly through the purpose of ASP.NET to make web application development feel similar to win-forms based development and thus to make the access for Windows application developers more fluent. That’s a good intent, but it brings many problems to life, because we are not in a stateful Windows application, but in a stateless web environment. While classic ASP.NET developers try hard to get a good separation of concerns to work, logic is often put too much in code behind. Furthermore, ASP.NET tries to emulate stateful behavior through saving a client-based ViewState as hidden field, which can become really big and can waste page sizes. Other problems include difficult Ajax handling, missing full control over page rendering (especially when you use web-forms) and a complex page lifecycle, which is difficult to understand and to use sometimes.

I’m thinking of ASP.NET MVC as kind of „back to the roots“. For many things you have to do more handwork, where ASP.NET gives you more comfort respectively didn’t require deep knowledge of web technologies and protocols. The intent is to give you full control of the HTML markup, but it implies that you create this markup at your own. Basically, you don’t have most of the well-known ASP.NET controls. Repeater control in ASP.NET? It’s named „foreach loop“ in ASP.NET MVC 😉 . GridView in ASP.NET? Use a foreach and a HTML table in ASP.NET MVC. That sounds cruel for most developers I spoke with about this topic. In fact it’s not the whole truth. There are some so-called „helper objects“ exposed in the views, which encapsulate basic (e.g. HTML) functionality and can be used instead of the real markup. Everyone can build up his own helper methods by using standard C# extension methods and thus extend their functionality for his own needs. Currently the helper methods cover mainly basic HTML functionality like list boxes, check boxes, buttons, forms etc.. Advanced controls are missing (yet), but it’s only a matter of time when others will provide them. The community project MvcContrib has done first steps in this direction and provides a Grid control, for instance. It’s not perfect, but it’s pretty nice code and shows up how controls can look in ASP.NET MVC. The fact why you can’t use most of the classic ASP.NET controls is that you don’t have ViewState and postbacks anymore. This implies that you can’t use any controls that rely on those principles. It forbids to use event based programming as well. Thus if you want to post form values back to the server, you have to create an HTML form and a controller action which can handle the POST verb. Thankfully there is a nice data binding concept, that gives you some support on dealing with this. If you want some kind of dynamic loading as can be done by event-based programming, use Ajax for that. ASP.NET MVC is introducing many new concepts as well: URL routing, TempData/ViewData, Helper objects, data binding, validation, … these are only some topics which you have to understand, if you are starting with ASP.NET MVC.

Beside those heavy changes and differences there are similarities to ASP.NET, too. Thus you are able to use the standard ASPX markup, which is available as standard view engine in ASP.NET MVC. Anyway, you can use most core ASP.NET features like authentication, role handling, Session, Caching etc..

In the whole, ASP.NET MVC gives you a much lower level of abstraction from basic HTML, which some will like and others not. Scott Hanselman got to the heart of that when he stated:

This is a not just a different tune, but a whole different band playing all new music. Not everyone will like the music, and that’s why the world has more than one band. This is a Good Thing.

I like to think of ASP.NET MVC as the raw, acoustic version of the more heavily produced and multi-layered ASP.NET WebForms we use today.

And to avoid misunderstandings: ASP.NET MVC isn’t there to replace standard ASP.NET. Instead it makes an alternative programming model and both technologies will be developed further by Microsoft in the future.

What music do you like?

To choose either ASP.NET or ASP.NET MVC depends on what you want to do. Nick Berardi developed a nice decision table which guides you on your choice.

Following that and my own experiences you should use ASP.NET MVC, if you want:

  • test-driven development, including your UI,
  • separation of concerns through the MVC principle with all goods, that are implied through this (logic at places where it should be, nicer architecture etc.),
  • improved team development, where different team members are responsible for different parts of the UI (Models, Views and Controllers),
  • RESTful URLs,
  • multiplicity of Views (e.g. for different output devices like PC, mobile, printer, …),
  • full control over your markup, clean and tiny HTML pages.

ASP.NET should be used in case you want to:

  • be productive in a short time (RAD/prototyping),
  • develop data centric applications (ASP.NET MVC is not the best for that due to the missing data-centric controls (at the moment) and missing data source controls),
  • make use of complex web forms (includes existing 3rd party controls),
  • use the event model,
  • get a fast entrance to web application development.

My opinion

Personally I like the development in ASP.NET MVC. It gives me more freedom than classic ASP.NET and I feel more home in there. ASP.NET MVC is in my opinion a step in the right direction. The loosely coupled components give you the flexibility to exchange or extend parts of the framework as well as to fake things out and test parts of your code separately. A main point that Microsoft has done right is to include the community in the development process and to consider their needs. The open source community project MVCContrib shows this direction of actively including the community. Furthermore, ASP.NET MVC comes with jQuery, built-in jQuery support and jQuery intellisense. Microsoft promises to support jQuery and to contribute improvements back into the jQuery development in the future. That’s a huge turnaround for Microsoft, which was fighting Open Source heavily not long ago. I think, other development teams at Microsoft should follow this example. For instance, the ADO.NET team has created so much distrust while developing the Entity Framework at its current state and it’s not much caring about community needs. Guys, time to re-think!

On the other hand, there are many things for you to dislike ASP.NET MVC. Through the lower level of abstraction and the missing ASP.NET controls you could miss some kind of comfort while creating your web applications. Furthermore, there is no direct „upgrade path“ for learning ASP.NET MVC if you have developed ASP.NET so far. For beginners in web-based application development, there is a very steep learning curve, because you have to be aware of the stateless programming model and basic technologies like HTML, CSS, HTTP and so on.

One thing to mention is that ASP.NET MVC is still in development. At this time, the RC has been released and V1 will follow in February 2009. For me and many others, ASP.NET MVC V1 is not a complete framework out-of-the-box, it’s more a basic framing which doesn’t limit developers in most things. It gives them the freedom and possibilities to realize their own opinions and principles. Phil Haack got the point:

In part, you can look at v1 of ASP.NET MVC as a Framework for building ASP.NET MVC Frameworks.

That’s a thing which I can truly sign. And it’s leading the future development. In my opinion there will come developers and build up their own frameworks on top of ASP.NET MVC, making them more narrow and including their own principles. And ASP.NET MVC allows them to do this. Moreover, that is why the ASP.NET MVC developers didn’t make their framework very opinionated. At every point there are many degrees of freedom and some people are frustrated about that, because it allows everyone to create bad code. But it’s a good thing, if others come and make their frameworks on top of ASP.NET MVC really opinionated. It’s easing the way for those people and thus I’m applauding the ASP.NET MVC team. I’m really happy to see this bare framework to come out and I’m interested to see what will have been developed in spproximately one year. For now, I’m really confident of that.

kick it on DotNetKicks.com

ASP.NET MVC RC1 released

Just a short announcement: as ScottGu stated in December last year, the Release Candidate of ASP.NET MVC has been released now and can be downloaded from here.

In the RC, the major bugs have been fixed and many little improvements have found their way to the package. All changes can be viewed in the release notes.

V1 of ASP.NET MVC is planned for February 2009, so stay tuned.

Links:

ASP.NET MVC Tip: Got an Ajax Request?

Job-related I’m diving into this ASP.NET MVC stuff currently and will give you at this point some posts on that in the nearer future. Just for now: I like ASP.NET MVC and how MS implemented the core concepts. It’s clean, testable, flexible and extensible. Many things have changed since beyond standard ASP.NET…

Currently I’m becoming inspired by the Ajax Helpers, which ship with ASP.NET MVC. With Ajax.BeginForm(), Ajax.ActionLink() and Ajax.RouteLink() there currently (ASP.NET MVC Beta 1) exist three extension methods, which one can use after integrating the Microsoft Ajax script libraries in his page and which provide basic Ajax functionality.

At the moment I’m using Ajax.ActionLink() in my project to reload parts of my page, if the user clicks on a link. Especially I’m reloading data asynchronously, which the user changed through his click. That’s working pretty perfect for me, additionally I can serve a Confirm-Message via the AjaxOption „Confirm„, which is presented to the user before executing an action and over which the user can canel an action, too.

There’s one problem for me in this case: with the ActionLink ASP.NET MVC calls an Controller-Action. That’s happening via a special URL, which is mapped by the ASP.NET MVC routing system to an action. This action delivers with PartialView() the data (View), which are injected in the existing page with the aid of Ajax. The problem is: the user can pass this URL directly in his browser too and then he gets only those partial data in response, but not the whole page as in the case when he’s using the Ajax-ActionLink.

Some googling and testing yielded two ways for resolving this problem:

1st) One action with discrimination of the request type

First of all it’s possible to create an action, which can be invoked through both the Ajax ActionLink and the user through an URL in his browser. After including the namespace „System.Web.Mvc.Ajax“ one can use the extension method „Request.IsMvcAjaxRequest()“ in his controller action, with which it’s possible to check if the current request is coming from an ASP.NET MVC Ajax helper. Accordingly you are able to return the PartialView (on an Ajax request) or the complete view of your data (in case there’s no Ajax request). This is looking roughly as follows:

using System.Web.Mvc;
using System.Web.Mvc.Ajax;
...

namespace MyNamespace
{
    public class MyController : Controller 
    {
        ...
        public ActionResult MyAction(...) 
        {
            if(Request.IsMvcAjaxRequest()) 
            {
                ...
                return PartialView("MyPartialView", myPartialModel);
            } 
            else 
            {
                ...
                return View("MyCompleteView", myCompleteModel);
            }
        }
    }
}

Is this solution pretty? Well… Kevin Hoffman is criticizing the additional discrimination of the request type in the controller. Especially it’s coming out that Kevin sees the MVC principle violated, because this discrimination is going beyond the responsibility of a contoller (the following quote refers to an older ASP.NET MVC release, where there was an AjaxController with an IsAjaxRequest property):

MVC is all about proper separation of concerns. There’s one line of code in the sample that I think is violating that, and that’s the IsAjaxRequest property. This all smacks of someone attempting to make the MVC framework feel more like the old Postback world and quite frankly, the old postback world can eat my shorts. The controller, IMHO, is just a controller. It should not ever have to determine if it is rendering Ajax or rendering Regular. Ajax or regular HTML is a view decision not a controller decision. The job of the controller is to fetch the appropriate data required for rendering a view, and then pick the view to render.

Strongly taken I agree with Kevin from the architectural point of view. The view should be responsible to decide how some data is displayed, the controller should only deliver this data. On the other hand side my own individual opinion is that the controller should be able to decide, to which view it’s sending the data it fetches. Many controllers are doing so… e.g. they are calling an error page instead of the actual view if something goes wrong or they are redirecting to other views depending on the count of the received data. The only thing I’m worried about in this case is that the decision „Ajax-call or not“ is design-oriented and does not depend on data, which is fetched in the controller action itself, but which depends on the initial request. Though I’m not worried much about this, I’ve worked out another solution, which I’m coming up with in the following section…

2nd) Two actions with attributation

If you want to avoid a discrimination by „IsMvcAjaxRequest()„, you have to implement a second action. A first action „MyAction“ can then be called by the user via his browser and will return the complete view, where the second action -named e.g. „MyActionAjax„- could return a partial view, which is relevant for the Ajax request. This is looking as follows:

using System.Web.Mvc;
...

namespace MyNamespace 
{
    public class MyController : Controller 
    {
        ...
        public ActionResult MyAction(...) 
        {
            return View("MyCompleteView", myCompleteModel);
        }

        public ActionResult MyActionAjax(...) 
        {
            return PartialView("MyPartialView", myPartialModel);
        }
    }
}

Please identify that the basic problem still persists: the user can call „MyActionAjax“ via his browser. And here comes the trick: we’ll attribute „MyActionAjax()„, thus refusing the access. I’ve written a filter attribute, which is dealing with this:

using System.Web.Mvc;
...

namespace SDX.xMedia.mvc.Presentation.Common
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public sealed class MvcAsyncPostAttribute : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext != null && filterContext.HttpContext != null)
            {
                if (!IsMvcAsyncPost(filterContext.HttpContext.Request))
                    filterContext.Cancel = true;
            }
        }

        private bool IsMvcAsyncPost(HttpRequestBase request)
        {
            if (request == null)
                return false;

            return request["__MVCASYNCPOST"] == "true";
        }
    }
}

In this case I’m walking by foot. The Ajax helpers from ASP.NET MVC are setting the request parameter „__MVCASYNCPOST“ when performing an Ajax request. Further the extension method „Request.IsMvcAjaxRequest()“ is implemented in a way, which is only querying this value. Here is the current implementation from the ASP.NET MVC project:

public static bool IsMvcAjaxRequest(this HttpRequestBase request)
{
    if (request == null)
    {
        throw new ArgumentNullException("request");
    }
    return (request["__MVCASYNCPOST"] == "true");
}

Thus of course I can use this method for my request:

using System.Web.Mvc;
using System.Web.Mvc.Ajax;
...

namespace SDX.xMedia.mvc.Presentation.Common
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public sealed class MvcAsyncPostAttribute : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext != null && filterContext.HttpContext != null && filterContext.HttpContext.Request != null)
            {
                if (!filterContext.HttpContext.Request.IsMvcAjaxRequest())
                    filterContext.Cancel = true;
            }
        }
    }
}

By the way: IAuthorizationFilter has been implemented, because only in this way I was able to cancel the execution of the action in the first place ( filterContext.Cancel = true; ). Now with this attribute it’s possible to mark the „Ajax-only“ action and this way to prohibit the access through the browser:

using System.Web.Mvc;
...

namespace MyNamespace 
{
    public class MyController : Controller
    {
        ...
        public ActionResult MyAction(...)
        {
            return View("MyCompleteView", myCompleteModel);
        }

        [MvcAsyncPost]
        public ActionResult MyActionAjax(...)
        {
            return PartialView("MyPartialView", myPartialModel);
        }
    }
}

Now which way is prettier? Architecturally I like the second variant with regard to the separation of concerns principle which lets the controller do the stuff it should do. But there is one unaesthetic point in my eyes: the Ajax ActionLink is referencing to the action „MyActionAjax()“ and this link is delivered to the user by his browser. The user could be confused when he wants to share this link with one of his friends and has no direct access to the controller action, which stands behind this url. Thus from a user’s point of view the first solution makes more sense, but there has to be a trade-off as the case arises and I’m agog about your thoughts.

Update for the second solution:

My problem with the second solution was the action-link, which is pointing to MyActionAjax() and thus provided to the user. Now I’ve worked out a quick and dirty work-around for that (and guess what: no I don’t like it). I’m setting up my own RouteHandler in the following way:

class AjaxRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        if (requestContext.HttpContext.Request.IsMvcAjaxRequest())
            requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"] + "Ajax";

        return base.GetHttpHandler(requestContext);
    }
}

Now you can set up your routes with this route handler:

RouteTable.Routes.Add(
    new Route("{Controller}/{Action}/{id}",
    new RouteValueDictionary(new { Controller = "MyController", id = (int?)null }),
    new AjaxRouteHandler()));

What’s done: if there is no Ajax request, then the „normal“ action will be invoked (e.g. „MyAction“). On an Ajax-request instead there will be called the action „MyActionAjax“ automatically. Note that the programmer has to be responsible for the availability of this action pair. The benefit of that: you can provide „MyAction“ in your Ajax-ActionLink or call it via your browser and share the url with your friends. The route handler decides whether to invoke MyAction or MyActionAjax. Thus the responsibility for deciding if we’ve got an Ajax request comes out from the controller into the route handler. Please remember that I don’t have anything against having this piece of code in my controller, I’m just here to show some other way for solving this problem…

kick it on DotNetKicks.com