WebAPI-根据请求手动解决控制器和操作

时间:2018-10-31 09:07:50

标签: c# asp.net-web-api session-state

我想让我的WebAPI应用程序根据如下操作属性来更改使用的SessionStateBehavior

    [HttpPost]
    [Route("api/test")]
    [SetSessionStateBehavior(SessionStateBehavior.Required)]    // <--- This modifies the behavior
    public async Task<int> Test(){}

但是,似乎唯一可以更改会话行为的地方是在HttpApplication的{​​{1}}内部(或在类似地方,在请求生命周期的早期),否则我会发现错误:

Application_PostAuthorizeRequest

因此,在那时还没有完成控制器或动作解析,所以我不知道为了检查其属性将调用什么动作。 因此,我正在考虑手动解决该问题。

我从以下几行代码开始首先解析控制器:

'HttpContext.SetSessionStateBehavior' can only be invoked before 'HttpApplication.AcquireRequestState' event is raised.

但是在最后一行中,我无法从请求中获得正确的 var httpCtx = HttpContext.Current; var ctrlSel = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector; var actionSel = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IHttpActionSelector)) as IHttpActionSelector; HttpControllerDescriptor controllerDescriptor = ctrlSel.SelectController(httpCtx.Request); 。 任何想法如何获得? 它不在控制器内部,所以我在那里还没有准备好。 还是有更好的方法来做到这一点? 我正在尝试查看框架的反汇编代码以复制其部分内容,但此时我很迷茫...


更新:

这是我手动解决操作最接近的方法,但是它不起作用:

我已经注册了这两项服务:

HttpRequestMessage

...并尝试获得所需的会话行为,例如:

            container.RegisterType<IHttpControllerSelector, DefaultHttpControllerSelector>();
            container.RegisterType<IHttpActionSelector, ApiControllerActionSelector>();

我有一个替代性的技巧可以使它起作用(从客户端发送标头值以修改会话行为),但是如果上述版本起作用,那就很好了。

更新:

最终,我根据客户端标头值设置了会话行为,并根据请求生命周期中稍后的操作属性验证了发送标头的有效性。如果有人可以解决我在上面使用的动作解决方案代码,请随时在此处发布答案。

1 个答案:

答案 0 :(得分:0)

我不知道这是否会对您有所帮助,但是我只是在学习Pluralsight课程(https://app.pluralsight.com/player?course=implementing-restful-aspdotnet-web-api),并且在“版本控制”一章中,作者展示了如何在他< strong>可以访问该请求。

控制器选择器如下所示:

public class CountingKsControllerSelector : DefaultHttpControllerSelector
{
  private HttpConfiguration _config;
  public CountingKsControllerSelector(HttpConfiguration config)
    : base(config)
  {
    _config = config;
  }

  public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
  {
    var controllers = GetControllerMapping();

    var routeData = request.GetRouteData();

    var controllerName = (string)routeData.Values["controller"];

    HttpControllerDescriptor descriptor;

    if (controllers.TryGetValue(controllerName, out descriptor))
    {
      [...]

      return descriptor;
    }

    return null;
  }
}

它已在WebApiConfig中注册为:

config.Services.Replace(typeof(IHttpControllerSelector),
  new CountingKsControllerSelector(config));