将对象从 ActionFilter.OnActionExecuting() 传递到 ApiController

Pass an object from ActionFilter.OnActionExecuting() to an ApiController

我希望在 ActionFilter 中为每个 http 请求创建一个对象,并将该对象传递给控制器​​。到目前为止,我已经尝试 Request.Properties[] 如下

public class DbReadonlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        actionContext.Request.Properties["CustomObjectKey"] = new MyClass();

而且我还尝试将新对象直接分配给 ControllerBase class。

public class DbReadonlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var controller = (MyControllerBase) actionContext.ControllerContext.Controller;
        controller.StorageContextFactory = new MyClass();

问题在于,这两种技术都没有将 MyClass 的实例传递给控制器​​,因为在调用控制器方法时,新的 属性["CustomObjectKey"] 在 Webapi 管道中丢失了。

控制器在调用动作过滤器 OnActionExecuting() 后由 webapi 管道重新实例化。

断点确认 Webapi 管道在单个 http 请求期间安排以下事件流。

MyControler 的双重实例化很奇怪,但现在我正在寻找任何技术来将新创建的对象从动作过滤器传递到控制器。

Edit-1:本题v1中提到的MyAuthorizationFilter其实就是一个Authentication filter。仍在调查中。

解决方案:错误在另一个过滤器中。在我删除我的身份验证过滤器后,这个问题中报告的问题就消失了。

您将不得不使用 .add 方法 Request.Properties 收集。

public class DbReadonlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        actionContext.Request.Properties.Add(new KeyValuePair<string, object>("CustomObjectKey", new MyClass()));

您可以从您的 api 控制器中检索此值。

object _customObject= null;

if (Request.Properties.TryGetValue("CustomObjectKey", out _customObjectKey))
{
    MyClass myObject = (MyClass)_customObject;
}

将变量从 ActionFilter.OnActionExecuting() 传递给 ApiController 的另一种方法:

public class CustomFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext actionContext)
    {
        actionContext.ControllerContext.RequestContext.RouteData.Values["CustomValue"] = "CustomValue";
    }
}

注意Web API使用ActionFilterAttribute :

System.Web.Http.Filters.ActionFilterAttribute

不是 MVC 经典:

System.Web.Mvc.ActionFilterAttribute

使用:

[CustomFilter]
public class SomeController : ApiController
{
    string customValue = RequestContext.RouteData.Values.ToDictionary(x => x.Key, y => y.Value)["user_id"].ToString();
    //...
}