Hugoware

The product of a web developer with a little too much caffeine

Archive for May 25th, 2009

Is ASP.NET And MVC Really A Good Fit?

with 8 comments

ASP.NET MVC is a new framework for building web applications. It’s geared to favor TDD and gives programmers more control over the the content that is sent down to the client. I’ve even defended ASP.NET MVC in other places for all of its great new features. I really do like ASP.NET MVC.

But the more I use it, the more I wonder if the pattern really works – or at least as well as WebForms did. Maybe I’m missing something, and I’d gladly take advice, but here are a few of my road blocks.

The Disconnect With RenderPartial

One of the cool things about WebControls was that you still had an awareness of other parts of the page. If you needed some client script to be attached to a page to make your control work, then…

this.Header.Controls.Add(
  new LiteralControl("<script type='text/javascript' >alert('hello world');</script>"
  ));

No problem. Stylesheets can be added, scripts imported – great. But what about MVC, more specifically, inside of a “UserControl/PartialView”.

<% this.Header.Controls.Add(
  new LiteralControl("<script type='text/javascript' >alert('hello world');</script>"
  ));%>

What does this little code snippet create? Object reference not set to an instance of an object. exception. Uh oh. Nobody is home.

But even if you could pass some sort of reference to the header into your control – How do you plan to add anything anyways? Code between <% and %> is executed after your header has been rendered, or at the very least, is no longer checking for changes to itself (I’m not exactly certain if it is fully rendered but it doesn’t reflect any changes made to it).

Of course, you can always add script and link tags inline, but isn’t that a step backwards?

Knowing Everything Going Into A View

Once the controller finished handling a request it passes the information into the view. The view, as I understand it, isn’t supposed to do anything more than display the result. But is it really that simple? Do your views have a standard way of turning out every time? Do you really always know exactly everything you’re planning on displaying? Or the order your plan to show it?

I’m working on a project right now that allows people to type in a search term and then get results from all sorts of categories. Not only that, the results are order by most relevant to least relevant on the view as well as changes up the text and wording of your results depending on your query (like searching for locations near zipcode returns distances or searching for open stores returns hours, etc…).

So here’s the problem – I’ve got defined classes for each of the types of results so I can include a score for each of them (since I can’t use the generated LINQ object), I’ve got a container class for each of them to calculate the scores (since a generic list won’t do), I’ve got another class to represent the view (as the ‘generic type’). I just want to do a LINQ query and drop my results into a Databound control!!

Instead, I’ve got all these extra classes, which feels like clutter to me. Not only that, ordering the content on the page is a trick in itself. With WebForms you could reorder controls and that was the end of it. As of now, I haven’t found an easy way to do this with MVC.

Maybe I’m a little spoiled from using Javascript so much lately working on jLinq. I enjoy the flexibility you have. Want to add a score property? something.prop = "Assigned just like that!"; Need to add a function! something.generate = function() { ... }; If you read my previous post about passing Anonymous Types, you’ll understand where the inspiration came from.

Inline Code Just Doesn’t Replace WebControls

<% and %> just doesn’t work as well as a WebControl. Not only is it a little difficult to read, it’s also deceptive in how it works. For example, what is shown on the page when this view is run?

<%--In the <body> tag--%>
<asp:Content ContentPlaceHolderID="body" runat="server">
    <% this.ViewData&#91;"MyParam"&#93; = 5; %>
</asp:Content>

<%--In the <head> tag--%>
<asp:Content ContentPlaceHolderID="head" runat="server">
    <% =this.ViewData&#91;"MyParam"&#93; %>
</asp:Content>

It’s not 5, but I’m sure you knew that. But does everyone on your team know that? Were you able to say with certainly before you answered?

Now, that’s not to suggest that you can’t make the same mistake inside of a WebForm, but inline server side code is already hard enough to read to begin with; what happens when you start placing your code in the wrong order as well? Moving code between <script> tags doesn’t help that much either.

Exactly, What Are We Testing Again?

I won’t claim to know much of anything about TDD – I’m admittedly as beginner. I’ve noticed the claim that MVC makes great strides in improving TDD by using Controllers. This way you can generate tests using the Controller Actions – something was much more difficult with WebForms.

This might not really be directed at MVC as a fault, but do we really need to test Controller Actions? Or are we actually testing the functionality behind the scenes? For example, I keep seeing a lot of tests like this.

[Test]
public void RouteDefaultsWork() {
    var app = new GlobalApplication();
    RouteCollection routes = new RouteCollection();
    GlobalApplication.RegisterRoutes(routes);
    var context = MvcMockHelpers.FakeHttpContext();
    context.Request.SetupRequestUrl("~/home");

    var data = routes.GetRouteData(context);
    Assert.AreEqual("home",data.Values["controller"]);
    Assert.AreEqual("Index",data.Values["action"]);
}

Is that really a test? That proves something that we’re going to notice the second we run the app (which I’m hoping is done before you release your app 🙂 ) Aren’t we more concerned if our functions that pull, format and update information are accurate. A unit test makes sense for .CalculateRate() or .GetClosestLocationToZipcode(), but I haven’t quite figured out the purpose of testing a controller action.

With that said, are the Controllers really handling this kind of logic? Or haven’t we created separate, reuseable classes elsewhere that are handling this programming? If so, is making Controllers available for writing tests really all that helpful? I don’t really know.

I’m clearly not an authority on TDD with MVC, so any clarifications on what I’m doing wrong then I’m welcome to advice.

Summary

Don’t get me wrong – I love MVC. It’s bugged me for a long time being stuck using annoying parts of ASP.NET like using only a single form for a page or stupidly long control IDs for things that never needed an ID. It just seems that a lot is lost when you move away from WebForms.

I know that development is in full swing for MVC and I expect for things to only improve at this point. I look forward to the future of MVC since it will no doubt continue to improve.

Written by hugoware

May 25, 2009 at 1:02 am