Redirect/Route

Topics: Administration, Customizing Orchard, Writing modules
Aug 26, 2011 at 4:03 PM

Hi I wonder if anyone can help please! I'm a novice to MVC and would like some help to redirect specific urls. For example if a user accesses the orchard website through

www.website.com/google/ 

I would the user to be redirected to 

www.google.com

 

 

I'm trying to create this as a module as I have many "Media Codes" with different redirect paths.

Thank you in advance!!

Coordinator
Aug 26, 2011 at 6:57 PM

There is a redirect action result that you can return from your controller action.

Aug 28, 2011 at 9:01 PM

Is there anyway you could be a little more descriptive about this process? I tried out a couple of different ideas, but I can't seem to get this routing concept in Orchard. Basically I now have a setup like this (and totally might be going in the wrong direction). I have a controller setup in one of my modules as:

namespace Rerouter.Controllers
{
    [Themed]
    public class RerouteController:Controller
    {
        private readonly IWebSiteFolder _webSiteFolder;
        private readonly IThemeManager _themeManager;

        public RerouteController(IOrchardServices orchardServices, IWebSiteFolder webSiteFolder, IThemeManager themeManager)
        {
            _webSiteFolder = webSiteFolder;
            _themeManager = themeManager;
            Services = orchardServices;
        }

        public IOrchardServices Services { get; set; }
        public Localizer T { get; set; }

        public ActionResult Index()
        {
            return Redirect("http://www.google.com");
        }
    }
}

And then I have a Routes.cs file that looks like:

 public class Routes : IRouteProvider
    {
        public void GetRoutes(ICollection<RouteDescriptor> routes)
        {
            foreach (var routeDescriptor in GetRoutes())
            {
                routes.Add(routeDescriptor);
            }       
        }

        public IEnumerable<RouteDescriptor> GetRoutes()
        {
            return new[] {
                new RouteDescriptor {
                    Priority = 5,
                    Route = new Route(
                        "Rerouter",//Name of route
                        new RouteValueDictionary {
                            {"area", "MyTheme"},
                            {"controller", "Rerouter"},
                            {"action", "Index"}
                        },
                        new RouteValueDictionary(),                    
                        new MvcRouteHandler())
                }
            };
        }
}
I just can't seem to get that controller to do anything? How am I supposed to call it. In MVC3 I would add my routes to the global.asax and I could call from anywhere. I could type /controller/action in the browser or I could use @Html.Action("Action","Controller", object). I have tried this code in both a module and a theme to see if I could get it working and I know I am doing something wrong. Orchard Architects to the rescue! (I hope)

Developer
Aug 28, 2011 at 9:26 PM

The controller in code is called 'ReRoute' but in your GetRoutes method its called 'Rerouter' also the Area is not correct.

try?

        public IEnumerable<RouteDescriptor> GetRoutes()
        {
            return new[] {
                new RouteDescriptor {
                    Priority = 5,
                    Route = new Route(
                        "Rerouter",//Name of route
                        new RouteValueDictionary {
                            {"area", "Rerouter"},
                            {"controller", "Reroute"},
                            {"action", "Index"}
                        },
                        new RouteValueDictionary(),                    
                        new MvcRouteHandler())
                }
            };
        }

Developer
Aug 28, 2011 at 9:39 PM

As Nick said - the Area parameter is incorrect. It should be equal to the name of your module.

- Piotr

Aug 28, 2011 at 11:25 PM

Okay I have it working with my Module is Rerouter, controller = RerouteController, action = Index.

I can call it from mysite.com/Rerouter/reroute/index but do you know how I can call it from the @Html.Action helper?

Specifically, I have an shape override in my Theme where when the user goes to my page mysite.com/mypage they get redirected, because on the page I have:

 

@Html.Action("Index", "Reroute")

 

The problem is I get an error that says:

 

The controller for path '/mypage' was not found or does not implement IController. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Web.HttpException: The controller for path '/mypage' was not found or does not implement IController. Source Error: 

Line 1: @Model.Html
Line 2: @Html.Action("Index", "Reroute")


How do I do this? Do I have to call that Controller from within the module views or can I call it from any view?

 

Developer
Aug 28, 2011 at 11:47 PM

You need to refer to your controller within the action method.

try...

@Html.Action("Index", "Reroute", new [] { Area = "Rerouter" })

You just need to add the area in.

Coordinator
Aug 29, 2011 at 6:10 AM

You could also use the Rewrite Rules module from the gallery ... which can do it without requiring some code.

Aug 29, 2011 at 7:10 PM

@Jetski5822

I get a compilation error with that:

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0103: The name 'Area' does not exist in the current context

Source Error:


Line 1:  @Model.Html
Line 2:  @Html.Action("Index", "Reroute", new [] { Area = "Rerouter" })

Developer
Aug 29, 2011 at 7:25 PM

There is an error - it should be new { Area = "Rerouter" } (anonymous object initializer) instead of new [] { Area = "Rerouter" } (which tries to initailize a collection).

- Piotr

Aug 29, 2011 at 7:53 PM

Thanks Piotr. That worked...sort of. It called the action just like I wanted...but then sadly I learned that MVC doesn't allow redirects from child actions. Maybe this was all for naught.

Child actions are not allowed to perform redirect actions.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions.

Source Error:

Line 1:  @Model.Html
Line 2:  @Html.Action("Index", "Reroute", new { Area="Rerouter" })