Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 Routing with WebForms

I have a solution that is using WebForms .Net 4.0. I am planing to utilize MVC3 in the same solution. I followed Scott Hanselman blog and things were roling.

I have to admit that I am quite new to this. However, It seems that I am missing a big part in how routes really work in respect to namespaces.

Currently, our solution have the following:

WebApplicatin: 
  Accounting
      Receivables
         ReceivablesGrid.aspx
         ReceivableForm.aspx
      Payables
        PayablesGrid.aspx
        PayablesForm
 ..etc.

So, you can request a Page using

Domain/Accounting/Receivables/ReceivablesGrid.aspx
Domain/Accounting/Receivables/ReceivableForm.aspx?Key=1
Domain/Accounting/Payables/PayablesGrid.aspx
Domain/Accounting/Payables/PayablesForm.aspx?Key=1

....

I am planing to add another layer to resemble MVC.

WebApplicatin: 
      Accounting
          Receivables
             ReceivablesGrid.aspx
             ReceivableForm.aspx
             Mobile
              Controllers
                ReceivableConroller.cs
              Models
              Views
                Receivables
                   Index
                   Update
                   Edit
                   Create
          Payables
            PayablesGrid.aspx
            PayablesForm
            Mobile
              Controllers
                PayablesConroller.cs
              Models
              Views
                Payables
                   Index
                   Update
                   Edit
                   Create

     ..etc.

Of course, this is not the real names. However, I tried to make it as close as possible to my situation. Unfortunately, it would be best if I follow this because I could use some of the logic that might be added at the same namespace. Moreover,creating folders at the root to resemble the Controllers, Views, Models wouldn't work with my solution.

In Global.asax, I added a route as such:

routes.MapRoute(
      "AccountingReceivablesMobile", // Route name
      "Accounting/Receivables/Mobile/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional });

routes.MapRoute(
      "AccountingPayablesMobile", // Route name
      "Accounting/Payables/Mobile/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Another solution that I ended up trying is by extending the RazorViewEngine. In the constructor of the new engine, I set two properties as follows:

base.ViewLocationFormats = new string[] { "~/Accounting/Receivables/Mobile/Views/{1}/{0}.cshtml",
"~/Accounting/Payables/Mobile/Views/{1}/{0}.cshtml"
 };

base.MasterLocationFormats = new[] { "~/Views/Shared/{0}.cshtml"}. 

this worked quite well. However, I am just feeling that adding those routes is not very scalable as adding a webForm. My problem is I really don't want to add a route for every possible route. This means, I would have another route or entry to the array when I add a new view. So, How can i make this simpler? What am i doing wrong? I looked at Areas however it seems to force to create an Areas folder and put inside it.

Thanks,

like image 965
Sam Avatar asked Oct 12 '22 05:10

Sam


1 Answers

Because ASP.NET MVC (as well as Rails and many other MVC implementations) rely on conventions over configuration, the framework really wants to have the \controllers, \views, and \models directories in the root of the site. The work you are doing to get the routing engine to pick up your deviation from the conventions is precicely what MVC tries to keep you from doing.

You could extend a portion of the framework, like your tests with the Razor engine... But personally, I embrace the conventions of the framework, which makes some scenarios like you are encountering a bit tricky, but I know that another developer with a brief knowledge of ASP.NET MVC can open the code and find the area of concern they need right away. Nesting those convention-based folders under other folders would make that not as obvious, unless they were defined as MVC areas.

I have two production solutions that are a hybrid of ASP.NET WebForms and MVC3. In both cases, I went with the default approach (controller, model, view folders in the root) and began refactoring my legacy web forms code base to utilize modern standards like the repository pattern as well as moving common business logic to a "services" namespace or a new assembly in the solution.

By stepping back to refactor your code to possibly use interfaces for business logic/repository classes (I'm making an assumption that you do not currently, because most people didn't with web forms), you can use Ninject or another IoC container to make wiring of this logic easy(er) in both the legacy web forms and the MVC controllers, allowing better structure and a single point of concerns; normally in your App_Start().

In regards to being outside the namespace, a productivity tool like ReSharper or CodeRush will automatically detect and populate your using statement if you write code against another namespace.

I know this isn't the answer you are looking for and some may flame away, but I think it's important to step back and look at what you are trying to solve. Complicating the basic architecture of MVC to fit your scenario would prompt me to either hold off if I didn't have the time/resources to refactor some legacy biz logic or embrace the baked-in conventions; Start with a couple simple controllers to eliminate pain points in your web forms app and, as time permits, begin porting pages over to MVC. The interim may not be pretty, but it will be simple.

This is a very good question and you did a great job investigating your options by extending Razor. I'm interested to see if anyone else has thoughts on deviating away from the standard MVC folder conventions. Maybe I'm just picky?

The final thing to check out, if your primary end-goal is making your site mobile-enabled, is this article by Steve Sanderson. It leverages the excellent 51Degrees.mobi assembly for mobile device detection and covers use within ASP.NET and ASP.NET MVC. Sanderson also has a similar post on his personal blog going over the same topic.

like image 122
adammokan Avatar answered Nov 15 '22 09:11

adammokan