Sunday, July 17, 2011

Asp.Net MVC vs Asp.Net Web Forms

We were working on this project which was build using C#, .Net 4.0 and Asp.NET Web Forms.

I come from a Java background where MVC pattern has been around since ever.  There are tons of Java based web frameworks out there that implement the MVC pattern.  It looked quite surprising to me that, till very recently there was no equivalent of MVC pattern in the .Net world.  But, recently the things have changed, Microsoft has come up with its own implementation of the MVC pattern called Asp.NET MVC3.

I certainly like the MVC approach over the Web Forms approach for multiple reasons, I had to present these reasons to the client and convince them to move to Asp.Net MVC3 instead of the current Asp.Net Web Forms approach.  Finally, after quite some talking and presenting and discussions we managed to convenience the client to adaopt the Asp.Net MVC 3 approach over the Web Forms approach.

This blog post highlights the points why I think, MVC makes a better choice as the presentation framework over Web Forms.

Separation of Concerns (SoC) And Single Responsibility Principle

If you ask me, what are the two most important principles which helps in keeping the code clean, modular, readable and maintainable?

My Answer would be, Separation of Concerns (SoC) and Single Responsibility Principle. 

Its extremely important that every class in the system has a well defined job for itself.  No class should try and do too many things, in fact it should do only *one* thing and do it well (Single Responsibility Principle).  If one class tries to do too many things, then the code of the class would be messy, difficult to understand and maintain.

The code behind classes of the Web Forms approach are victim of this problem.  Lot of times, I have seen the code behind classes are bloated and are longer than 2000 lines.  Such classes are difficult to maintain and understand.  The code looks convoluted.

Why does this happen?  

Because, code behind classes have lots of responsibility.  They deal with
  • Showing the view
  • Dynamically rendering JavaScript
  • Updating the model
  • Validating the values entered by the user
  • Implementing some business logic
  • Making a call to the service
  • Differentiate the Post and Get requests etc.  
End result is a truly complex and gumped up code behind.
MVC on the other hand, implements these principle very well.
  • Controller classes are only responsible to update the model, decided which view to render and that's about it.
  • Views only responsibility is to use the model to render itself.  
  • Model just holds the business realted information.  
End result of all this is clean, modular, readable and maintainable code.

MVC gives full control over the rendered HTML

In the Web Forms approach, we were using third part controls called Telerik controlsAt times its really difficult to control the HTML that gets rendered from these controls.  Many times the HTML that is rendered is more complex than what would be required.  Because of this, designers find it difficult to style it the way they want it.

With MVC, you get full control of the exact HTML that gets rendered.  This is an absolute boon for the designers and developers

Unit Testing

I don't want to talk about how difficult it is to unit-test web forms code behind classes.  The web form code behind classes are tightly coupled with things like Session, ViewState Request, Response etc.  This makes them extremely bad candidates for unit testing.  To unit test web forms code behind classes one needs a very strong will and extremely good mocking and Unit testing skills.

On the other hand, MVC has been build with Unit Testing in mind.  One can easily do Test Driven Development with MVC controllers.  Controllers are not coupled with Session or Request or Response object which makes them easily unit testable.

Search Engine Optimizations and RESTful URL's

Web Forms application URL's end with .aspx extension.  They represent a physical file in the file system.  The MVC URL's do not have any extensions.  They do not logically map to a file on the file system.  Instead they map to a controller and an action method inside the controller.  The URL of MVC application look like
  • http://localhost:8080/appname/customer/create
  • http://localhost:8080/appname/customer/1
  • http://localhost:8080/appname/customer/list
  • http://localhost:8080/appname/customer/edit
Integration with Third Party JavaScript libraries

Its difficult to integrate the web forms application seamlessly with a JavaScript library.  For e.g. If you wanted to do Ajax with jQuery in a web forms application, imagine how much code you will have to write.  How will you render the dynamic HTML in this case.  How will you preserve the view state?  Its all very messy.

With MVC, we do not have a problem like this ever.  By default, MVC application comes integrated with jQuery.  However, you could go ahead and integrate any other JavaScript library of your choice.  Since view is not tightly coupled with controller integrating any JavaScript library is extremely easy.

No IsPostBack

I think there is no Asp.Net application in the world that does not have code which looks like

One class/method to handle both the get and post requests. At every step we have to decide whether its a get request or a post request and change the business processing.

This is infrastructure code. We should not be bothering about checking whether the request is a get request or a post request. Framework should do this for me.

With MVC, we do not have to keep checking whether its a get request or a post request.  We can simply put an attribute to a method marking it only accessible via the GET request or only accessible via the POST requests.  With MVC the above code would look like

Notice that we simply have to mark which methods are invokable over which protocol using either the HttpGet or HttpPost attributes. End result, simplified and easy to understand code.

No View State 

Web Forms provides a wrapper over the stateless HTTP protocol to make it state-full.  It achieves this by adding a hidden field called __VIEWSTATE__ to the rendered page.  If not handled correctly and especially when you are using some third party control library like Telerik controls ViewState can easily get out of hands.  I have see pages that have ViewState that goes in MB's.  This ViewState will be sent/received to/from the server for every Post requests.  Its sent/received to/from the server even when you do a Ajax request.  The performance of such pages goes for a toss!

MVC has no concept of ViewState.  MVC does not add a wrapper over the stateless HTTP Protocol.  In fact it harnesses the HTTP protocol.  Hence, MVC pages are much faster and they can easily out perform the Web Forms counter parts on any day. 


These are some of the points why I think, MVC is definitely a better choice over Web Forms for building Customer Facing, fast Web 2.0 applications.  

This list is by not means an extensive comparision of Web Forms vs the MVC appraoches.  Just some little peaces which I though were really important.

We have made our choice to move to MVC, have you?

24 comments:

  1. Good post! ASP.NET MVC does offer its set of advantages over ASP.NET WebForms.

    I know you don't like Telerik's WebForms offering but you should check out our MVC extensions (http://demos.telerik.com/aspnet-mvc/). Would be interesting to get your take on those as they were done from the ground up and in the "pure" ASP.NET MVC way. Hopefully they are a better fit for your projects and maybe you'll like them more:)

    ReplyDelete
  2. Giedrius MereckisJuly 22, 2011 at 12:41 AM

    Doesn't sound like you have done a lot of web forms programming. IsPostBack has nothing to do with Get or Post requests, it refers whether the page is entered first time or not (PostBack). I still prefer WebForms for web applications due to the object-oriented feel, component based approach(if done right). MVC feels like functional programming to me and I prefer it for content websites with.

    ReplyDelete
  3. Hello Vassil Terziev,

    Thanks, Personally, I have nothing against Telerik controls. Whatever I have posted are my real experiences.

    I am a big fan of Open source software. MVC comes integrated with jQuery, there are thousands of open source plugins for jQuery which do almost anything that you can think of. I have not tried Telerik's offering for ASP.NET MVC because till now I didn't see a need to use any paid MVC components. However that's just me.

    Giedrius Mereckis,

    You are right, I have not done much Web Forms development. However, I feel I understand Web Forms approach just fine.

    Let me explain it again, As you said IsPostBack tells us whether page is entered/rendered first time or not. When the Page is rendered first time a "GET" request is sent to the server. In this request IsPostBack will be set to false.

    When a post back event occurs for e.g. lets say user fills the form and clicks the submit button, information is submitted to the same page using the the HTTP POST method. In this request IsPostBack will be set to true. Do you still feel IsPostBack has nothing to do with GET or POST request?

    I can understanding, for long time Asp.NET web forms developers moving to Asp.NET MVC3 might be a bit overwhelming, but trust me, if you want to develop fast Web 2.0 applications, MVC is going to be the way forward.

    Thanks

    Deep Shah

    ReplyDelete
  4. "Do you still feel IsPostBack has nothing to do with GET or POST request?"

    Yes - because GET or POST can happen on the first attempt to retrieve info from a page (POST via cross page postbacks). I'll let MS explain:

    During a cross-page postback, the contents of the source page's controls are posted to the target page, and the browser executes an HTTP POST operation (not a GET operation). However, in the target page, the IsPostBack property is false immediately after a cross-page post. Although the behavior is that of a POST, the cross-posting is not a postback to the target page. Therefore, IsPostBack is set to false and the target page can go through its first-time code.

    ReplyDelete
  5. Agreed.

    However in 99% of the cases GET is used to load the Page for the first time. And when one fills the form and submits the information it submitted over the POST to the same page. Hence, although for the sake of arguing, one could think that IsPostBack is nothing to do with GET or POST requests, the truth is IsPostBack is mostly used to differentiate between the GET and POST requests.

    Over and above it the point here is that the code that gets executed when IsPostBack=true is almost always completely different from what gets executed in IsPostBack=false condition.

    For e.g. lets say we have to render a form where Address needs to be entered by an user. When the page gets rendered for the first time i.e. IsPostBack=false/GET request we get all sorts of reference data i.e. load the list of countries (from the DB) in the drop down and stuff like that. When information is filled and posted back i.e. IsPostBack=true/POST request, we usually write code to save the address information and not bother about filling the country dropdown.

    With MVC we can clearly specify what should happen when a GET request is executing and what should happen when POST request is executing. We do not have to keep checking whether its IsPostBack=true or IsPostBack=false. This for me reduces some boiler plate code.

    ReplyDelete
  6. I can't say I agree on your points, and here is why:
    1) You say seperation of concern: Webforms have exactly that, but you as a developer have to do it. Webforms does not force you to do anything like MVC does because Webforms is not a pattern. Webforms gives you the developer the freedom to use whatever you want. There are no limitations in webforms for coding SOC.
    Consider Webforms as your View and Model, leave all business and connection layer to something else.
    2) Total control of HTML: If you dont know how to control your HTML in Webforms, then you are not very bright developer. You can use pure Xhtml and never use any asp net controls. In ASP .NET 4, you can even determine how the ID tag is formed.
    3) Unit test, you got me there, webforms are difficult to unit test but not impossible.
    4) SEO, webforms can use the same routing as MVC and give the same SEO, so this point is bull...
    5) Integration with third party javascript, Im not even gonna answere this silly one..
    6) No postback, well true in some ways. MVC does perform client callback, which is AJAX which is some sort of postback, just with GET rather than POST.
    7) No Viewstate...Hahahahah, you can easily turn off Viewstate and every good programmers should do this on default in webforms..

    After reviewing this artivle you seem not very experienced in Webforms, and your points are not all that thoughtful, but thanks for the input :)

    ReplyDelete
  7. Hello Deleo,

    Here are my responses:

    1) WebForms code behind class is a mess. People write all sort of code in the code behind class. The fact that WebForms does not force you to have any separation of concern itself leads to poor design in most cases.

    2) Lot of times, people use third party controls like Telerik and Infragistics. With these controls you can't always have full control over the HTML generated.

    3) If a framework is difficult to unit test what does it highlight? It highlights that, its poorly designed.

    4) I would agree with you here.

    5) Tell me something, with webforms, if you had a state dropdown (dropdown control) needs to be updated when a country is selected and we wanted to do this using JQuery only, how much could would you have to write. Hod difficult/easy would it be?

    6) Posting back to the same page and then writing code to identify whether its a postback or not, is boiler plate code. This is, another example of not having separation of concerns. Checking "IsPostBack" is framework code, why should my code behind worry about whether its postback or not?

    MVC can do AJAX using a GET or POST does not have to be a GET request. I can totally control which Action to call in the GET/POST request. I don't have to keep checking whether its a GET/POST request and perform an action based on that decision. In fact, I can also control that certain actions are only available over POST request and certain actions are only available over GET request. This is done by simply adding an attribute over the action names.

    7) Why would a framework enable something by default (ViewState) that is actually bad and then someone has to turn it off explicitly? Question is why have it in first place. MVC has no view state at all and developers are spared from turning it on or off!

    I might be a "not very experienced webforms developer" but to me, you look like a very well versed webforms developer, who wants to overlook the benefits of MVC and does not want to move on.

    ReplyDelete
  8. First I like to thank you for your response, I do love a good conversation :)

    A webform does not force a developer to use a specific pattern, which can be a downside if the developer or team is inexperienced or plain stupid. Given these two terms, you can really frackup the mvc pattern as well. Although it does give the developer something to think about and many errors in design can/vcould be avoided.

    2) Yes, some use third party frameworks such as Telerik and you have no exact control of the HTML, this is true in Webform as well as MVC.
    5) You create it as same as you would with MVC. Perform a AJAX to server. You have to define static methods in codebehind which will catch the call though, and parse it to JSON.
    6)You are answering your own question. You should never put code in codebehind that is reliant on postback. Write your codebehind with the mindset that postback does not exist. Bind everything onLoad method and use HttpRuntime.Cache as often as you can. You can also limit this GET/POST in webforms, you just dont know how.
    7)Really? you cant understand why viewstate was invented in the first place? Webforms have existed for a very long time, where there were needs to preserve state. Later Microsoft invented control state, which is used instead of viewstate to hold critical state of a control. Microsoft have turned viewstate on as default because of compatibility. Any skilled web developer turns this off. Have you ever seen the attribute AutoeventWireup= true? Have you ever changed this to false? Well, you should ALWAYS turn this off unless you need compatibility to old ASP code. This as with viewstate is turned on by default by Microsoft.

    I am an old webform developer that have not yet seen the great benefits of MVC, that is true. I don't write an article saying which is better, because I dont know MVC that much. Same should you. Do not put webforms down when you clearly lack the knowledge of webforms. I understand enough of MVC and its difference to Webforms to state that neither is one's successor. You use webforms and MVC for the same thing, although in some scenarios you should choose MVC over webforms.They both have their strength and weakness.
    Please dont take this as trolling, if you do, please excuse my writing. I meant this as purely feedback, constructive. In your future technology articles you might want some experience to backup your theories :)

    ReplyDelete
  9. Hello Deleo,

    Me too enjoys constructive conversation and I can tell you one thing I am enjoying this one!

    I think we have to agree to disagree with each other.

    It seems like you agree with me on the design front, and on point number 2.

    About 5, putting static methods? Well I don't know about other but I surely don't like putting static methods anywhere. Static methods are signs of poor design.

    Point 6 and 7, You need to understand that one does not develop all projects from scratch. We have to inherit some projects and in such projects, people have not followed the best practices because of which you have to deal with a hell lot of crap code and bad design.

    I would agree that this can happen with MVC as well but since it forces the developers to follow good design practices the changes of bad MVC code are very little.

    Whatever I have mentioned in the post are real problems with Web Forms and I can certainly tell you that 80% (if not more) of the projects out there suffer from these problems.

    ReplyDelete
  10. Hello Deleo,

    One of the readers on a different post wrote this and I guess, it applies to this conversation as well:

    "I think it's hard to understand what Deep is talking about without having made transition from ASP.NET with all its complexities to another platform (MVC3, Rails, Grails, you name it). The thing is, Telerik is following ASP.NET best practice which is about putting an elephant in a China shop. I was working quite extensively in ASP.NET and now I moved to MVC3/JQuery/JSON and guess what - things just work. You don't have to keep in mind that a control put extra code and alter ids and name on the client side. The programming model is so much better it makes me wonder what kept so long in ASP.NET world"

    ReplyDelete
  11. ViewState is a very useful component if used properly. It can be manipulated in many ways to adjust to small applications to large web forms. To say that ASP.NET MVC is faster than Web Forms is down-right wrong. ASP.NET Web Forms out-weigh MVC performance-wise.

    With ASP.NET 4.0, you have URL routing for RESTless and SEO friendly URLs. It's very simple to take advantage of this feature in your Global.asax.

    If you're a powerful developer / architect, you will realize that a well-versed web forms developer will outperform (development-time-wise and performance-wise) a skillful MVC developer. Done it for over 8 years and am pretty familiar with MVC... too much control taken away from you. I tell my program what to do, I don't let it tell me how to build my architecture.

    ReplyDelete
  12. How is writing if(IsPostback)....else.... any more complicated than writing [HttpPost] and [HttpGet] as attributes of the MVC methods? You are still doing the same thing. You call one method on post, and another on get. Are the parenthesis in the if/then really that much of a problem?

    Regarding url routing, outside of SEO (a programmers worst nighmare thanks to retarded search engines), what benefit does passing "directory" parameters to a controller have over passing querystring parameters to a page? In both cases, you're instructing some page/method/function/etc to handle the request. You could argue it would help in switching platforms or something (honestly, if you switch platforms, is that your biggest concern?) but in both cases, you are requesting a very specific resource.

    Finally, regarding viewstate, turn it on when you want an easy way to handle page/control state and turn it off when you need the extra performance boost and want to code around the cases where data needs to be repopulated.

    -Justin

    ReplyDelete
  13. Hi, I notice how many people have ALWAYS used webforms wrongly and how the call MVC a technology. MVC exists even before many of us were born. I have developed MVC applications well before asp.net MVC came live, so to me it is not new and indeed, although they have done a good job, it still lacks power. HTML can be controlled only when there is a clean separation of concerns, something that many asp.net webform developers DO NOT KNOW how to do because they just keep on using what microsoft told them to use, a code-behind model which is not very good either. You can totally remove the code behind from a webform and create your own controllers and routing. Extension-less URLs can be achieved by using libraries such as intelligentia. Then, you have a total separation of concerns and you have an MVC (Model View Controller) application without loosing the features that most developers are used to use, such as Custom user contorls, etc. my point is... if you really are a developer, you will have done MVC apps even before asp.net MVC.

    ReplyDelete
  14. I'm relatively new to MVC but I've used Webforms since .NET 1.0. There are parts I like and I can see how it can help a novice developer but I don't like how inflexible the pattern is and I'm concerned that it will limit the expandability and flexibility of the application. Generally speaking, I like to create separate business libraries and data layers in n-tier fashion - my code behind pages are very lean and clean and I use controls to separate code if I need to for SOC and SRP.

    My questions about MVC are the following:

    1. Could I create business and data libraries with MVC or is everything forced to reside in the model layer?

    2. Can I create custom web controls or ascx controls with MVC and reuse them across web pages?

    3. Where do I add custom code for presentation? I don't want to add functions in a view as that would remind me of ASP with hmtl and code interspersed.

    4. It sounds like you can't use datagrids with MVC. I really don't want to build my own sortable datagrid:-)

    5. What do other developers use in MVC to mimic viewstate? I suppose I could use an asp.net hidden control and parse the values myself but that's what viewstate does, right?

    ReplyDelete
  15. Im an ASP MVC and Spring MVC developer. Its cool, nice architecture MVC but I will summarize as this:

    If is a Website without much cluttered GUI, simple forms, list, etc the way of HTML and few jquery plugins so use MVC.

    If is a Web Application, with cluttered or complex GUI, you need custom components(forget here jquery plugins, some are good but some are useless) and state, Webforms is the way to go.

    ReplyDelete
  16. Hello There,

    You can totally Create separate business and data libraries MVC does not stop you from doing it.

    Custom reusable sections of page in MVC are called partials. You can create them very easily and use them across your application.

    There are many options, one of them is, create HtmlHelpers to do it

    We have build an application with MVC which has a datagrid on almost every page. We use jqGrid for showing the grid. We integrate it with MVC using jquery and JSON.

    You can serialize the model on the page in the worst cast if you really want to a functionality like view state. Else you can use hidden fields for store singular values like identifiers.

    Thanks

    Deep Shah

    ReplyDelete
  17. I think that web forms has played its role in making coding in the world of http an easy task, but only in enterprise level. Technically speaking, it promoted an environment and methodology a bit strange for that world, the single form model and page lifecycle. Web applications serve content that is requested using an endpoint and that content consists from smaller pieces that do something, menus, banners, forms, articles, datalists etc. Technically the source for each is different and the user will interact with only one each time, so it should really be separated from other modules. Web forms break that by serving them as one, even if using usercontrols...they are served as one...they postback as one, in the same page, that is a file, even for redirection the 'page' must be recreated etc. Viewstate, page lifecycle, unique control iding system, state restoration was invented to cover only the methodology of web forms, its not an http matter. It was something done for the first time but i feel a bit misslead from web programming. I was stuck in the server implementation and gave less to serving web content. Web dev is simpler when scripted directly. That is me though. Keep walking.

    ReplyDelete
  18. I think that web forms has played its role in making coding in the world of http an easy task, but only in enterprise level. Technically speaking, it promoted an environment and methodology a bit strange for that world, the single form model and page lifecycle. Web applications serve content that is requested using an endpoint and that content consists from smaller pieces that do something, menus, banners, forms, articles, datalists etc. Technically the source for each is different and the user will interact with only one each time, so it should really be separated from other modules. Web forms break that by serving them as one, even if using usercontrols...they are served as one...they postback as one, in the same page, that is a file, even for redirection the 'page' must be recreated etc. Viewstate, page lifecycle, unique control iding system, state restoration was invented to cover only the methodology of web forms, its not an http matter. It was something done for the first time but i feel a bit misslead from web programming. I was stuck in the server implementation and gave less to serving web content. Web dev is simpler when scripted directly. That is me though. Keep walking.

    ReplyDelete
  19. i really found this post helpful...thnk you

    ReplyDelete
  20. I ve recently had a scenario where dynamic forms had to present complex ui to the user that could submit raw or listed items back as unit. I ve tried mvc at first but state managment and post value retriaval using custom model binders was overkill and had to move a big portion on webforms. With little work creating usercontrols and some viewmodels over modelling, the team started building the ui after 8 hours of initial preparation. Mvc has its place but webforms is more modular when it is needed.

    ReplyDelete
    Replies
    1. You can use an asp.net form in an mvc project. I have implemented few asp.net forms and silverlight in my mvc app. I have used them only on advance screens which are not used on daily basis.

      Delete
  21. I have worked on asp.net forms for many years, ironically on just two products and about 10 years :). I dont find anything that I cant do with asp.net that I can in MVC. However, I find mvc better and easier for both programming and maintenance.
    Also, I feel that world if moving away from server side processing of User interface. Our latest adventure is building liquid layout UX connecting it to data services on server. Except very few screens all are pure html (not even MVC @html) and hosing them all over CDN and using web and db servers just to process data has made it perform so fast. We multi-tenancy saas app. Performance and ui is everything for us.

    ReplyDelete
  22. It's good you show the difference between Asp.Net MVC vs Asp.Net Web Forms.We came to know lots of thing from your sites which we are looking for.

    ReplyDelete
  23. Finally, reading again your article convinced us to rebuild the old&rusty backend we have to start with it as first MVC project;
    if we will rebuild the core app, time will show.
    Regards

    ReplyDelete

Have some Fun!