【问题标题】:ASP.NET 5/MVC 6 pipeline branching and controller namespace constraintASP.NET 5/MVC 6 管道分支和控制器命名空间约束
【发布时间】:2016-01-06 21:42:07
【问题描述】:

我想在 ASP.NET 5/MVC 6 中使用管道分支,这样只有命名空间 xxx.yyy.Pipe1.Controllers 中的控制器才能“可用”到“Startup.cs”中这样映射的分支app.Map("/pipe1", ConfigurePipe1);
这样做的首选和/或正确方法是什么? 与其说是控制器发现,不如说是限制在请求处理期间可以解析的控制器集。我这样做的原因是需要为每个管道使用不同的身份验证方案,从而为每组控制器使用不同的身份验证方案。 谢谢!

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc


    【解决方案1】:

    如果我理解正确,您想通过相应控制器的命名空间映射应用程序吗?

    我认为这是不可能的。有MapWhen 方法。我试图在它调用时解析控制器,但我没有运气(我知道这是没有希望的)。

    app.MapWhen(context => {
        var shouldWeMap = ... // here I tried many things but it was impossible to resolve the controller.
        return shouldWeMap;
    }, ConfigurePipe1);
    

    如果你想知道哪个控制器会被命中,你必须让 asp.net 将此请求映射到一个 mvc 配置。但是在这样做之后,您就错过了将该请求映射到应用程序的机会,因为您已经完成了它:(

    【讨论】:

      【解决方案2】:

      我找到了解决方法。它使用自定义IActionFilter 来检查每个请求中使用的配置。

      只需按照您之前的建议映射一个新配置:

      app.Map("/pipe1", ConfigurePipe1);
      

      然后在ConfigurePipe1 中使用不同的签名(唯一名称?)使 MVC 到 MapRoute。通过这种方式,您可以实现自己的全局 IActionFilter 并强制它检查已使用的 RouteData。

      在那里你可以做任何你想做的事。检查控制器的命名空间等等...

      所以ConfigurePipe1 可能是这样的:

      public void ConfigurePipe1(IApplicationBuilder app)
      {
          app.UseMvc(routes =>
          {
              routes.MapRoute(
                  name: "CustomPipeRoute",
                  template: "{controller}/{action}/{id?}",
                  defaults: new { controller = "Home", action = "Index" }
              );
          });
      }
      

      在自定义 IActionFilter 中,我们可以像这样检查它们:

      public class GlobalActionFilter : IActionFilter
      {
          public void OnActionExecuting(ActionExecutingContext context)
          {
              var controllerNamespace = context.Controller.GetType().Namespace;
              var pipeRoute = context.RouteData.Routers.OfType<TemplateRoute>().FirstOrDefault(x => x.Name == "CustomPipeRoute");
              if (pipeRoute != null)
              {
                  // We are using /pipe1
              }
              if (.....)
              {
                  // You can redirect to somewhere else if you want.
                  var controller = (Controller)context.Controller;
                  context.Result = controller.RedirectToAction("Index", "Controller");
              }
          }
      
          public void OnActionExecuted(ActionExecutedContext context)
          {
          }
      }
      

      另外不要忘记将自定义过滤器注册为:

      services.AddMvc(config =>
      {
          config.Filters.Add(typeof(GlobalActionFilter));
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-13
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 2015-04-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多