What ASP.NET MVC Could Learn From Rails

Most developers that are interested in bettering themselves really do want to hear both sides of the story. They want to understand the strengths of other platforms, not so they can move, but so that they can understand how to make their own framework/platform better. When you read this post, I hope you will read it with that in mind. I hope you will see this not as me criticizing your platform, or someone else’s work, but instead as me saying “here is what I think is cool about this other platform, how can your platform get in on that?”

A Tale Of Two Frameworks

There was a time when Ruby on Rails was the hottest thing on the block, and many ASP.NET developers pined for the day when we could leave behind controls and viewstate and move into the glorious world of web development. Cause what we were doing wasn’t web development, don’t kid yourself. Then ASP.NET MVC came out, and a lot of people (myself included) jumped on that bandwagon and have never looked back.

I have been very happy with ASP.NET MVC for a long time. It gives me a simple to use framework that gets out of my way and lets me write real web applications. And I love it! But there is just one problem, websites are quite often complex beasts and ASP.NET MVC only solves a small part of the puzzle. Every project I start I have to pull in a membership system, migrations, an ORM, an IOC container, logging, testing framework, etc… I have to find and plugin all of these tools every time I want to do build another site. (Nuget has helped with the finding and integrating part immensely!)

I guess this is to be expected though, ASP.NET MVC wasn’t really meant to be an opinionated framework. They wanted to produce a framework which would have broad appeal across the hundreds of thousands of .NET developers out there. Not an easy task! They also wanted a smaller framework that they could release in short cycles. Based on their goals, I’d say that they have done a great job.

But because of this they couldn’t just pick different frameworks and include them as defaults. First of all, there were few choices that would not have been controversial. Secondly, if they had made controversial decisions, the framework would have been rejected by early adopters and not seen the adoption that it has now.

Creating a generic framework is fine, as long as you understand what you are giving up to get there. The power of frameworks like Ruby on Rails, Django, or CakePHP is that they span the whole stack. While this might lock you down to doing things in a certain way, in the end the benefit derived from the tight integration is very often worth it.

Walking Through The Problem

In order to demonstrate this, let’s take the example of authentication in a web application. In ASP.NET MVC we have the normal ASP.NET authentication mechanism which we can leverage in order to have users and roles, but as most of us know, a lot of people end up rolling their own or looking for an outside solution. Why? Because the user is part of our domain, and the ASP.NET authentication system forces us to use their tables, stored procs, db deployment tools, etc… It is clunky and not extensible at all. So let’s say we want to build an alternative, what would we have to do?

The first we need is a model that represents a user, we can either include this in the framework, or maybe just let the user define the class that they need, and then implement an interface for us to interact with. Okay, so how do we get the tables in the database? Well, we could create some scripts and put them in the project, then the developer can run those to create the user tables. That doesn’t seem very awesome, what if they aren’t running SQL Server? Yes, some of us do use .NET without SQL Server. What if they need to automate creating the database for testing? Also, how much does it suck to have to manually run the scripts on every machine you need to deploy to?

Well, we could write code to connect to the database and run the DDL to create a table. That would be more automatic. But again, what database are they running, which connection do we use, how do we let the user modify their user object to fit their needs if we need to create the table? Arrrrgh! Okay, let’s just punt on that and say that we will just create scripts for a few databases, and let the user modify and then run them manually, or integrate the scripts into their build process. That sucks.

Now how do we get the user model in and out of the database? We don’t really know how the developer is going to be doing data access, so we can’t pull the user from the database within the framework, we will have to force the user to implement a class that we can call and get users, in the same way that the provider model is currently implemented in .NET. This isn’t terrible, just inconvenient.

So now we are at the point where we have a database table, and we can pull users from the database. The only problem is that the developer has had to implement an interface on his user object, manually edit and run scripts, implement a persistence mechanism (most likely an ORM), and implement a provider to allow us to perform CRUD operations on users. And we are just getting started! What about creating a controller, views, adding routes, validation, sending e-mails, etc…? There are a lot of pieces that go into a successful authentication mechanism, this isn’t easy stuff.

In the ASP.NET MVC world, all of these problems may seem overwhelming. Sure, we could implement a full solution, but we’d have to make a lot of assumptions and force the user into tools that they might not be using. Or we include our own tools, and bypass their stack in the same way that the ASP.NET providers work. This disconnect is what frameworks like Sharp Architecture try to solve, but third party libraries could never depend on frameworks like this until their adoption reached a critical mass. Otherwise they would be spending a lot of effort, for every little return.

How Would You Do This In Rails?

In Rails there are a few different frameworks available to do authentication. The one that I have used is Devise. In order to use Devise, the first thing we would do is to add the gem to our Gemfile (a gem is like a NuGet package, if you don’t know what a NuGet package is, go here) with a line like this:

gem 'devise', '~> 1.3.4'

Then we just run “bundle install” and the gem is installed into our project. Now we have to configure devise. We can run this command (you can type out ‘generate’ instead of ‘g’ if you want):

rails g

And it will show you all of the generators available to you. You will see a section for Devise. Devise is able to hook into these generators and do some really powerful stuff. We can see from this list that there is a generator for devise called “devise:install”. We can run that:

rails g devise:install

Now Devise has installed its configuration file into your app, and you are almost ready to go. You’ll notice there is another generator just called “devise”, if we run that it tells us to give it a model name so it can generate a User model for you. Because everything in Rails has a place, you simply run this command:

rails g devise User

And it drops User model into your /app/models folder, generates a migration for you, and puts routes into your routes.rb file. Now all I have to do is run my migrations (I can edit the migration or create another migration to edit my user table, allowing me to completely customize my user):

rake db:migrate

And now my database tables are created and everything is ready to go. I can put this on my controller:

before_filter :authenticate_user!

And now that controller will redirect me to a login/signup page, allow me to create an account, send confirmation e-mails (if I want), etc… I also have a number of helper methods that I can run like “user_signed_in?” or “current_user” in order to interact with users on a more fine grained level.

What Happened There?

Well, you saw the power and productivity of a full stack framework. Devise knows what tools you are using (or how to integrate with them), and where everything goes. Because of this we don’t need to tell it how to create a model, create database tables, save/retrieve users from the database, how to connect to the database, how to send e-mail, etc… These are all configuration and sensible defaults that have already been setup in your application.

And for anything that isn’t automated, there are Rails generators that we can hook into to create config files, add routes, views, and any other assets. We are able to do this because most everything has a place in a Rails app. Rails is a very opinionated framework, and it shows. If you follow the “Rails Way” then things will be smooth and super productive.

How Do We Make ASP.NET MVC Better?

That is a very difficult question. You see, the Rails community long ago agreed to go along with the “Rails Way” in exchange for increased productivity and integration. I’m not sure that the .NET developer community would respond favorably to the kinds of changes which would be required to bring ASP.NET MVC up to the level of integration that Rails enjoys.

This doesn’t mean that they can’t come close though. One thing they could do is start to favor certain tools more in the framework. Start to setup conventions and tools that developers are expected to use, and let them know that if they stray, they are on their own. However, the problems here are obvious. The tools that are going to be made the defaults will be Microsoft’s own tools, like Entity Framework or MEF. This could create some serious friction with the developer community if they start to integrate too tightly with these tools.

An MVC Uber-Framework?

Another interesting path would be to see some full stack frameworks spring up on top of ASP.NET MVC. Maybe Microsoft could implement another framework on top of ASP.NET MVC which would be fully integrated, but could be tossed out if you just wanted just the underlying web framework. As long as this framework was simple and powerful enough, you would probably see a large number of developers jump on board, which would give OSS creators a reason to integrate with it. On the MS platform, a tool like this usually has to come from within Microsoft itself, otherwise it has an extremely hard time gaining any momentum.

I can see a lot of eyes rolling and hands shooting up after that last paragraph, but hear me out. If Microsoft continues down the path they are now, and they start integrating things like Entity Framework and MEF as defaults, but not truly integrated, then all we are going to get is a bunch of code generation when we start a project. This isn’t going to help OSS developers extend the framework. But, if they could instead tease out the web layer from the rest, and build a more integrated application stack on top of it, that would go a lot further. I’d love to hear people’s feedback on this.

Will It Change?

I don’t know! ASP.NET MVC is a fine framework. I just don’t feel like it is as productive as it could be. Good, solid, testable web development just doesn’t have to be as hard as it currently is with ASP.NET MVC. ASP.NET MVC has given us a good start on the web layer, but hooking up our applications to this front end is often repetitive, clumsy, and cumbersome. All I want is for my whole stack to play nicely together, is that really too much to ask?

Be Sociable, Share!

86 comments

  1. @Alex there is absolutely nothing you can do in Rails I can’t do as equally as good or better in C# ASP.NET + MVC3.

  2. @ChrisM : what about deployment?

  3. @Justin A

    My deployment process is

    1. Change build configuration mode to release
    2. click publish
    3. ftp files up

    I specifically make it 3 steps, I could skip the ftp files but I always want manual intervention when it comes to uploading files to my production servers. Soon the binaries will just come straight from the CI server that hasn’t had enough time to be fully configured yet.

  4. Picking on the oldest, most unchanged part of the asp.net framework seems like a cheat Justin. So, you have to build an authentication module you like one time. Big deal.

  5. @ChrisM – what about minification/compression of jss and css? bundling them into a single / a few files?

  6. Justin Etheredge

    @Chris I don’t think I’m really “picking” on any part of ASP.NET. The issue I have spans the ASP.NET MVC stack. I could have just as easily used any framework which needs to integrate with models, validation, persistence, etc…. I’m merely asking, “how would you do this?” And the answer is that you can’t. My argument is about a full stack framework versus a framework that only focuses on the web.

    And again, I’m not saying that ASP.NET MVC is bad, I’m just saying that their focus is different. In my opinion, ASP.NET MVC loses a lot because it lacks an integrated stack.

  7. @Justin Etheredge “I’m merely asking, “how would you do this?” And the answer is that you can’t.”

    What are you asking how would you, and you claim you can’t? I really don’t accept that answer at all.

    With MVC3, Nuget, and MVC Scaffholding you can do just about anything you talked about rails doing here in the blog post.

  8. >The power of frameworks like Ruby on Rails, Django, or CakePHP is that they span the whole stack.

    Just like to add Java EE to this list, which is a very powerful framework that spans the whole stack as well.

  9. It is true, the large number of good gems and easy to use plugins make Ruby on Rails so powerful. There is nearly for every problem a nice gem or plugin in the Rails world: authentication, authorization, pagination, HTML parsing, image processing, file uploading, deployment automation, testing, etc.

  10. Somebody has already mentioned this. What Ruby On Rails has that .NET does not is a vibrant community full of devs willing to put the hours into OSS.

    It is pointless arguing over the nuts and bolts of each language or each framework when this is the differentiating factor.

    There is gem for every situation because passionate developers have created these gems to a high and professional standard.

    There is not as much OSS although there is some great stuff in .NET because the devs are not prepared to put the hours in to do this.

    To me it is that simple.

  11. I think there’s a lot of good influence coming from Rails into MVC; MVC Scaffolding and Nuget packages to name a couple. Let’s hope it continues.

    I feel you’re pain somewhat with Authentication, but it does happen to be one of the older parts of the framework (IIRC, was revamped in ASP.NET 2.0) and can worked with to make a little less painful.

  12. @Paul Cowan, I don’t accept your remarks. My organization makes use many pieces of open source software. We also use commercial products when it makes sense. Then build everything else ourselves.

    Whether open source is as deep as the ROR community /shrug I don’t dev on ROR and don’t have any desire to.

  13. @Chris Marisic whats not to accept? RoR does produce more OSS. That is my point and it is an obvious one. The fact that there is less OSS in .NET indicates that less developers are developing it.

    I am interested to know why my comment annoyed you so much.

    As for whether you have developed on ROR or have any desire to, I don’t care. You can develop in PERL for all I care.

  14. @Paul Cowan and more automatically = better?

  15. @Chris Marisic in this case yes, much better and a wider spectrum of choice.

    I am a .NET developer mainly so I have no gain from saying this. it is just my interpretation.

  16. @Justin A – “what about minification/compression of jss and css? bundling them into a single / a few files?”

    nuget -> Combres.

    RE: Blog author –

    “Yes, some of us do use .NET without SQL Server”, you then go on to say how good Rails is because its owns the entire stack!

    Anyway, yes a very opinionated framework on top of MVC that bundles in everything would be ideal. Having a complete VS/.Net/SQL/IIS combo all wrapped up would be amazing for the guys running MS top to bottom. For anyone else though I think it would be a detriment.

    Or I guess I could just start using Rails…

  17. Kudos for putting out a potentially controversial piece, while trying to maintain objective and evidence-based. It makes me happy to read posts where we can discuss the merits of different frameworks / stacks with an eye towards improving quality all around, rather than simply debating which is better (I mean, of course the one I use/know/love is better — let me make pull out my google + confirmation bias…).

    We need more forums like this where we can discuss different platforms without devolving into a flamewar.

  18. Hi,

    I completely agree with you. I’ve accepted rails/padrino as superior when i started to do startup weekends. In these weekends the idea is to build a working, deployed product from scratch and present it on sundays.

    I do like rails but its a bit much, i usually go to padrino, which is slimmer but the principles are the same.

    Its absolutely stunning how FULL STACK it is compared to mvc.

    Let me elaborate on some of the details of this ful stack:

    - At the httplayer, there is something which is called RACK. That converts http requests to ruby calls. It is layered and acts as middleware. It is the defacto standard in ruby when it comes to building web framewors. Because its middleware you can easily at gzip, caching, mutexes, fileserving and what not. Also the community embraced it and now its still being improved. Padrino, Sinatra, Rails, Camping they all run on rack. This pattern is so successful it has been ported to node.js as well under the name of connect.

    - At the routes level.

    Routes in rails, are very powerfull, they have the resources tag, that defines the standard REST methods, and also nested routes. Meaning, you can nest posts/comments in eachother.

    - At the controller level

    Controllers can have before filters, just like in mvc, and they can respond to js,xml etc in the same controller call.

    - At the view level

    The variables you define in your controller are past over to your view, no need for a magic @model variabele.

    Then we have the template engines:

    - Haml, well isjust haml we have nhaml which is nice.
    - SLIM template engine, a better easier to use template engine. Like haml, but better. Been cloned to node.js under the name Jade.
    - Liquid, Erb, Markup, Textile/redcloth.

    Even sexier, is that all the template engines, are abstracted in to a gem called tilt.

    which means (in pseudo):

    Tilt.Render “bla” searches for a template with the name bla, it doesnt matter if its haml, lquid, whatever it just compiles depending on the extension.

    Also some of the engines use an template to ruby compiler/abstraction layer called TEMPLE. Which makes, making your own template engine a lot easier.

    - Asset bundeling/minifcation.

    It has sprockets , minification and compiling of SASS/LESS.

    - Testing

    The defacto is rspec for testing, but even more powerfull is capybara for testing. It is a super pragmatic request spec driver. Which allows you to fast test the code with Visit “/home” click “my button” kind of style.

    On top of this, there is cucumber, with hydra.

    - Deployment

    For deployment there is the excelent capistrano that allows you to deploy your code via git, to multiple server via one command control app.

    - Database

    For databases there is activerecord/datamapper and another ton of tools. Its superior with its named scopes, and simplicity of use.

    It has seed, rebuild db, rake tasks and what nots. Also it runs on my many database types.

    - Community tools /services

    There is the excellent github, the for everyone accesible buildserver called travis ci.

    Well i can go on for hours but the most important thing is. All of this is super pragmatic, its easy to use and its easy to build apps with.

    I am building a clone of these important gems, to see if i can get the same productivity in .NET.

    Who’s helping me out ?

    Cheers,
    Emile

  19. Even more:

    Forms:

    - Formbuilder/simpleform/formtastic. Make nested forms super easy.

    Deployment:

    With Heroku its super easy to deploy with absolutely no effort. (we have app harbor now, which is a sort of heroku clone)
    With Chef its easy to build new server and install software remotely.

    Cheers,

    Emile

  20. Emile,

    Alot of those things already exist for .NET, the majority of them can all be installed directly with Nuget.

    - At the routes level.

    Look at RestMVC https://github.com/bbyars/restmvc

    - At the view level

    The variables you define in your controller are past over to your view, no need for a magic @model variabele. — The model is not magic, you specifically pass the model to the view. This is why the view is decoupled from the controller, this is a feature of MVC.

    Then we have the template engines:

    Razor is just the bomb. Honestly it’s the best view engine ever made, and Razor 2.0 raises the bar.

    - Asset bundeling/minifcation.

    Look at Cassette, Request Reduce, Squishit

    - Testing

    The defacto is rspec for testing, but even more powerfull is capybara for testing.

    MSpec + Machine.Fakes

    It is a super pragmatic request spec driver. Which allows you to fast test the code with Visit “/home” click “my button” kind of style.

    On top of this, there is cucumber, with hydra.

    Specflow + Selenium WebDriver

    - Deployment

    There’s app harbor and octopus deploy, along with built in web deploy

    - Database

    EntityFramework and EF Migrations are a strong choice here, Fluent Migrations is an alternative for EF migrations, however at this point EF migrations has become very robust and is likely the best choice.

    However I’ve found RDBMS to be entirely terrible for transactional system design, I do all primary development now targeting RavenDB which is just godly.

    - Community tools /services

    Team City, Hudson for CI, i can’t remember the 3rd option off hand, all are free or have no cost options. Codeplex, Bitbucket and GitHub all work great for .NET

  21. As someone who has developed on windows for 10 years before moving, I can safely say that windows an inferior development platform on just about every level.

    There is no focus on the shell. You only need to compare zsh to powershell to know the difference.

    I think the crudeness of the add view dialogue for ASP.NET MVC is a perfect analogy to how broken the platform is.

    It hurts every time I go back to windows and have to leave all that amazing tooling behind me.

    The visual metaphors that exist on windows are just not developer friendly.

    MS never really cultivated OSS and that might lead to the end of the story.

  22. @Paul Cowan you’re speaking of Microsoft that doesn’t exist any more, you need to get out from under your shell.

    Server 8 will ship with factor 10x as many powershell commandlets along with intellisense for powershell. Regardless if you want to state that powershell as a language isn’t perfect that’s fine because in Server 8 system admins will be able to ridiculous amounts of high powered server configuration and activities in single lines.

    The add view dialog is a joke, it’s not really needed. Views are just text files. However you can use the MVC Scaffholding nuget to create very powerful usages of create views/controllers. The end goal is to make dialogs like the add view window to be entirely extensible, not sure if that’s finalized for vs11 or not currently.

    I’m not sure where you pull “The visual metaphors that exist on windows are just not developer friendly.” out from. Visual Studio is by far the most powerful developer tooling ever created, especially coupled with Nuget now.

    “MS never really cultivated OSS and that might lead to the end of the story.” That story has been changing over the past decade substantially. Look ASP.NET it’s being developed truly as OSS, you can go clone it, fork it and even submit patches. The experience they’ve created with Nuget is a dream for .NET and OSS/FOSS. There’s nothing like nuget install RavenDB and you’re ready to rock and roll.

    Yes Nuget might just be the .NET version of Gems but the integration with VS is the huge difference, especially now how you can use nuget even with a build server or crazy things like build an entire project deployment organization around it: Octopus Deploy.

  23. @Chris Marisic

    I have to laugh every time a .NET developer mentions intellisense like it is an essential need to developl.

    Nuget is inferior, I know because I have used it and it is not just me who thinks this.

    I love VIM now, I love that it starts in a millisecond. I love all the vast array of plugins, bundles and dot files on github I fan use.

    VS is a big prehistoric, monolithic disaster. I smile every day that I don’t have to use it.

    I feel I am entitled to make these statements after so many years on the platform.

  24. @Paul Cowan

    You can think inaccurately as much as you want, but I guarantee you that I can code more productively using Visual Studio + C# + R# + ASP.NET + Nuget than you could ever hope to in VIM.

  25. @Chris Marisic How can you possibly prove that? What evidence do you have to back up that statement?

    I can say that I can fly to the moon.

    Does not mean that I can.

  26. I can say that because it’s just not humanly possible to navigate text files faster/more efficiently using a pure text editor only when modern software projects will generally have dozens and hundreds of files to structure and partition code and responsibilities.

    With R# I can jump and navigate to any place i need to be effectively instantly. Gems is nice, but it’s like nuget where install-package actually can install the package AND setup everything for your project to consume said package. With Gems you need to know where its installed, how to call it etc. The integration of nuget into VS is just superior.

  27. @chris marisic, I am laughing at your last post because you have obviously never used vim or at least vim properly.

    The cmd-p, ctags and buffergator give the same functionality with much better performance and less likely to hang.

    After using both VS and vim, I know what I prefer.

    There is no point debating when you are comparing your point of view to something you have never used.

  28. @Chris Marisic

    It is like me arguing that Vim is better than Emacs when I have never used Emacs and I have not so I have no idea which is better.

    I would not be arguing against Visual Studio if I had not used it but I have used it most of my professional career….more is the pity.

  29. I just don’t accept your statements as valid. Unless they built VIM versions or modules that actually UNDERSTAND code. There is absolutely no way it can do better than VS + R#.

    Another big factor with VS is the tight test integration I get.

  30. Have you used VIM + cmd p?

    Can you honestly say that you have. If not then it is pointless arguing against something you have not used.

    These dotfiles create a vimrc of pure goodness:

    https://github.com/skwp/dotfiles

    Waiting for the test suite to start up in R# is something I am glad I do not experience any more.

    As I said previously

  31. R# test settings, on the test runner build settings: build files never. Tools options unit testing, shadowcopy assemblies: false. Test up to 4 assemblies in parallel

    My tests start instantly.

    I used tools that would run my tests on every save, but that got ridiculous so now I can build to flush all changes to disk, and test immediately with 2 hotkeys. Also can do it with the mouse if desired.

  32. In the long run its all about your personal taste & oppinion. If you build a big application, there is usually a app-specific framework, so you do not need to operate on that low level as described.

  33. I like MVC 3 and 4 much better than other frameworks such as php ones, rails, django.

    One common problem to all is there will be things that you will have to spend time to get them done, doesnt matter which framework you use.

    Moreover you get great tools, and microsoft support, with community behind you with Microsoft tools. I dont feel the same for ruby or open source tools.

    http://hasanatagun.com

  34. Is there a reason that people have to resist competitive technologies so vehemently? Anyone who is good with -any- decent tool can do anything anyone else can do. Each tool does some things in a more user-friendly, nimble or reliable manner than others.

    I say learn as much as you can and see what you can do with it. My company may use ASP.NET / C#, but I have plenty of interest in F#, Java, Ruby, Python, client-side MVC Frameworks, Node.JS, etc.

    RoR and Java aren’t used by the companies who choose not to use ASP.NET MVC “just because”. They’re mammoth and have impressive communities behind them.

    Word on the street is that the best programmers hate all technology – because they can list the pros and the cons of each. (And boy, can they list cons.)

    I don’t think my expertise is quite that high yet.

    The idea of integrating Ruby/RoR with HAML, Handlebars/Mustache, SASS, LESS, Bootstrap, knockout, backbone, angular, ember, etc. makes me tingle. Everything from the raw HTTP requests to the highest levels of server and client-side abstractions are in your control. I think my pet peeve with – and also what I like about – RoR/OSS is that it moves so fast. You have to be pretty smart just to keep up.

    Enterprise Java/Oracle/BigData has an elite corp of developers with immense expertise in architecture and patterns. A ton of the patterns now seen in ASP.NET MVC were first popularized by the Java community. I can’t say I’m a huge fan of Java as a language in and of itself, but from what I hear and have seen, as an enterprise/server platform, it is top-notch.

    ASP.NET MVC is okay. Maybe I’m a bit pessimistic about it because I use it. Visual Studio 2012 is great. Integration with other MS products is great. I can’t say a ton of 3rd party products are amazing, but that situation has improved. Having only some pieces of my toolkit OSS is bothersome at times – you only have so much flexibility with the built-in tools and if you switch over to a 3rd party server, for example, there goes your customer support. There isn’t much incentive to create new OSS tools for MS products due to the fact that it’s not a full OSS technology stack. However, ASP.NET MVC, C#, Visual Studio, Entity Framework and whatever other utilities you use are generally really easy to use and pick up on. MS products are nice if you want a suite that you know will fit your needs for years to come, so long as your needs to change too much or too quickly.

    There are ways around all of the cons I could list, and there are alternatives to all of the pros. The truth is that skilled developers can make just about any tech work, although I do honestly think the RoR and Java communities have a 1-up on us MS developers at this time. Probably why they’re paid so much :)

    Oh well. Ce la vi!

Leave a comment