ASP.NET 核心 - 添加自定义 属性 到 HttpRequest

ASP.NET Core - Add Custom Property to HttpRequest

我有一些 ASP.NET 中间件可以在收到请求时对其进行分析。根据其中可用的内容 HttpRequest,我想添加一个我可以自定义的 属性在我的代码中使用。我的问题是,有没有办法将 属性 添加到 HttpRequest 以便我可以在我的控制器中访问它?例如,在我的 Controller 中,我想做这样的事情:

namespace MyWebsite.Controllers
{
  public class MyController : Controller

  public IActionResult Index()
  {
    if (this.Request.MyProperty == null)
    {
      return View("~/Views/NoExist.cshtml");
    }
    return View ("/Views/Index.cshtml");
  }
}

MyProperty 表示我想通过自定义中间件注入或添加的自定义 属性。这可能吗?如果是这样,如何?如果不是,推荐的方法是什么?

谢谢!

  1. 创建一个具有只读 ConcurrentDictionary 属性 的单例。或者,使用 ConcurrentDictionary 类型的只读静态 属性 创建静态 class。

  2. 将只读队列 属性 添加到全局 class。

  3. 使用 HttpContext.TraceIdentifier 作为唯一键并添加 将数据作为值传递给 ConcurrentDictionary。同时将 HttpContext.TraceIdentifier 和 DateTime.Now 添加到队列 属性.

  4. 创建一个清理方法,通过将数据从队列中拉出直到低于特定年龄(比如 90 秒),从队列和 ConcurrentDictionary 中删除旧数据。

  5. 创建一个定期运行并调用清理方法的后台工作程序。有图书馆可以做到这一点。您也可以在启动时分拆一个线程,但这缺乏冗余,除非您对其进行编码。

  6. 使用密钥 HttpContext.TraceIdentifier.

    从任何调用的代码访问您的数据

编码愉快!

实现您想要的东西的传统方式是通过 HttpContext.Items 共享所有内容。这样你应该自己管理 keys 或者甚至可以声明你的扩展方法以方便地设置和获取值。

但是在这里我想介绍一种与asp.net core中的新概念request feature相关联的新方法。与每个请求关联的功能可以由管道中的不同中间件添加,并且可以被任何(如果可用)使用。这看起来更整洁、更有条理,尽管与旧方法相比可能不是很方便。

假设您在中间件的上下文中,以下代码将添加一个公开您的 属性:

的功能
//declare the feature interface first
public interface IMyFeature {
    string MyProperty {get;}
}

//the concrete type for the feature
public class MyFeature : IMyFeature {
    public MyFeature(string myProperty){
        MyProperty = myProperty;
    }
    public string MyProperty {get;}
}

//the context is in your middleware
//add the feature
var myFeature = new MyFeature("value of your choice");
//context here is the HttpContext
context.Features.Set<IMyFeature>(myFeature);

现在,在管道后面的任何地方,您都可以像这样使用添加的功能:

//context here is the HttpContext
var myFeature = context.Features.Get<IMyFeature>();
if(myFeature != null){
    //consume your feature
}

我认为 request features 概念的优点之一是它对 feature interfaces 的明确定义,可以通过您的代码轻松学习、引用和管理。甚至将它移植到某个库中以供重用也比依赖某些常量密钥来访问共享数据(通过使用 HttpContext.Items 实现)更有意义。当然对于一些简单的数据分享,你可以只用HttpContext.Items,request这个特性以后可能会进化,有一个很酷的概念,可能包含更多的数据。