从 global.asax 中的 Application_BeginRequest 重定向到一个动作

Posted

技术标签:

【中文标题】从 global.asax 中的 Application_BeginRequest 重定向到一个动作【英文标题】:Redirect to an action from Application_BeginRequest in global.asax 【发布时间】:2011-10-27 23:03:23 【问题描述】:

在我的网络应用程序中,我正在验证来自 glabal.asax 的 url。我想验证 url,如果需要,需要重定向到一个动作。我正在使用 Application_BeginRequest 来捕获请求事件。

  protected void Application_BeginRequest(object sender, EventArgs e)
    
        // If the product is not registered then
        // redirect the user to product registraion page.
        if (Application[ApplicationVarInfo.ProductNotRegistered] != null)
        
             //HOW TO REDIRECT TO ACTION (action=register,controller=product)
         
     

或者有没有其他方法可以验证每个 url,同时在 mvc 中获取请求并在需要时重定向到操作

【问题讨论】:

***.com/questions/580728/…的可能重复 【参考方案1】:

以上所有方法都不起作用,您将处于执行方法Application_BeginRequest的循环中。

你需要使用

HttpContext.Current.RewritePath("Home/About");

【讨论】:

【参考方案2】:

使用以下代码进行重定向

   Response.RedirectToRoute("Default");

“默认”是路由名称。如果您想重定向到任何操作,只需创建一个路由并使用该路由名称。

【讨论】:

这将创建一个循环 @Null Pointer,请您接受其他可行的答案之一吗? 如果在 Application_beginRequest 函数中使用,这会导致发生重定向循环。【参考方案3】:

除了已经提到的方式。另一种方法是使用 URLHelper,一旦发生错误,我在场景中使用它,用户应该被重定向到登录页面:

public void Application_PostAuthenticateRequest(object sender, EventArgs e)
    try
         if(!Request.IsAuthenticated)
            throw  new InvalidCredentialException("The user is not authenticated.");
        
     catch(InvalidCredentialException e)
        var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
        Response.Redirect(urlHelper.Action("Login", "Account"));
    

【讨论】:

这会导致另一个请求。这又使另一个,。这使得另一个。当你在 application_begin 请求函数中时以此类推。 @RichardBarker 此代码不在 application_begin 请求中!!!!我把它放在 Application_PostAuthenticateRequest 中的 catch 块中,因为发生了 cas 错误 我很抱歉。问题显示 BeginRequest。我可以建议您更新您的答案以表明这一点并解释您这样做的原因吗? 这有点好,但我从您的更新中创建了一个简短的完整代码示例。这将有助于未来的堆垛机,使其更易于理解和使用。我相信这是解决 OP 中描述的问题的最佳解决方案 - 它将避免循环问题,但首先它需要再次检查当前请求是否用于登录操作。 我喜欢这样,因为它会从帮助程序生成 MVC 路由,并且会固有地处理对路由的更改。我从不习惯将 MVC 路由硬编码为字符串!【参考方案4】:

试试这个:

HttpContext.Current.Response.Redirect("...");

【讨论】:

【参考方案5】:

我是这样做的:

        HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Home");
        routeData.Values.Add("action", "FirstVisit");

        IController controller = new HomeController();

        RequestContext requestContext = new RequestContext(contextWrapper, routeData);

        controller.Execute(requestContext);
        Response.End();

这样你包装传入的请求上下文并将其重定向到其他地方而不重定向客户端。所以重定向不会触发 global.asax 中的另一个 BeginRequest。

【讨论】:

【参考方案6】:
 Response.RedirectToRoute(
                                new RouteValueDictionary 
                                     "Controller", "Home" ,
                                     "Action", "TimeoutRedirect"   );

【讨论】:

这会引起另一个请求;这将导致另一个请求。这会导致另一个请求。这创造了另一个。直到它完全出错。【参考方案7】:

我有一个旧的 Web 表单应用程序,我必须将其转换为 MVC 5,其中一个要求是支持可能的 old_form.aspx 链接。在 Global.asax Application_BeginRequest 中,我设置了一个 switch 语句来处理旧页面以重定向到新页面,并避免可能不希望的循环到请求的原始 URL 中的“.aspx”的主/默认路由检查。

    protected void Application_BeginRequest(object sender, EventArgs e)
    
        OldPageToNewPageRoutes();
    

    /// <summary>
    /// Provide redirects to new view in case someone has outdated link to .aspx pages
    /// </summary>
    private void OldPageToNewPageRoutes()
    
        // Ignore if not Web Form:
        if (!Request.RawUrl.ToLower().Contains(".aspx"))
            return;

        // Clean up any ending slasshes to get to the old web forms file name in switch's last index of "/":
        var removeTrailingSlash = VirtualPathUtility.RemoveTrailingSlash(Request.RawUrl);
        var sFullPath = !string.IsNullOrEmpty(removeTrailingSlash)
            ? removeTrailingSlash.ToLower()
            : Request.RawUrl.ToLower();
        var sSlashPath = sFullPath;

        switch (sSlashPath.Split(Convert.ToChar("/")).Last().ToLower())
        
            case "default.aspx":
                Response.RedirectToRoute(
                    new RouteValueDictionary
                    
                        "Controller", "Home",
                        "Action", "Index"
                    );
                break;
            default:
                // Redirect to 404:
                Response.RedirectToRoute(
                    new RouteValueDictionary
                    
                        "Controller", "Error",
                        "Action", "NotFound"
                    );
                break;

        
    

【讨论】:

【参考方案8】:

就我而言,我不喜欢使用 Web.config。然后我在 Global.asax 文件中创建了上面的代码:

protected void Application_Error(object sender, EventArgs e)
    
        Exception ex = Server.GetLastError();

        //Not Found (When user digit unexisting url)
        if(ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)
        
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "NotFound");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        
        else //Unhandled Errors from aplication
        
            ErrorLogService.LogError(ex);
            HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Index");

            IController controller = new ErrorController();
            RequestContext requestContext = new RequestContext(contextWrapper, routeData);
            controller.Execute(requestContext);
            Response.End();
        
    

这就是我的 ErrorController.cs

public class ErrorController : Controller

    // GET: Error
    public ViewResult Index()
    
        Response.StatusCode = 500;
        Exception ex = Server.GetLastError();
        return View("~/Views/Shared/SAAS/Error.cshtml", ex);
    

    public ViewResult NotFound()
    
        Response.StatusCode = 404;
        return View("~/Views/Shared/SAAS/NotFound.cshtml");
    

这就是我基于 mason 类的 ErrorLogService.cs

//common service to be used for logging errors
public static class ErrorLogService

    public static void LogError(Exception ex)
    
        //Do what you want here, save log in database, send email to police station
    

【讨论】:

【参考方案9】:

你可以试试这个:

Context.Response.Redirect();

不确定。

【讨论】:

以上是关于从 global.asax 中的 Application_BeginRequest 重定向到一个动作的主要内容,如果未能解决你的问题,请参考以下文章

从global.asax中的Application_BeginRequest重定向到某个操作

ASP.NET 将响应保存到 global.asax 中的文件

ASP.NET MVC中的Global.asax文件

为啥 Global.asax.cs 中的 Session_Start 会导致性能问题?

ASP.NET中的Webconfig 和 Global.asax区别

Global.asax 中的“解析器错误消息:无法加载类型”