• DefaultHttpContext


    using System.Security.Claims;
    using Microsoft.AspNetCore.Http.Features;
     
    namespace Microsoft.AspNetCore.Http;
     
    /// <summary>
    /// Encapsulates all HTTP-specific information about an individual HTTP request.
    /// </summary>
    public abstract class HttpContext
    {
        /// <summary>
        /// Gets the collection of HTTP features provided by the server and middleware available on this request.
        /// </summary>
        public abstract IFeatureCollection Features { get; }
     
        /// <summary>
        /// Gets the <see cref="HttpRequest"/> object for this request.
        /// </summary>
        public abstract HttpRequest Request { get; }
     
        /// <summary>
        /// Gets the <see cref="HttpResponse"/> object for this request.
        /// </summary>
        public abstract HttpResponse Response { get; }
     
        /// <summary>
        /// Gets information about the underlying connection for this request.
        /// </summary>
        public abstract ConnectionInfo Connection { get; }
     
        /// <summary>
        /// Gets an object that manages the establishment of WebSocket connections for this request.
        /// </summary>
        public abstract WebSocketManager WebSockets { get; }
     
        /// <summary>
        /// Gets or sets the user for this request.
        /// </summary>
        public abstract ClaimsPrincipal User { get; set; }
     
        /// <summary>
        /// Gets or sets a key/value collection that can be used to share data within the scope of this request.
        /// </summary>
        public abstract IDictionary<object, object?> Items { get; set; }
     
        /// <summary>
        /// Gets or sets the <see cref="IServiceProvider"/> that provides access to the request's service container.
        /// </summary>
        public abstract IServiceProvider RequestServices { get; set; }
     
        /// <summary>
        /// Notifies when the connection underlying this request is aborted and thus request operations should be
        /// cancelled.
        /// </summary>
        public abstract CancellationToken RequestAborted { get; set; }
     
        /// <summary>
        /// Gets or sets a unique identifier to represent this request in trace logs.
        /// </summary>
        public abstract string TraceIdentifier { get; set; }
     
        /// <summary>
        /// Gets or sets the object used to manage user session data for this request.
        /// </summary>
        public abstract ISession Session { get; set; }
     
        /// <summary>
        /// Aborts the connection underlying this request.
        /// </summary>
        public abstract void Abort();
    }
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Security.Claims;
    using Microsoft.AspNetCore.Http.Features;
    using Microsoft.AspNetCore.Http.Features.Authentication;
    using Microsoft.Extensions.DependencyInjection;
     
    namespace Microsoft.AspNetCore.Http;
     
    /// <summary>
    /// Represents an implementation of the HTTP Context class.
    /// </summary>
    public sealed class DefaultHttpContext : HttpContext
    {
        // The initial size of the feature collection when using the default constructor; based on number of common features
        // https://github.com/dotnet/aspnetcore/issues/31249
        private const int DefaultFeatureCollectionSize = 10;
     
        // Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
        private static readonly Func<IFeatureCollection, IItemsFeature> _newItemsFeature = f => new ItemsFeature();
        private static readonly Func<DefaultHttpContext, IServiceProvidersFeature> _newServiceProvidersFeature = context => new RequestServicesFeature(context, context.ServiceScopeFactory);
        private static readonly Func<IFeatureCollection, IHttpAuthenticationFeature> _newHttpAuthenticationFeature = f => new HttpAuthenticationFeature();
        private static readonly Func<IFeatureCollection, IHttpRequestLifetimeFeature> _newHttpRequestLifetimeFeature = f => new HttpRequestLifetimeFeature();
        private static readonly Func<IFeatureCollection, ISessionFeature> _newSessionFeature = f => new DefaultSessionFeature();
        private static readonly Func<IFeatureCollection, ISessionFeature?> _nullSessionFeature = f => null;
        private static readonly Func<IFeatureCollection, IHttpRequestIdentifierFeature> _newHttpRequestIdentifierFeature = f => new HttpRequestIdentifierFeature();
     
        private FeatureReferences<FeatureInterfaces> _features;
     
        private readonly DefaultHttpRequest _request;
        private readonly DefaultHttpResponse _response;
     
        private DefaultConnectionInfo? _connection;
        private DefaultWebSocketManager? _websockets;
     
        // This is field exists to make analyzing memory dumps easier.
        // https://github.com/dotnet/aspnetcore/issues/29709
        internal bool _active;
     
        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultHttpContext"/> class.
        /// </summary>
        public DefaultHttpContext()
            : this(new FeatureCollection(DefaultFeatureCollectionSize))
        {
            Features.Set<IHttpRequestFeature>(new HttpRequestFeature());
            Features.Set<IHttpResponseFeature>(new HttpResponseFeature());
            Features.Set<IHttpResponseBodyFeature>(new StreamResponseBodyFeature(Stream.Null));
        }
     
        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultHttpContext"/> class with provided features.
        /// </summary>
        /// <param name="features">Initial set of features for the <see cref="DefaultHttpContext"/>.</param>
        public DefaultHttpContext(IFeatureCollection features)
        {
            _features.Initalize(features);
            _request = new DefaultHttpRequest(this);
            _response = new DefaultHttpResponse(this);
        }
     
        /// <summary>
        /// Reinitialize  the current instant of the class with features passed in.
        /// </summary>
        /// <remarks>
        /// This method allows the consumer to re-use the <see cref="DefaultHttpContext" /> for another request, rather than having to allocate a new instance.
        /// </remarks>
        /// <param name="features">The new set of features for the <see cref="DefaultHttpContext" />.</param>
        public void Initialize(IFeatureCollection features)
        {
            var revision = features.Revision;
            _features.Initalize(features, revision);
            _request.Initialize(revision);
            _response.Initialize(revision);
            _connection?.Initialize(features, revision);
            _websockets?.Initialize(features, revision);
            _active = true;
        }
     
        /// <summary>
        /// Uninitialize all the features in the <see cref="DefaultHttpContext" />.
        /// </summary>
        public void Uninitialize()
        {
            _features = default;
            _request.Uninitialize();
            _response.Uninitialize();
            _connection?.Uninitialize();
            _websockets?.Uninitialize();
            _active = false;
        }
     
        /// <summary>
        /// Gets or set the <see cref="FormOptions" /> for this instance.
        /// </summary>
        /// <returns>
        /// <see cref="FormOptions"/>
        /// </returns>
        public FormOptions FormOptions { get; set; } = default!;
     
        /// <summary>
        /// Gets or sets the <see cref="IServiceScopeFactory" /> for this instance.
        /// </summary>
        /// <returns>
        /// <see cref="IServiceScopeFactory"/>
        /// </returns>
        public IServiceScopeFactory ServiceScopeFactory { get; set; } = default!;
     
        private IItemsFeature ItemsFeature =>
            _features.Fetch(ref _features.Cache.Items, _newItemsFeature)!;
     
        private IServiceProvidersFeature ServiceProvidersFeature =>
            _features.Fetch(ref _features.Cache.ServiceProviders, this, _newServiceProvidersFeature)!;
     
        private IHttpAuthenticationFeature HttpAuthenticationFeature =>
            _features.Fetch(ref _features.Cache.Authentication, _newHttpAuthenticationFeature)!;
     
        private IHttpRequestLifetimeFeature LifetimeFeature =>
            _features.Fetch(ref _features.Cache.Lifetime, _newHttpRequestLifetimeFeature)!;
     
        private ISessionFeature SessionFeature =>
            _features.Fetch(ref _features.Cache.Session, _newSessionFeature)!;
     
        private ISessionFeature? SessionFeatureOrNull =>
            _features.Fetch(ref _features.Cache.Session, _nullSessionFeature);
     
        private IHttpRequestIdentifierFeature RequestIdentifierFeature =>
            _features.Fetch(ref _features.Cache.RequestIdentifier, _newHttpRequestIdentifierFeature)!;
     
        /// <inheritdoc/>
        public override IFeatureCollection Features => _features.Collection ?? ContextDisposed();
     
        /// <inheritdoc/>
        public override HttpRequest Request => _request;
     
        /// <inheritdoc/>
        public override HttpResponse Response => _response;
     
        /// <inheritdoc/>
        public override ConnectionInfo Connection => _connection ?? (_connection = new DefaultConnectionInfo(Features));
     
        /// <inheritdoc/>
        public override WebSocketManager WebSockets => _websockets ?? (_websockets = new DefaultWebSocketManager(Features));
     
        /// <inheritdoc/>
        public override ClaimsPrincipal User
        {
            get
            {
                var user = HttpAuthenticationFeature.User;
                if (user == null)
                {
                    user = new ClaimsPrincipal(new ClaimsIdentity());
                    HttpAuthenticationFeature.User = user;
                }
                return user;
            }
            set { HttpAuthenticationFeature.User = value; }
        }
     
        /// <inheritdoc/>
        public override IDictionary<object, object?> Items
        {
            get { return ItemsFeature.Items; }
            set { ItemsFeature.Items = value; }
        }
     
        /// <inheritdoc/>
        public override IServiceProvider RequestServices
        {
            get { return ServiceProvidersFeature.RequestServices; }
            set { ServiceProvidersFeature.RequestServices = value; }
        }
     
        /// <inheritdoc/>
        public override CancellationToken RequestAborted
        {
            get { return LifetimeFeature.RequestAborted; }
            set { LifetimeFeature.RequestAborted = value; }
        }
     
        /// <inheritdoc/>
        public override string TraceIdentifier
        {
            get { return RequestIdentifierFeature.TraceIdentifier; }
            set { RequestIdentifierFeature.TraceIdentifier = value; }
        }
     
        /// <inheritdoc/>
        public override ISession Session
        {
            get
            {
                var feature = SessionFeatureOrNull;
                if (feature == null)
                {
                    throw new InvalidOperationException("Session has not been configured for this application " +
                        "or request.");
                }
                return feature.Session;
            }
            set
            {
                SessionFeature.Session = value;
            }
        }
     
        // This property exists because of backwards compatibility.
        // We send an anonymous object with an HttpContext property
        // via DiagnosticListener in various events throughout the pipeline. Instead
        // we just send the HttpContext to avoid extra allocations
        /// <summary>
        /// This API is used by ASP.NET Core's infrastructure and should not be used by application code.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public HttpContext HttpContext => this;
     
        /// <inheritdoc/>
        public override void Abort()
        {
            LifetimeFeature.Abort();
        }
     
        private static IFeatureCollection ContextDisposed()
        {
            ThrowContextDisposed();
            return null;
        }
     
        [DoesNotReturn]
        private static void ThrowContextDisposed()
        {
            throw new ObjectDisposedException(nameof(HttpContext), $"Request has finished and {nameof(HttpContext)} disposed.");
        }
     
        struct FeatureInterfaces
        {
            public IItemsFeature? Items;
            public IServiceProvidersFeature? ServiceProviders;
            public IHttpAuthenticationFeature? Authentication;
            public IHttpRequestLifetimeFeature? Lifetime;
            public ISessionFeature? Session;
            public IHttpRequestIdentifierFeature? RequestIdentifier;
        }
    }
  • 相关阅读:
    关于SQL Server 2005 SP2中提供的Vardecimal存储格式
    .NET平台网络编程之最佳实践 【转载】
    如果类型转换无可避免,那么应该尽可能用as运算符,而不是强制转换
    ArraySegment 的使用 【转载】
    如果不写Order By子句,会怎么样
    ToString 的几个思考
    尽量用属性(Property),而不是字段(Field)
    如何设置SQL Server服务器上面的CPU占用过高的警报
    SQL Server 2008 Replication and Filestream, are both supported together?【转载】
    Microsoft Sync Framework
  • 原文地址:https://www.cnblogs.com/htlp/p/16169198.html
Copyright © 2020-2023  润新知