HttpContext.Features 与 HttpContext.Items 在 Asp.Net Core 中的区别

20

这两个属性有什么不同?

我可以使用HttpContext.Items代替HttpContext.Features中间件之间共享数据。我唯一看到的区别是,我要为一个键告诉Items,它会给我一个对象,我需要强制转换。在Features中,这个转换可以自动完成。

它们背后还有其他东西吗?

2个回答

24
最大的区别在于 HttpContext.Items 被设计用来存储 Key-Value-Pair,而 HttpContext.Features 被设计用来存储 Type-Instance-Pair。更具体地说,HttpContext.Items 被设计用于在当前请求范围内共享项目,而 HttpContext.FeaturesIFeatureCollection 实例,绝不能像这样使用。 IFeatureCollection 接口表示 HTTP 功能的集合,例如:
  1. IAuthenticationFeature 存储原始路径基础和原始路径。
  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);
}

实现部分 (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!
    }
}

这是有意为之的设计。因为没有必要存储两个 IHttpConnectionFeature 实例或两个 ISession 实例。

虽然你可以使用 FeatureCollection 存储一些 Type-Value 对,但最好不要这样做。正如你所看到的,如果某个类型已经存在于集合中,Set<TFeature>(TFeature instance) 将简单地替换旧实例;这也意味着如果你有两个相同类型的对象,将会出现一个 bug。


1
您说 HttpContext.Items 对于每个请求而言是短暂的,那么 HttpContext.Features 的成员寿命是多久? - Mohammad Barbast
1
@MohammadBarbast,实际上,确切的生命周期与IServer接口的实现有关。事实上,即使在HttpContext之前,服务器实现本身和一些功能(如ServerAddressFeature)也是由服务器实现创建的。请参见Kestrel - itminus

9

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

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

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


1
那么 HttpContext.Features 的生命周期是多久? - Mohammad Barbast
1
@MohammadBarbast 它是按请求处理的,与 HttpContext.Items 相同。关于这个主题还有更多信息,请参阅 此 GitHub 问题 - Will Ray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接