008So Im a n00b in some areas and it is painful finding this out sometimes. I spent most of the morning trying to figure out why my ASP.Net Web Site application wasnt routing to my MVC controller that is inside of my ASP.Net MVC Area.

Granted, that is a weird setup so there are a lot of things I thought could possibly go wrong. The real reason was embarrassingly obvious, but not embarrassing enough that I wouldnt post it for the world to see.

What do you see wrong with this route:

context.MapRoute(
    "Default Route",
    "ServerManagement/{controller}/{action}/{id}",
    new {   controller = "farms",
            action = "index"
        });

Give up? You have to give a default value if you have a placeholder in the route. In this case we have /{id} in the route, but we never a default value for the id. The following route worked fine.

context.MapRoute(
    "Default Route",
    "ServerManagement/{controller}/{action}/{id}",
     new {   controller = "Farms",
             action = "index",
             id=""
         });

Lesson learned!

012 Its nice when fixing a problem is easy.  Its nice when you scratch your head for a bit and then smack your forehead because someone in front of you laid out exactly what to do, and exactly what needs to be done.  I just had such a moment.

While working MVC into out existing ASP.Net Web Site project we hit, what we thought was a brick wall.

HTTP Error 500.22 - Internal Server Error
An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.

 

Well the Visual Studio engineers deserve a hand for helping me get this going.  After spending a minute looking into the web.config to find out what was wrong, I ran into this little bit of commented out configuration.

<!--
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.

    <system.webServer>

        ...then some more config

 

That is exactly what was needed to take us into integrated mode in IIS, which is needed for MVC.

Some of you non-RSS readers might have noticed about a month ago I changed the theme of my blog. Ive received several complaints about the background and dont really feel like messing with the getting a new one right, so lets just change the whole theme.

I was quite partial of the background as it was an abstract shot I took of a local landmark, but I had to yield to the massesthats a bit of an overstatement I guess; however, I cant argue with the success.

Just take a look at the bounce rate of the blog over the past month. I will give you one guess when I changed the theme.

SS-2010.03.29-10.51.37

Pretty shocking huh? As a friend pointed out, the lower bounce rate could be because the visitors are lost or dont know where to find what they are looking for, but as as 80% is coming in off keyword traffic and 19% are coming from my linked articles on StackOverflow, I dont think thats a problem.

Lets face it. Everyone loves MVC. At least all the web purists love it. Its clean, straight forward, and very testable. But lets also face it. We have a huge investment in WebForms. I mean up until now, 100% of the stuff we built was WebForms, include 100% of the master pages.

These pages govern how  the entire site looks and a wee bit of its functionality.

a

It would be a real shame if we had to start being less DRY and copy all that markup, in potentially many files, to new, MVC master pages. Luckily, you dont.

Let me stop right there. Technically, no, you dont. Mvcs ViewMasterPage (VMP) inherits from MasterPage (MP), so you can just tell your VMP to use the MP you want and it will work, unless you have the single line I hate more than any other lines in your MP.

<form id=Form1 runat=server>

 

So this single line blows the possibility of using the master page as a VMP out of the water. No problem right, include that in a nested MP and put that runat=server around the content place holder, right?

a_3

Thats nice and all, but all those other bit out side of the WebForms specific master page needs to be inside that stupid form.

image

Uh oh! No way around that one! Either move the run at server form outside or convert those controls. Id vote for convert the controls.

OK, so how about just use partial views and HtmlHelpers. That sounds like a good idea. Heres another problem.

<%= Html.MyMenu() %>

 

System.Web.UI.MasterPage does not have a HtmlHelper attribute where we get all those nice HtmlHelper Extensions. What about just creating one and using it?

<%= new HtmlHelper(null,null).MyMenu() %>

 

Great! That compiles, but dont get too excited. It doesnt run. We cant just pass null into HtmlHelper. We can new up the first parameter and create our own custom implementation of the second and it does work.

<%= new HtmlHelper(new ViewContext(), new FakeViewDataContainer).MyMenu() %>

 

That looks nasty too, but since that is my own customer helper extension, when not just call into that directly.

<%= MyMenuHelper.MyMenu(null) %>

 

Thats better, and since we arent using the HtmlHelper at all, we can clean up the syntax just a bit.

<%= MyMenuHelper.CreateMenu() %>

 

I can live with that, but if we ever need to do anything complicated that requires view data or other information to be passed along, were in a nasty situation. This works for us for now, so were going to ride this idea for a little longer and see how it goes.

Eventually all those WebForms pages will be moved over to MVC and this wont be an issue. Well have only the MVC master page and everything will be simple.

Lets face it. jQuery has made writing JavaScript cool and fun. JavaScript had a bad reputation in my world for a long time, and for no really good reason. JavaScript is an amazing language. Its the crappy compatibility browser implementation of that really sucks. Anyway, Im digressing already.

We write a lot of JavaScript to make the UI snazzy, attractive, quick and easy to use. Im sure we all write a lot of a JavaScript. Im sure we all have tons of JS files sitting around and we include a handful of them on each page, mix and match, pick and choose. What a mess!

Besides the nightmare of having to know which files to include, on which pages, this method is also a performance drag. Each page needs to request 15 to 20 JS files. Sure the page browser is going to cache some of them, but we still pay for the expense in some way or another.

In addition to the performance problem, there is a deployment headache where we have to minify 30 different files. Sure we could script that, but still sounds like a headache.

So how do I have only one JS file (minus the core jQuery stuff I pull from a CDN)? Plug-ins! Every bit of JS I use on my pages is wrapped in a jQuery plug-in. Of course there is a tiny bit of JS that invokes the plug-in that is either directly on the page or in its own JS file, but in comparison of lines, it is statistically insignificant.

What this lets me do is combine every JS file I have into a single giant JS file, minify that, and link it once. Everything I could possibly do is pulled down in that one file, one time, via one request.

Im sure we all have JS like the following.

$().ready(function(){
  $(".myButton").click(function(){
      alert("You clicked me.");
      $(".message")
           .css("color","blue")
           .text("my message is blue");
  });

});

Pretty typical jQuery. Everyone likes blue messages. What I don't like about this script is I can't drop it on the page where I don't want that to happen. If it's in my master JS file, every page is going to get this action, and that's probably not what I want.

So let's make a plug-in for it. This is my basic pattern for creating a jQuery plug-in.

(function($){
  $.fn.messageForm = function(options){
    var defaults = {};
    var params = $.extend(options, defaults);

    // do stuff here

    return this;
  }
})(jQuery);

There are a lot of websites out there that can explain the pattern better than I can, but the basics are simple.

First, we create an anonymous function with a $ parameter and pass the jQuery object to it. This avoids any naming conflicts we might have with $ and ensures we can use it in our plug-in.

We setup some default values, although empty are at this point, and then merge them with the options that are passed into the call to the plug-in. This lets us easily parameterize the call without adding loads of new variables.

Lastly we return the jQuery object the plug-in was called on so we can allow chaining of other plug-ins.

Throwing in the custom code and we end up with this.

(function($){
  $.fn.messageForm = function(options){
    var defaults = {
          buttonSelector : ".myButton",
          messageSelector : ".message",
          messageColor : "blue"
        };
    var params = $.extend(options, defaults);
    var $this = this;

    function buttonClick(){
       alert("You clicked me.");
       $(params.messageSelector,$this)
         .css("color",params.messageColor)
         .text("my message is " + params.messageColor);
    }

    $(params.buttonSelector,$this).click(buttonClick);

    return this;
  }
})(jQuery);

 

What I can do now is put this JS in a file next to dozens of other similar plug-ins and serve it up. We still have to call it from somewhere though.

$().ready(function(){
   $("body").messageForm();
});

I know the purists out there would scream, but I dont mind tacking this on the bottom of my HTML. You can pass some parameters to it as well.

$().ready(function(){
   $("body").messageForm({messageColor:"red"});
});