ASP.Net MVC Redirect Specific Routes to External Site

10,069

You can use attribute routing to make it easier.

Your RouteConfig will look like below:

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

        routes.MapMvcAttributeRoutes(); // enable attribute routing

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

Then you can add an action like below:

public class SponsorsController : Controller
{

    [Route("sponsors/information")]
    public ActionResult RedirectInformation()
    { 
        return RedirectPermanent("http://yoururl.com");
    }
}

EDIT ONE

If you don't want to use attribute routing, you are still going to need the action but your RouteConfig will look like below:

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

        //The order is important here
        routes.MapRoute(
            name: "redirectRoute",
            url: "sponsors/information",
            defaults: new { controller = "Home", action = "RedirectToInformation"}
        );

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


    }
}

In routing like this, if the match is found the rest of the routes are ignored. So, you'd want to put most specific route on top and most general in the bottom

EDIT TWO (based on the comment)

You can put a simple appsettings in Web.config like below:

<appSettings>
  <add key="UseAttributeRouting" value="true" />
</appSettings>

Then in RegisterRoutes you can read it like below and make the decision.

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

        if (Convert.ToBoolean(ConfigurationManager.AppSettings["UseAttributeRouting"]))
        {
            routes.MapMvcAttributeRoutes();
        }
        else
        {
            routes.MapRoute(
                name: "redirectRoute",
                url: "sponsors/information",
                defaults: new {controller = "Home", action = "RedirectToInformation"}
                );
        }

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

The browser sometimes caches these redirects, so you may want to recommend clearing browser caches if you change these settings. Check this superuser post for clearing the cache for Chrome.

Share:
10,069
Tracy Fletcher
Author by

Tracy Fletcher

Updated on June 04, 2022

Comments

  • Tracy Fletcher
    Tracy Fletcher almost 2 years

    I have an nicely functioning ASP.Net MVC site using the simple standard routing scheme:

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

    My client would like to redirect the static pages to a secondary site, so that they can edit them, template-style, at will. The pages that actually do something will remain on the original site.

    What I need to do is set up routes for my functional views/controller-actions and redirect the remaining urls to the external site regardless of whether or not the specified url has a matching controller/action. I don't want to mess with the existing code, but use routing to execute some of the pages and redirect from others.

    For example:

    mysite.com/sponsors/signup would be executed

    mysite.com/sponsors/information would be redirected

    Even though the sponsors controller contains actions for both signup and information and there are existing views for both signup and information.

    So far, I have been unable to wrap my head around a way to do this.

    Any ideas?

  • Tracy Fletcher
    Tracy Fletcher about 9 years
    Thank you very much! The attribute routing may be my best choice. One thing that I failed to mention in my post is that I want to be able to switch the redirect functionality off via a web.config app setting. If I used attribute routing could I switch if off by conditionally including routes.MapMvcAttributeRoutes(); in my code path? This website runs an orphanage sponsorship program, and all my time is donated. Thanks for giving your time and expertise!
  • Tracy Fletcher
    Tracy Fletcher about 9 years
    Thank you very much for your help! I am trapping a perfectly valid mvc path, with existing controller and action code. Am I correct in saying that if my custom mvc handler appears in the list of registered routes in global.asax before the general handler, and redirects to an external url, I should be good to go?
  • Yogiraj
    Yogiraj about 9 years
    @TracyFletcher you are welcome! :) It's awesome that you are donating the time and I am happy to help out. Please check my edits.
  • Tracy Fletcher
    Tracy Fletcher about 9 years
    Thanks! The redirect is working well. An odd side effect has come up though. My ActionLinks are resolving incorrectly. My Global.asax.cs has a number of entries like: routes.Add("ContactUs", new HardRedirect( "ContactUs", strRedirectURL, new HardRedirectHandler()));
  • Tracy Fletcher
    Tracy Fletcher about 9 years
    Now my ActionLinks like: <%=Html.ActionLink("Edit", "Edit", "OrphanageKids", new { id = Model.DependentID }, null)%> are generating links like this: localhost:49268/…, instead of localhost:49268/OrphanageKids/Edit/60
  • Tracy Fletcher
    Tracy Fletcher about 9 years
    Thanks, I appreciate the kind words, and the help as well. Yes, your edit is exactly what I was thinking about. One last question though, can I use multiple Attributes on a single controller action?
  • Tracy Fletcher
    Tracy Fletcher about 9 years
    E.G. [Route("sponsors/information")] [Route("AboutUs/ContactUs")], etc.
  • Yogiraj
    Yogiraj about 9 years
    Yes, you can have multiple route attributes like that.
  • Josh Gallagher
    Josh Gallagher over 7 years
    "The browser sometimes caches these redirects" When using permanent redirects, as per this answer, it's not just the browser that caches. Proxy servers may choose to cache as well, and as permanent redirects are a promise to all parties that the resource will forever be hosted at the new address, the proxy may well cache this forever.