views:

123

answers:

4

Im in the process of moving our website from a crappy CMS over to a nice custom coded MVC website. Everything has gone smoothly so far but I'm having some issues with routing.

Our company sends out a lot of marketing emails and letters. In these we have the user go to Landing Pages so we can track how campaigns are doing, as well as offer more information. So in a letter it would say "visit www.OurSite.com/LandingPage". However, in MVC all the pages are placed in folders of their controllers by default.

So say I have a page called LP in my Home controller, so the url is www.OurSite.com/Home/LP

What I need is for it to become www.OurSite.com/LP like before, so our currently running marketing campaigns won't give a 404 once we launch the new website. Plus it's a lot nicer to type in so we wan't to keep using this for the future.

Based on this default route:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

I've tried creating something like this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );

    routes.MapRoute(
        "LandingPage",
        "{action}/{id}",
        new { controller = "Home", action = "LandingPage", id = UrlParameter.Optional }
    );
}

But it isn't solving my issue.

I've done some googling and it's all for really complex routing that doesn't really apply. I'm not really interested in making this ultra dynamic or anything. I have no problems making a new route each time we run a campaign.

I should also note, not everyone of these pages will be in the Home controller. So just having a route remove that won't work. There are many controllers our landing pages fall under.

+1  A: 

Your route just needs to route to the correct action that will then return the correct view. In other words you can have "www.OurSite.com/LandingPage" and have the view's actual path be /Home/LandingPage". The route will be

routes.MapRoute(
        "CPA2010Route", // Route name
        "CPA2010", // URL with parameters
        new { controller = "Home", action = "CPA2010"  } // Parameter defaults
    );

Then in the LandingPage action you return the path to the View:

public ActionResult CPA2010()
{
    return View("~/Views/Home/CPA2010.aspx");
}

Your default route needs to go last in the order the routes are defined or otherwise it is going to match this route and all the others. It will then try and route you to Home controller Index action which is not what you want. If you move this route to the top it will match correctly and get rid of your 404

amurra
I gave this a try but it is still producing a 404 for me. : (My route is: routes.MapRoute( "CPA2010Route", // Route name "CPA2010", // URL with parameters new { controller = "Home", action = "CPA2010" } // Parameter defaults );and my Home controller code is: public ActionResult CPA2010() { return View("~Views/Home/CPA2010.aspx"); }
Duk
Oh god that made messy code, you can also see it here: http://pastie.org/1054360
Duk
Duk: Just surround the code with tildes
abatishchev
+3  A: 

It appears you have two separate problems.

The first is that order matters when you add the routes.

The default route will literally match every request to your site. Since it is added first instead of last no other route will be examined.

Once you swap the order of those routes you probably want to use this: http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

All you have to do is add a reference and one line of code to your global.asax and you'll get much better info to work off of.

However, like I mentioned above, until the default route is added last even a correct route won't get executed.

jwsample
+4  A: 

I edited your code in http://pastie.org/1054360. You had to put your new route before the default one. When routing it doesn't matter which route matches most, the FIRST route matching the URL gets called. In your example http://domain.com/CPA2010 matches the default route first because there are no restriction specified. It looks for CPA2010 controller's Index action. Try the code here and it should work.

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "CPA2010Route", // Route name
            "CPA2010", // URL with parameters
            new { controller = "Home", action = "CPA2010"  } // Parameter defaults
        );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterRoutes(RouteTable.Routes);
    }
}
Ufuk Hacıoğulları
This worked. Thank you very much. I did however have to change the controller to say return View("CPA2010");. When I did return View("~/Views/Home/CPA2010.aspx"); I got an error saying it wasn't allowed. Thanks!
Duk
+3  A: 

It looks like you have a typo in your call to View().

Try: View("~/Views/Home/CPA2010.aspx") or View("CPA2010") or just View()

Mitch R.