Friday, 27 June 2014

Alternative way of using RedirectToAction() in Sitecore MVC

20 comments
Today I’ve noticed a post in Sitecore SDN forum regarding RedirectToAction() is not working in Sitecore MVC. In this blog post I am going to explain how we can redirect to regular MVC controller action in Sitecore MVC project. We cannot use RedirectToAction() in Sitecore MVC as it interrupts the page rendering process in Sitecore. See below diagram made by David Morrison to get the overview of Sitecore MVC Request Pipeline Execution Lifecycle.
For the demo purpose; I’ve created a controller rendering GetBook which will get the book id using data source and will display specific book details. If data source is set to null then I’ve to redirect to Error Page (or Redirect to anywhere as per your requirement).
Below are the few ways to perform redirection (returning/rendering a view) in Sitecore MVC:
  1. Redirect to specified URL (Sitecore Page / ASPX Page / External URL) using Redirect(): Redirect() tells MVC to redirect to specified URL instead of rendering HTML. In this case, browser receives the redirect notification and makes a new request for the specified URL. URL in the browser's address bar gets updated. This acts similar to Response.Redirect() in Asp.Net WebForm. Moreover, Redirect() also cause the browser to receive a 302 redirect response status code within your application.
    public ActionResult DisplayBookDetail()
            {
                string DataSourceId = RenderingContext.Current.Rendering.DataSource;
                if (DataSourceId != null)
                {
                    // Write your logic here
                    return View();
                }
                else
                {
                    return Redirect("~/CustomASPXPages/Error.aspx");
                }
            }
    
    Use RedirectPermanent() instead of Redirect() if you want to return 301 redirect response status code.
  2. Redirect to another View: return View("ViewName") tells MVC to generate HTML to be displayed for the specified view and sends it to the browser. This acts similar to Server.Transfer() in Asp.Net WebForm. return View() doesn't make a new requests, it just renders the view without changing URLs in the browser's address bar.
    public ActionResult DisplayBookDetail()
            {
                string DataSourceId = RenderingContext.Current.Rendering.DataSource;
                if (DataSourceId != null)
                {
                    // Write your logic here
                    return View();
                }
                else
                {
                    return View("Error");
                }
            }
    
  3. Redirect to non-Sitecore Page using RedirectToRoute(): In RouteConfig.cs file you need to add a route that triggers MVC action. The routes for the MVC Web Application are defined in the RouteConfig.cs under the App_Start folder of the MVC Project.
    You can modify RouteConfig.cs and use the RegisterRoutes function to register the custom route. The route maps the first segment of a URL to a controller name, the second segment of a URL to a controller action, and the third segment to a parameter named id. The RouteConfig.cs contains the following code:
    public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                RouteTable.Routes.MapRoute("ErrorDetails", "GetBook/Error", new { controller = "GetBook", action = "Error" });
            }
        }
    
    The RouteConfig.cs contains a static RegisterRoutes function which is called from the Global.asax file.
    protected void Application_Start(object sender, EventArgs e)
            {
               RouteConfig.RegisterRoutes(RouteTable.Routes);        
            }
    
    RedirectToRoute redirects to a specific route defined in the Route table.
    public ActionResult DisplayBookDetail()
            {
                string DataSourceId = RenderingContext.Current.Rendering.DataSource;
                if (DataSourceId != null)
                {
                    // Write your logic here
                    return View();
                }
                else
                {
                    return RedirectToRoute("ErrorDetails");
                }
            }
    
  4. Redirect to Sitecore Page using RedirectToRoute():Use below code to redirect to Sitecore Page using RedirectToRoute()
    public ActionResult DisplayBookDetail()
            {
                string DataSourceId = RenderingContext.Current.Rendering.DataSource;
                if (DataSourceId != null)
                {
                    // Write your logic here
                    return View();
                }
                else
                {
                    //Get Sitecore Item where you want to redirect
                    Item item = Sitecore.Context.Database.GetItem(Sitecore.Data.ID.Parse("{24240FF2-B4AA-4EB2-B0A4-63E027934C38}"));
    
                    var pathInfo = LinkManager.GetItemUrl(item, UrlOptions.DefaultOptions);
    
                    return RedirectToRoute(MvcSettings.SitecoreRouteName, new { pathInfo = pathInfo.TrimStart(new char[] { '/' }) });
                }
            }
    
Comments and suggestions are most welcome. Happy coding!

20 comments :