Asp.Net Core中的HttpContext.Features与HttpContext.Items

Moh*_*ast 4 httpcontext asp.net-core

这两个属性之间有什么区别?

我可以使用HttpContext.Items而不是在HttpContext.Features之间共享数据middlewares。我看到的唯一区别是,我告诉Items了一个钥匙,它给了我对象,因此我必须强制转换它。此转换可以Features自动完成。

他们后面还有其他东西吗?

itm*_*nus 6

最大的区别在于,的HttpContext.Items目的是要存储Key-Value-Pair,而的HttpContext.Features目的是要存储Type-Instance-Pair

更明确地说,HttpContext.Items旨在共享当前请求范围内的项目,而作为HttpContext.Features的实例的IFeatureCollection绝不能那样使用。

IFeatureCollection接口表示HTTP功能的集合,例如:

  1. IAuthenticationFeature 它存储原始PathBase和原始Path。
  2. ISessionFeature 存储当前会话。
  3. IHttpConnectionFeature 存储基础连接。
  4. 等等。

为了帮助存储和检索Type-Instance-Pair,该界面具有三种重要的方法:

public interface IFeatureCollection : IEnumerable<KeyValuePair<Type, object>>{
    // ...
    object this[Type key] { get; set; }
    TFeature Get<TFeature>();
    void Set<TFeature>(TFeature instance);
}
Run Code Online (Sandbox Code Playgroud)

并且实现(FeatureCollection)会将值简单地转换为所需的类型:

public class FeatureCollection : IFeatureCollection
{
    // ... get the required type of feature
    public TFeature Get<TFeature>()
    {
        return (TFeature)this[typeof(TFeature)];    // note: cast here!
    }

    public void Set<TFeature>(TFeature instance)
    {
        this[typeof(TFeature)] = instance;          // note!
    }
}
Run Code Online (Sandbox Code Playgroud)

这是设计使然。因为不需要存储两个IHttpConnectionFeature实例或两个ISession实例。

虽然您可以存储一些Type-ValueFeatureCollection,但最好不要。如您所见,Set<TFeature>(TFeature instance)如果集合中已经存在某种类型,它将简单地替换旧的;如果您有两个相同的类型,这也意味着会出现错误。


Wil*_*Ray 5

HttpContext.Items 正如您所提到的,旨在共享短期的每个请求数据。

HttpContext.Features旨在共享各种 HTTP 功能,允许中间件创建或修改应用程序的托管管道。它已经包含了.NET 的几个特性,例如IHttpSendFileFeature.

您应该使用它HttpContext.Items来存储数据,并HttpContext.Features添加另一个中间件类可能需要的任何新 HTTP 功能。