【问题标题】:Instantiation of a controller in OnActionExecuting (...not throwing a 404) in MVC Azure在 MVC Azure 中实例化 OnActionExecuting 中的控制器(...不抛出 404)
【发布时间】:2016-05-09 10:42:20
【问题描述】:

目标是在 Azure MVC 站点管理的同一 URL 上添加维护批次。网址应该是这样的:

https://admin.mysite.com/Batch?pass=HKE671

我决定重写OnActionExecuting 并在url 中捕获我需要的信息来触发maintenance 方法。我不熟悉 MVC 项目,这听起来可能不是很传统......

  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
      EmailUtility.SendSupportEmail("DEBUG - On result executing", ""); //I receive this email
      int y = 14;
      if (Request.Url.Query.Length > y)
      {
          string url = Request.Url.Query.Remove(0, y); // I remove ?ReturnUrl=%2f
          if (url.StartsWith("Batch"))
          {
              mySite.Admin.Web.Controllers.TenantController controller = new mySite.Admin.Web.Controllers.TenantController();
              EmailUtility.SendSupportEmail("DEBUG - starts maintenance", ""); // I don't receive this one
              controller.maintenance(HttpUtility.ParseQueryString(url).Get("pass"));
          };
      }
      base.OnActionExecuting(filterContext);
  }

这段代码在本地运行得和我需要的一样好,maintenance 方法被调用并完成了这项工作。但是在 Azure 上部署时,此修改会引发 404 错误。有趣的是,我发送了两封调试邮件:我没有收到第二封"DEBUG - starts maintenance",因此我的 404 错误来自OnActionExecuting 中的控制器实例化。

首先,我想了解为什么我的开发机器和 Azure 的行为不同?

那么,我怎样才能让它工作呢?谢谢,

1 月 4 日编辑:
我取得了一点进展,但是这个问题仍然没有解决。
- 关于我的开发机器和 Azure 之间的区别:这个站点上有一些重定向:https、404 和不存在的域。我认为这是由于 404 错误。用 try/catch 封装代码没有给我发送任何错误,所以我猜我可以从假设中抑制 404。
- 我在OnAuthorization 上尝试了上面的代码,但没有取得更多成功。
- 我注意到第一封电子邮件DEBUG - On result executing 实际上只在第一次测试时发送。我第二次运行测试时没有发送它。这对我来说没有任何意义,因为每次都应该检查会话。

今天的结论:这似乎更像是一个路由/重定向问题。

【问题讨论】:

    标签: c# asp.net-mvc azure routing onactionexecuting


    【解决方案1】:

    你为什么不这样做:

          protected override void OnActionExecuting(ActionExecutingContext filterContext)
          {    
             try {
                //your code here
             } catch (Exception ex){
                EmailUtility.SendSupportEmail("Execution failed: " + ex.Message , "");
             }
          }
    

    如果您的代码抛出异常,这应该可以让您更好地理解它失败的原因。

    但更重要的是,一种更可靠的检查正确 URL 的方法是:

    if (filterContext.HttpContext.Request.Url.AbsolutePath.EndsWith("Batch")){
    }
    

    据我所知,您的字符串变量“url”永远不会以“Batch”开头,因为 Request.Url.Query 仅包含“?”之后的部分。从而使您的支票始终返回错误。为什么这在 localhost 上工作很难说,但在我看来它不应该。

    实际上,要在所有情况下工作,您的检查应该是:

    if (filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().EndsWith("batch") || filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().EndsWith("batch/")){
    }
    

    编辑后: 好的,所以发生的情况是您在 Home Controller 中请求“Batch”操作,但由于您未通过身份验证,您被重定向到 Account Controller 中的 LogOn。您应该会看到一个登录页面,除非您的 Views 文件夹中没有关联的 LogOn 视图,或者根本没有 AccountController,在这两种情况下都会引发异常。

    Batch 方法是否应该检查身份验证?如果没有,请从 HomeController 中的此方法中删除 [Authorize] 注释,您应该没问题。

    您仍然需要调整 if-check,因为它实际上只在 LogOn 页面上评估为 true,如果您实际进入 Batch 页面,则为 false。

    【讨论】:

    • 我认为这不能以任何方式回答这个问题
    • 添加了第二个更重要的建议
    • 实际上我的检查有效,因为我抑制了查询的前 14 个字符 (?ReturnUrl=%2f),然后测试剩余字符串的开头是否存在“Batch”。它在我的开发计算机上运行良好。
    • 在您的开发计算机上,在 if 语句的行上设置一个断点,然后在调试器中添加两个监视:一个在“url”上,另一个在“filterContext.HttpContext.Request.Url”上。我对这两个值很好奇
    • filterContext.HttpContext.Request.Urlhttp://localhost:6146/Account/LogOn?ReturnUrl=%2fBatch%3fpass%3dHKE671&pass=HKE671urlBatch%3fpass%3dHKE671&pass=HKE671
    【解决方案2】:

    真可惜,问题出在其他地方!... 上面的代码运行良好,但该站点的路由拒绝了不完整的 url。在这种情况下,它必须包含项目名称:https://admin.mysite.com/Admin/Batch?pass=HKE671 然后一切恢复正常!

    所以答案是:我的本地计算机上的行为不同,因为我的开发计算机的本地主机不会像 Azure 那样路由解决方案的项目。

    非常感谢您的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多