global.asax redirecttoroute not working

2019-04-12 07:56发布

问题:

I want to use a custom route in my global.asax with response.redirecttoroute but it is not working. I have the following in my RouteConfig:

routes.MapRoute(
            name: "Error",
            url: "Error/{action}/{excep}",
            defaults: new { action = "Index", excep = UrlParameter.Optional }
        );

And in my global.asax I do the following:

Response.RedirectToRoute("Error", new { action="Index", excep=ex.Message });

In my ErrorController I have:

public ActionResult Index(string excep)
    {
        ViewBag.Exception = excep;

        return View();
    }

And in my Index view for the error I call the ViewBag.Exception to show the exception.

When I use:

Response.Redirect("/Error/Index/0/"+ex.Message, true);

And use this in my controller:

public ActionResult Index(int? id,string excep)
    {
        ViewBag.Exception = excep;

        return View();
    }

It works, but this is with the default route and is not what I want. Why does it work with a redirect but not with redirecttoroute?

回答1:

I faced the same issue but now I found a solution. Maybe you can try this: Just rename the class names or variable names to your needs. Take note after changing anything from your Global.asax clear your browser cache. Hope this helps.

Global.asax

  public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
       //Make sure this route is the first one to be added
        routes.MapRoute(
           "ErrorHandler",
           "ErrorHandler/{action}/{errMsg}",
           new { controller = "ErrorHandler", action = "Index", errMsg=UrlParameter.Optional}
           );
        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

Once an unhandles exception occurs redirect the response to your error handler from your Global.asax Application_Error event

 protected void Application_Error(object sender, EventArgs e)
        {
            var errMsg = Server.GetLastError().Message;
            if (string.IsNullOrWhiteSpace(errMsg)) return;
            //Make sure parameter names to be passed is are not equal
            Response.RedirectToRoute("ErrorHandler", new { strErrMsg=errMsg });
            this.Context.ClearError();
        }

Error Handler Controller

public class ErrorHandlerController : Controller
    {

        public ActionResult Index(string strErrMsg)
        {
            ViewBag.Exception = strErrMsg;
            return View();
        }

    }

To test the error handler on your Index ActionResult of HomeController add this code.

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //just intentionally add this code so that exception will occur
            int.Parse("test");
            return View();
        }
    }

The output will be



回答2:

This other question has a pretty good answer: How is RedirectToRoute supposed to be used?

I would try adding a Response.End() after the RedirectToRoute and seeing if that works.



回答3:

here is how i solved my problem using MVC 4:

RouteConfig.cs

    routes.MapRoute(
            name: "ErrorHandler",
            url: "Login/Error/{code}",
            defaults: new { controller = "Login", action = "Error", code = 10000 } //default code is 10000
        );

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

Global.asax.cs

    protected void Application_Start()
    {
            //previous code
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            this.Error += Application_Error; //register the event
    } 

    public void Application_Error(object sender, EventArgs e)
    {
            Exception exception = Server.GetLastError();
            CustomException customException = (CustomException) exception;
            //your code here

            //here i have sure that the exception variable is an instance of CustomException.
            codeErr = customException.getErrorCode(); //acquire error code from custom exception

            Server.ClearError();

            Response.RedirectToRoute("ErrorHandler", new
                                    {
                                            code = codeErr
                                    });
            Response.End();
    }

Here is the trick: make sure to put Response.End() at the end of Application_Error method. Otherwise, the redirect to route will not work properly. Specifically, the code parameter will not be passed to controller's action method.

LoginController

    public class LoginController : Controller
    {
           //make sure to name the parameter with the same name that you have passed as the route parameter on Response.RedirectToRoute method.
           public ActionResult Error(int code)
           {
                   ViewBag.ErrorCode = code;

                   ViewBag.ErrorMessage = EnumUtil.GetDescriptionFromEnumValue((Error)code);

                   return View();
           }
    }