diff --git a/samples/CoreApp/SessionExampleExtensions.cs b/samples/CoreApp/SessionExampleExtensions.cs index 3aef3a2442..6c848261f4 100644 --- a/samples/CoreApp/SessionExampleExtensions.cs +++ b/samples/CoreApp/SessionExampleExtensions.cs @@ -54,7 +54,7 @@ static void SetValue(HttpContext context, byte[] data) builder.MapGet("/count", (HttpContextCore ctx) => { - var context = (HttpContext)ctx; + var context = ctx.AsSystemWeb(); if (context.Session!["callCount"] is not int count) { @@ -69,7 +69,7 @@ static void SetValue(HttpContext context, byte[] data) builder.MapGet("/item", (HttpContextCore ctx) => { - var context = (HttpContext)ctx; + var context = ctx.AsSystemWeb(); var result = context.Session!["item"]; context.Session!["item"] = default(int); diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/Features/HttpApplicationFeature.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/Features/HttpApplicationFeature.cs index c5d7810914..87ad5463b3 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/Features/HttpApplicationFeature.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/Features/HttpApplicationFeature.cs @@ -41,7 +41,7 @@ public HttpApplicationFeature(HttpContextCore context, IHttpResponseEndFeature p private HttpApplication InitializeApplication(HttpContextCore context) { var app = _pool.Get(); - app.Context = context; + app.Context = context.AsSystemWeb(); _contextOrApplication = app; return app; } diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationExtensions.cs index 3fa978920a..f330229a50 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationExtensions.cs @@ -185,7 +185,7 @@ private void CallStartup(IServiceProvider services) app.Context = new DefaultHttpContext { RequestServices = scope.ServiceProvider, - }; + }.AsSystemWeb(); try { diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationVaryBy.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationVaryBy.cs index ef3987667a..8b2e0e1f0d 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationVaryBy.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/HttpApplication/HttpApplicationVaryBy.cs @@ -42,7 +42,7 @@ public static void AddHttpApplicationVaryByCustom(this OutputCachePolicyBuilder { builder.VaryByValue(context => { - var value = context.Features.Get()?.Application.GetVaryByCustomString(context, custom); + var value = context.Features.Get()?.Application.GetVaryByCustomString(context.AsSystemWeb(), custom); return new(custom, value ?? string.Empty); }); @@ -79,7 +79,7 @@ ValueTask IOutputCachePolicy.CacheRequestAsync(OutputCacheContext context, Cance { foreach (var key in _keySelector(context.HttpContext)) { - context.CacheVaryByRules.VaryByValues[key] = app.GetVaryByCustomString(context.HttpContext, key) ?? string.Empty; + context.CacheVaryByRules.VaryByValues[key] = app.GetVaryByCustomString(context.HttpContext.AsSystemWeb(), key) ?? string.Empty; } } diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SessionEventsMiddleware.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SessionEventsMiddleware.cs index 2f7a28c52a..b42b89c5da 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SessionEventsMiddleware.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SessionEventsMiddleware.cs @@ -19,7 +19,7 @@ public SessionEventsMiddleware(RequestDelegate next) public async Task InvokeAsync(HttpContextCore context) { var app = context.Features.GetRequired(); - var session = context.GetAdapter().Session; + var session = context.AsSystemWeb().Session; if (session is { IsNewSession: true }) { diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SetDefaultResponseHeadersMiddleware.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SetDefaultResponseHeadersMiddleware.cs index 74015003f9..393916f4d9 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SetDefaultResponseHeadersMiddleware.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.CoreServices/SetDefaultResponseHeadersMiddleware.cs @@ -22,7 +22,7 @@ public Task InvokeAsync(HttpContext context) var context = (HttpContext)state; WriteDefaultContentType(context); - context.Response.GetAdapter().Cache.UpdateHeaders(); + context.Response.AsSystemWeb().Cache.UpdateHeaders(); return Task.CompletedTask; }, context); diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/FeatureCollectionExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/FeatureCollectionExtensions.cs new file mode 100644 index 0000000000..2aa8095292 --- /dev/null +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/FeatureCollectionExtensions.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.AspNetCore.Http.Features; + +namespace Microsoft.AspNetCore.SystemWebAdapters; + +internal static class FeatureCollectionExtensions +{ + internal static TFeature GetRequired(this IFeatureCollection features) + { + if (features.Get() is TFeature feature) + { + return feature; + } + + throw new InvalidOperationException($"Feature {typeof(TFeature)} is not available"); + } +} diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedApis.txt b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedApis.txt index 439e74f95e..758be16f34 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedApis.txt +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Generated/ExcludedApis.txt @@ -12,6 +12,7 @@ M:System.Web.HttpRequestBase.op_Implicit(Microsoft.AspNetCore.Http.HttpRequest)~ T:Microsoft.AspNetCore.SystemWebAdapters.SessionState.ISessionState T:Microsoft.AspNetCore.SystemWebAdapters.SystemWebAdaptersOptions +T:Microsoft.AspNetCore.SystemWebAdapters.SystemWebAdaptersConversionExtensions # We manually type forward this only for .NET 4.7.2+ T:System.Web.SameSiteMode diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCachePolicy.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCachePolicy.cs index f1978d426e..2909da721c 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCachePolicy.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCachePolicy.cs @@ -49,7 +49,7 @@ private void UpdateCacheControl(CacheControlHeaderValue cacheControl) cacheControl.NoCache = GetCacheability() == HttpCacheability.NoCache; } - private ResponseHeaders Headers => _context.GetAdapter().Response.TypedHeaders; + private ResponseHeaders Headers => _context.AsSystemWeb().Response.TypedHeaders; public HttpCacheVaryByHeaders VaryByHeaders => _varyByHeaders ??= new(); diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContext.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContext.cs index 76f30ebedd..b6e29a0728 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContext.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContext.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Http.Features.Authentication; using Microsoft.AspNetCore.SystemWebAdapters; using Microsoft.AspNetCore.SystemWebAdapters.Features; +using Microsoft.AspNetCore.SystemWebAdapters.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -21,8 +22,6 @@ public class HttpContext : IServiceProvider { private static readonly HttpContextAccessor _accessor = new(); - private readonly HttpContextCore _context; - private HttpRequest? _request; private HttpResponse? _response; private HttpServerUtility? _server; @@ -31,74 +30,88 @@ public class HttpContext : IServiceProvider public static HttpContext? Current { - get => _accessor.HttpContext; - set => _accessor.HttpContext = value; + get => _accessor.HttpContext?.AsSystemWeb(); + set => _accessor.HttpContext = value?.AsAspNetCore(); } internal HttpContext(HttpContextCore context) { - _context = context ?? throw new ArgumentNullException(nameof(context)); + Context = context ?? throw new ArgumentNullException(nameof(context)); } - public HttpRequest Request => _request ??= new(_context.Request); + internal HttpContextCore Context { get; } + + public HttpRequest Request => _request ??= new(Context.Request); - public HttpResponse Response => _response ??= new(_context.Response); + public HttpResponse Response => _response ??= new(Context.Response); - public IDictionary Items => _items ??= _context.Items.AsNonGeneric(); + public IDictionary Items + { + get + { + if (_items is null) + { + var items = Context.Items; + _items = items is IDictionary d ? d : new NonGenericDictionaryWrapper(items); + } + + return _items; + } + } - public HttpServerUtility Server => _server ??= new(_context); + public HttpServerUtility Server => _server ??= new(Context); - public TraceContext Trace => _trace ??= new(_context); + public TraceContext Trace => _trace ??= new(Context); - public Exception? Error => _context.Features.Get()?.Exceptions is [{ } error, ..] ? error : null; + public Exception? Error => Context.Features.Get()?.Exceptions is [{ } error, ..] ? error : null; [SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = Constants.ApiFromAspNet)] - public Exception[] AllErrors => _context.Features.Get()?.Exceptions.ToArray() ?? Array.Empty(); + public Exception[] AllErrors => Context.Features.Get()?.Exceptions.ToArray() ?? Array.Empty(); - public void ClearError() => _context.Features.Get()?.Clear(); + public void ClearError() => Context.Features.Get()?.Clear(); - public void AddError(Exception ex) => _context.Features.Get()?.Add(ex); + public void AddError(Exception ex) => Context.Features.Get()?.Add(ex); - public RequestNotification CurrentNotification => _context.Features.GetRequired().CurrentNotification; + public RequestNotification CurrentNotification => Context.Features.GetRequired().CurrentNotification; - public bool IsPostNotification => _context.Features.GetRequired().IsPostNotification; + public bool IsPostNotification => Context.Features.GetRequired().IsPostNotification; - public HttpApplication ApplicationInstance => _context.Features.GetRequired().Application; + public HttpApplication ApplicationInstance => Context.Features.GetRequired().Application; public HttpApplicationState Application => ApplicationInstance.Application; - public Cache Cache => _context.RequestServices.GetRequiredService(); + public Cache Cache => Context.RequestServices.GetRequiredService(); /// /// Gets whether the current request is running in the development environment. /// - public bool IsDebuggingEnabled => _context.RequestServices.GetRequiredService().IsDevelopment(); + public bool IsDebuggingEnabled => Context.RequestServices.GetRequiredService().IsDevelopment(); public IPrincipal User { - get => _context.Features.Get()?.User ?? _context.User; + get => Context.Features.Get()?.User ?? Context.User; set { - if (_context.Features.Get() is { } feature) + if (Context.Features.Get() is { } feature) { feature.User = value; } else { - var newFeature = new PrincipalUserFeature(_context) { User = value }; + var newFeature = new PrincipalUserFeature(Context) { User = value }; - _context.Features.Set(newFeature); - _context.Features.Set(newFeature); + Context.Features.Set(newFeature); + Context.Features.Set(newFeature); } } } - public HttpSessionState? Session => _context.Features.Get()?.Session; + public HttpSessionState? Session => Context.Features.Get()?.Session; public void SetSessionStateBehavior(SessionStateBehavior sessionStateBehavior) - => _context.Features.GetRequired().Behavior = sessionStateBehavior; + => Context.Features.GetRequired().Behavior = sessionStateBehavior; - public DateTime Timestamp => _context.Features.GetRequired().Timestamp.DateTime; + public DateTime Timestamp => Context.Features.GetRequired().Timestamp.DateTime; public void RewritePath(string path) => RewritePath(path, true); @@ -128,7 +141,7 @@ public void RewritePath(string filePath, string pathInfo, string? queryString) => RewritePath(filePath, pathInfo, queryString, false); public void RewritePath(string filePath, string pathInfo, string? queryString, bool setClientFilePath) - => _context.Features.GetRequired().Rewrite(filePath, pathInfo, queryString, setClientFilePath); + => Context.Features.GetRequired().Rewrite(filePath, pathInfo, queryString, setClientFilePath); [SuppressMessage("Design", "CA1033:Interface methods should be callable by child types", Justification = Constants.ApiFromAspNet)] object? IServiceProvider.GetService(Type service) @@ -156,15 +169,15 @@ public void RewritePath(string filePath, string pathInfo, string? queryString, b public ISubscriptionToken DisposeOnPipelineCompleted(IDisposable target) { var token = new DisposeOnPipelineSubscriptionToken(target); - _context.Response.RegisterForDispose(token); + Context.Response.RegisterForDispose(token); return token; } [return: NotNullIfNotNull(nameof(context))] - public static implicit operator HttpContext?(HttpContextCore? context) => context?.GetAdapter(); + public static implicit operator HttpContext?(HttpContextCore? context) => context?.AsSystemWeb(); [return: NotNullIfNotNull(nameof(context))] - public static implicit operator HttpContextCore?(HttpContext? context) => context?._context; + public static implicit operator HttpContextCore?(HttpContext? context) => context?.AsAspNetCore(); private sealed class DisposeOnPipelineSubscriptionToken : ISubscriptionToken, IDisposable { diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContextBase.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContextBase.cs index 0ac23f7165..228a0fdcdb 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContextBase.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpContextBase.cs @@ -56,9 +56,6 @@ public virtual IPrincipal User public virtual object? GetService(Type serviceType) => throw new NotImplementedException(); - [return: NotNullIfNotNull(nameof(context))] - public static implicit operator HttpContextBase?(HttpContextCore? context) => context?.GetAdapterBase(); - public virtual Caching.Cache Cache => throw new NotImplementedException(); public virtual void RewritePath(string path) => throw new NotImplementedException(); @@ -70,5 +67,8 @@ public virtual IPrincipal User public virtual void RewritePath(string filePath, string pathInfo, string? queryString, bool setClientFilePath) => throw new NotImplementedException(); public virtual void SetSessionStateBehavior(SessionStateBehavior sessionStateBehavior) => throw new NotImplementedException(); + + [return: NotNullIfNotNull(nameof(context))] + public static implicit operator HttpContextBase?(HttpContextCore? context) => context?.AsSystemWebBase(); } } diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCookieCollection.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCookieCollection.cs index af44d68df6..b9e4dbe2cc 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCookieCollection.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpCookieCollection.cs @@ -29,10 +29,10 @@ internal HttpCookieCollection(IRequestCookieCollection cookies) internal HttpCookieCollection(HttpResponse response) { - response.UnwrapAdapter().OnStarting(static state => + response.AsAspNetCore().OnStarting(static state => { var response = (HttpResponse)state; - var headers = response.UnwrapAdapter().Headers; + var headers = response.AsAspNetCore().Headers; var isShareable = false; for (var i = 0; i < response.Cookies.Count; i++) @@ -54,7 +54,7 @@ internal HttpCookieCollection(HttpResponse response) // Additionally, we should not set this header during an SSL request, as certain versions // of IE don't handle it properly and simply refuse to render the page. More info: // http://blogs.msdn.com/b/ieinternals/archive/2009/10/02/internet-explorer-cannot-download-over-https-when-no-cache.aspx - if (!isShareable && !response.UnwrapAdapter().HttpContext.Request.IsHttps && response.TypedHeaders.CacheControl is { Public: true } cacheControl) + if (!isShareable && !response.AsAspNetCore().HttpContext.Request.IsHttps && response.TypedHeaders.CacheControl is { Public: true } cacheControl) { cacheControl.NoCache = true; cacheControl.NoCacheHeaders.Add(HeaderNames.SetCookie); diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequest.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequest.cs index c07fcbcd4e..a2931aaca1 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequest.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequest.cs @@ -23,8 +23,6 @@ namespace System.Web { public class HttpRequest { - private readonly HttpRequestCore _request; - private RequestHeaders? _typedHeaders; private string[]? _userLanguages; private string[]? _acceptTypes; @@ -39,37 +37,39 @@ public class HttpRequest internal HttpRequest(HttpRequestCore request) { - _request = request; + Request = request; } - internal RequestHeaders TypedHeaders => _typedHeaders ??= new(_request.Headers); + internal HttpRequestCore Request { get; } + + internal RequestHeaders TypedHeaders => _typedHeaders ??= new(Request.Headers); - public string Path => _request.HttpContext.Features.GetRequired().Path; + public string Path => Request.HttpContext.Features.GetRequired().Path; - public string PathInfo => _request.HttpContext.Features.GetRequired().PathInfo; + public string PathInfo => Request.HttpContext.Features.GetRequired().PathInfo; - public string FilePath => _request.HttpContext.Features.GetRequired().FilePath; + public string FilePath => Request.HttpContext.Features.GetRequired().FilePath; [SuppressMessage("Design", "CA1056:URI-like properties should not be strings", Justification = Constants.ApiFromAspNet)] - public string RawUrl => _request.HttpContext.Features.GetRequired().RawUrl; + public string RawUrl => Request.HttpContext.Features.GetRequired().RawUrl; - public string? PhysicalPath => _request.HttpContext.Features.GetRequired().PhysicalPath; + public string? PhysicalPath => Request.HttpContext.Features.GetRequired().PhysicalPath; - public string CurrentExecutionFilePath => _request.HttpContext.Features.GetRequired().CurrentExecutionFilePath; + public string CurrentExecutionFilePath => Request.HttpContext.Features.GetRequired().CurrentExecutionFilePath; - public NameValueCollection Headers => _headers ??= _request.Headers.ToNameValueCollection(); + public NameValueCollection Headers => _headers ??= Request.Headers.ToNameValueCollection(); - public Uri Url => new(_request.GetEncodedUrl()); + public Uri Url => new(Request.GetEncodedUrl()); - public ReadEntityBodyMode ReadEntityBodyMode => _request.HttpContext.Features.GetRequired().Mode; + public ReadEntityBodyMode ReadEntityBodyMode => Request.HttpContext.Features.GetRequired().Mode; - public Stream GetBufferlessInputStream() => _request.HttpContext.Features.GetRequired().GetBufferlessInputStream(); + public Stream GetBufferlessInputStream() => Request.HttpContext.Features.GetRequired().GetBufferlessInputStream(); - public Stream GetBufferedInputStream() => _request.HttpContext.Features.GetRequired().GetBufferedInputStream(); + public Stream GetBufferedInputStream() => Request.HttpContext.Features.GetRequired().GetBufferedInputStream(); - public string HttpMethod => _request.Method; + public string HttpMethod => Request.Method; - public string? UserHostAddress => _request.HttpContext.Connection.RemoteIpAddress?.ToString(); + public string? UserHostAddress => Request.HttpContext.Connection.RemoteIpAddress?.ToString(); [SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = Constants.ApiFromAspNet)] public string[] UserLanguages @@ -111,17 +111,17 @@ public string[] UserLanguages } } - public string? UserAgent => _request.Headers[HeaderNames.UserAgent]; + public string? UserAgent => Request.Headers[HeaderNames.UserAgent]; public string RequestType => HttpMethod; - public NameValueCollection Form => _form ??= _request.HasFormContentType ? _request.Form.ToNameValueCollection() : StringValuesReadOnlyDictionaryNameValueCollection.Empty; + public NameValueCollection Form => _form ??= Request.HasFormContentType ? Request.Form.ToNameValueCollection() : StringValuesReadOnlyDictionaryNameValueCollection.Empty; - public HttpCookieCollection Cookies => _cookies ??= new(_request.Cookies); + public HttpCookieCollection Cookies => _cookies ??= new(Request.Cookies); - public HttpFileCollection Files => _files ??= _request.HasFormContentType ? new(_request.Form.Files) : HttpFileCollection.Empty; + public HttpFileCollection Files => _files ??= Request.HasFormContentType ? new(Request.Form.Files) : HttpFileCollection.Empty; - public int ContentLength => (int)(_request.ContentLength ?? 0); + public int ContentLength => (int)(Request.ContentLength ?? 0); [SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = Constants.ApiFromAspNet)] public string[] AcceptTypes @@ -156,23 +156,23 @@ public string[] AcceptTypes public string? ContentType { - get => _request.ContentType; - set => _request.ContentType = value; + get => Request.ContentType; + set => Request.ContentType = value; } - public Stream InputStream => _request.HttpContext.Features.GetRequired().InputStream; + public Stream InputStream => Request.HttpContext.Features.GetRequired().InputStream; - public NameValueCollection ServerVariables => _serverVariables ??= _request.HttpContext.Features.GetRequired().ToNameValueCollection(); + public NameValueCollection ServerVariables => _serverVariables ??= Request.HttpContext.Features.GetRequired().ToNameValueCollection(); - public bool IsSecureConnection => _request.IsHttps; + public bool IsSecureConnection => Request.IsHttps; - public NameValueCollection QueryString => _query ??= _request.Query.ToNameValueCollection(); + public NameValueCollection QueryString => _query ??= Request.Query.ToNameValueCollection(); public bool IsLocal { get { - var connectionInfo = _request.HttpContext.Connection; + var connectionInfo = Request.HttpContext.Connection; // If unknown, assume not local if (connectionInfo.RemoteIpAddress is null) @@ -192,7 +192,7 @@ public bool IsLocal public string AppRelativeCurrentExecutionFilePath => $"~{FilePath}"; - public string ApplicationPath => _request.HttpContext.RequestServices.GetRequiredService>().Value.AppDomainAppVirtualPath; + public string ApplicationPath => Request.HttpContext.RequestServices.GetRequiredService>().Value.AppDomainAppVirtualPath; public Uri? UrlReferrer => TypedHeaders.Referer; @@ -200,17 +200,17 @@ public bool IsLocal public bool IsAuthenticated => LogonUserIdentity?.IsAuthenticated ?? false; - public IIdentity? LogonUserIdentity => _request.HttpContext.User.Identity; + public IIdentity? LogonUserIdentity => Request.HttpContext.User.Identity; public Encoding? ContentEncoding => TypedHeaders.ContentType?.Encoding; - public string? UserHostName => _request.HttpContext.Connection.RemoteIpAddress?.ToString(); + public string? UserHostName => Request.HttpContext.Connection.RemoteIpAddress?.ToString(); - public HttpBrowserCapabilities Browser => _browser ??= new(_request.HttpContext); + public HttpBrowserCapabilities Browser => _browser ??= new(Request.HttpContext); public string? this[string key] => Params[key]; - public NameValueCollection Params => _params ??= new ParamsCollection(_request); + public NameValueCollection Params => _params ??= new ParamsCollection(Request); public byte[] BinaryRead(int count) { @@ -257,12 +257,12 @@ public void SaveAs(string filename, bool includeHeaders) w.Write(Path); // Includes the leading '?' if non-empty - w.Write(_request.QueryString); + w.Write(Request.QueryString); w.Write(" "); - w.WriteLine(_request.Protocol); + w.WriteLine(Request.Protocol); - foreach (var header in _request.Headers) + foreach (var header in Request.Headers) { w.Write(header.Key); w.Write(": "); @@ -287,13 +287,13 @@ private static void WriteTo(Stream source, Stream destination) source.Position = currentPosition; } - public void Abort() => _request.HttpContext.Abort(); + public void Abort() => Request.HttpContext.Abort(); [return: NotNullIfNotNull(nameof(request))] - public static implicit operator HttpRequest?(HttpRequestCore? request) => request.GetAdapter(); + public static implicit operator HttpRequest?(HttpRequestCore? request) => request?.HttpContext.AsSystemWeb().Request; [return: NotNullIfNotNull(nameof(request))] - public static implicit operator HttpRequestCore?(HttpRequest? request) => request?._request; + public static implicit operator HttpRequestCore?(HttpRequest? request) => request?.AsAspNetCore(); private class StringWithQualityHeaderValueComparer : IComparer { diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequestBase.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequestBase.cs index 8063fd7ed8..31bd11fe95 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequestBase.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpRequestBase.cs @@ -93,6 +93,6 @@ public virtual string? ContentType public virtual void Abort() => throw new NotImplementedException(); [return: NotNullIfNotNull(nameof(request))] - public static implicit operator HttpRequestBase?(HttpRequestCore? request) => request?.GetAdapterBase(); + public static implicit operator HttpRequestBase?(HttpRequestCore? request) => request?.HttpContext.AsSystemWebBase().Request; } } diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponse.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponse.cs index c0873f6251..f741a7997f 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponse.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponse.cs @@ -25,8 +25,6 @@ public class HttpResponse { private const string NoContentTypeMessage = "No content type declared"; - private readonly HttpResponseCore _response; - private NameValueCollection? _headers; private ResponseHeaders? _typedHeaders; private TextWriter? _writer; @@ -35,15 +33,17 @@ public class HttpResponse internal HttpResponse(HttpResponseCore response) { - _response = response; + Response = response; } - internal ResponseHeaders TypedHeaders => _typedHeaders ??= new(_response.Headers); + internal HttpResponseCore Response { get; } + + internal ResponseHeaders TypedHeaders => _typedHeaders ??= new(Response.Headers); public int StatusCode { - get => _response.StatusCode; - set => _response.StatusCode = value; + get => Response.StatusCode; + set => Response.StatusCode = value; } public int SubStatusCode { get; set; } @@ -51,15 +51,15 @@ public int StatusCode [AllowNull] public string StatusDescription { - get => _response.HttpContext.Features.GetRequired().ReasonPhrase ?? ReasonPhrases.GetReasonPhrase(_response.StatusCode); - set => _response.HttpContext.Features.GetRequired().ReasonPhrase = value; + get => Response.HttpContext.Features.GetRequired().ReasonPhrase ?? ReasonPhrases.GetReasonPhrase(Response.StatusCode); + set => Response.HttpContext.Features.GetRequired().ReasonPhrase = value; } - public NameValueCollection Headers => _headers ??= _response.Headers.ToNameValueCollection(); + public NameValueCollection Headers => _headers ??= Response.Headers.ToNameValueCollection(); public void ClearHeaders() { - _response.Headers.Clear(); + Response.Headers.Clear(); _cookies?.Clear(); StatusCode = 200; @@ -71,19 +71,19 @@ public void ClearHeaders() public bool TrySkipIisCustomErrors { - get => _response.HttpContext.Features.GetRequired().Enabled; - set => _response.HttpContext.Features.GetRequired().Enabled = value; + get => Response.HttpContext.Features.GetRequired().Enabled; + set => Response.HttpContext.Features.GetRequired().Enabled = value; } - public bool BufferOutput => _response.HttpContext.Features.GetRequired().IsEnabled; + public bool BufferOutput => Response.HttpContext.Features.GetRequired().IsEnabled; - public Stream OutputStream => _response.Body; + public Stream OutputStream => Response.Body; [AllowNull] public Stream Filter { - get => _response.HttpContext.Features.GetRequired().Filter; - set => _response.HttpContext.Features.GetRequired().Filter = value; + get => Response.HttpContext.Features.GetRequired().Filter; + set => Response.HttpContext.Features.GetRequired().Filter = value; } public HttpCookieCollection Cookies => _cookies ??= new(this); @@ -92,8 +92,8 @@ public Stream Filter public bool SuppressContent { - get => _response.HttpContext.Features.GetRequired().SuppressContent; - set => _response.HttpContext.Features.GetRequired().SuppressContent = value; + get => Response.HttpContext.Features.GetRequired().SuppressContent; + set => Response.HttpContext.Features.GetRequired().SuppressContent = value; } public Encoding ContentEncoding @@ -162,7 +162,7 @@ public TextWriter Output if (_writer is null) { // No need to dispose the stream writer as it doesn't own the stream and autoflushes - _writer = new StreamWriter(_response.Body, ContentEncoding, leaveOpen: true) + _writer = new StreamWriter(Response.Body, ContentEncoding, leaveOpen: true) { AutoFlush = true, }; @@ -174,21 +174,21 @@ public TextWriter Output set => _writer = value; } - public bool IsClientConnected => !_response.HttpContext.RequestAborted.IsCancellationRequested; + public bool IsClientConnected => !Response.HttpContext.RequestAborted.IsCancellationRequested; public void AddHeader(string name, string value) => AppendHeader(name, value); - public void AppendHeader(string name, string value) => _response.Headers.Append(name, value); + public void AppendHeader(string name, string value) => Response.Headers.Append(name, value); public bool HeadersWritten { - get => _response.HasStarted; + get => Response.HasStarted; } public string? RedirectLocation { - get => _response.Headers.Location; - set => _response.Headers.Location = value; + get => Response.Headers.Location; + set => Response.Headers.Location = value; } public bool IsRequestBeingRedirected => StatusCode is >= 300 and < 400; @@ -210,7 +210,7 @@ private void Redirect(string url, bool endResponse, bool permanent) Clear(); var resolved = ResolvePath(url); - _response.Redirect(resolved, permanent); + Response.Redirect(resolved, permanent); ContentType = "text/html"; @@ -226,7 +226,7 @@ private void Redirect(string url, bool endResponse, bool permanent) } } - public HttpCachePolicy Cache => _cache ??= new(_response.HttpContext); + public HttpCachePolicy Cache => _cache ??= new(Response.HttpContext); private string ResolvePath(string url) { @@ -240,7 +240,7 @@ private string ResolvePath(string url) return url; } - var vdir = _response.HttpContext.RequestServices.GetRequiredService>().Value.AppDomainAppVirtualPath; + var vdir = Response.HttpContext.RequestServices.GetRequiredService>().Value.AppDomainAppVirtualPath; var sb = new StringBuilder(url, 1, url.Length - 1, url.Length + vdir.Length); @@ -257,11 +257,11 @@ private string ResolvePath(string url) public void SetCookie(HttpCookie cookie) => Cookies.Set(cookie); - public void Flush() => _response.Body.Flush(); + public void Flush() => Response.Body.Flush(); - public Task FlushAsync() => _response.Body.FlushAsync(_response.HttpContext.RequestAborted); + public Task FlushAsync() => Response.Body.FlushAsync(Response.HttpContext.RequestAborted); - public void End() => _response.HttpContext.Features.GetRequired().EndAsync().GetAwaiter().GetResult(); + public void End() => Response.HttpContext.Features.GetRequired().EndAsync().GetAwaiter().GetResult(); public void Write(char ch) => Output.Write(ch); @@ -278,11 +278,11 @@ public void BinaryWrite(byte[] buffer) public void Clear() { - _response.Clear(); + Response.Clear(); ClearContent(); } - public void ClearContent() => _response.HttpContext.Features.GetRequired().ClearContent(); + public void ClearContent() => Response.HttpContext.Features.GetRequired().ClearContent(); public void WriteFile(string filename) => TransmitFile(filename); @@ -291,12 +291,12 @@ public void TransmitFile(string filename) => TransmitFile(filename, 0, -1); public void TransmitFile(string filename, long offset, long length) - => _response.SendFileAsync(filename, offset, length >= 0 ? length : null).GetAwaiter().GetResult(); + => Response.SendFileAsync(filename, offset, length >= 0 ? length : null).GetAwaiter().GetResult(); [return: NotNullIfNotNull(nameof(response))] - public static implicit operator HttpResponse?(HttpResponseCore? response) => response?.GetAdapter(); + public static implicit operator HttpResponse?(HttpResponseCore? response) => response?.HttpContext.AsSystemWeb().Response; [return: NotNullIfNotNull(nameof(response))] - public static implicit operator HttpResponseCore?(HttpResponse? response) => response?._response; + public static implicit operator HttpResponseCore?(HttpResponse? response) => response?.AsAspNetCore(); } } diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseBase.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseBase.cs index 1b4d2ae1d8..c0e56891d7 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseBase.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpResponseBase.cs @@ -130,6 +130,6 @@ public virtual Stream Filter public virtual void TransmitFile(string filename, long offset, long length) => throw new NotImplementedException(); [return: NotNullIfNotNull(nameof(response))] - public static implicit operator HttpResponseBase?(HttpResponseCore? response) => response?.GetAdapterBase(); + public static implicit operator HttpResponseBase?(HttpResponseCore? response) => response?.HttpContext.AsSystemWebBase().Response; } } diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpServerUtility.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpServerUtility.cs index e7fbe9c12a..58bf66b68a 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/HttpServerUtility.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/HttpServerUtility.cs @@ -27,9 +27,9 @@ internal HttpServerUtility(HttpContextCore context) public string MapPath(string? path) => _context.RequestServices.GetRequiredService().MapPath(_context.Request.Path, path); - public Exception? GetLastError() => _context.GetAdapter().Error; + public Exception? GetLastError() => _context.AsSystemWeb().Error; - public void ClearError() => _context.GetAdapter().ClearError(); + public void ClearError() => _context.AsSystemWeb().ClearError(); /// /// This method is similar to but handles the trailing character that @@ -113,7 +113,7 @@ public static string UrlTokenEncode(byte[] input) public void Transfer(string path, bool preserveForm) { _context.Features.GetRequired().Transfer(path, preserveForm); - _context.Response.GetAdapter().End(); + _context.Response.AsSystemWeb().End(); } [Obsolete(Constants.TransferRequest.Message, DiagnosticId = Constants.TransferRequest.DiagnosticId)] diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/NonGenericDictionaryWrapper.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/NonGenericDictionaryWrapper.cs index d933d5fa4d..ac3b98ce9b 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/NonGenericDictionaryWrapper.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/Internal/NonGenericDictionaryWrapper.cs @@ -36,7 +36,7 @@ public ICollection Keys { if (_keys is null) { - _keys = _original.Keys.AsNonGeneric(); + _keys = AsNonGeneric(_original.Keys); } return _keys; @@ -49,7 +49,7 @@ public ICollection Values { if (_values is null) { - _values = _original.Values.AsNonGeneric(); + _values = AsNonGeneric(_original.Values); } return _values; @@ -78,6 +78,9 @@ public void CopyTo(Array array, int index) } } + private static ICollection AsNonGeneric(ICollection collection) + => collection is ICollection c ? c : new NonGenericCollectionWrapper(collection); + public void Remove(object key) => _original.Remove(key); public IDictionaryEnumerator GetEnumerator() => new DictionaryEnumerator(_original); diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/InternalSystemWebExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/InternalSystemWebExtensions.cs deleted file mode 100644 index 334d142219..0000000000 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/InternalSystemWebExtensions.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Web; -using Microsoft.AspNetCore.Http.Features; -using Microsoft.AspNetCore.SystemWebAdapters.Internal; - -namespace Microsoft.AspNetCore.SystemWebAdapters; - -internal static class InternalSystemWebExtensions -{ - [return: NotNullIfNotNull(nameof(request))] - internal static HttpRequest? GetAdapter(this HttpRequestCore? request) - => request?.HttpContext.GetAdapter().Request; - - [return: NotNullIfNotNull(nameof(request))] - internal static HttpRequestBase? GetAdapterBase(this HttpRequestCore? request) - => request?.HttpContext.GetAdapterBase().Request; - - [return: NotNullIfNotNull(nameof(request))] - internal static HttpRequestCore? UnwrapAdapter(this HttpRequest? request) => request; - - [return: NotNullIfNotNull(nameof(response))] - internal static HttpResponse? GetAdapter(this HttpResponseCore? response) - => response?.HttpContext.GetAdapter().Response; - - [return: NotNullIfNotNull("request")] - internal static HttpResponseBase? GetAdapterBase(this HttpResponseCore? response) - => response?.HttpContext.GetAdapterBase().Response; - - [return: NotNullIfNotNull(nameof(response))] - internal static HttpResponseCore? UnwrapAdapter(this HttpResponse? response) => response; - - internal static IDictionary AsNonGeneric(this IDictionary dictionary) - => dictionary is IDictionary d ? d : new NonGenericDictionaryWrapper(dictionary); - - internal static ICollection AsNonGeneric(this ICollection collection) - => collection is ICollection c ? c : new NonGenericCollectionWrapper(collection); - - [return: NotNullIfNotNull(nameof(context))] - internal static HttpContext? GetAdapter(this HttpContextCore? context) - { - if (context is null) - { - return null; - } - - var result = context.Features.Get(); - - if (result is null) - { - result = new(context); - context.Features.Set(result); - } - - return result; - } - - [return: NotNullIfNotNull(nameof(context))] - internal static HttpContextCore? UnwrapAdapter(this HttpContext? context) => context; - - [return: NotNullIfNotNull(nameof(context))] - internal static HttpContextBase? GetAdapterBase(this HttpContextCore? context) - { - if (context is null) - { - return null; - } - - var result = context.Features.Get(); - - if (result is null) - { - result = new HttpContextWrapper(context); - context.Features.Set(result); - } - - return result!; - } - - internal static TFeature GetRequired(this IFeatureCollection features) - { - if (features.Get() is TFeature feature) - { - return feature; - } - - throw new InvalidOperationException($"Feature {typeof(TFeature)} is not available"); - } -} diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/SystemWebAdaptersConversionExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/SystemWebAdaptersConversionExtensions.cs new file mode 100644 index 0000000000..c555c73171 --- /dev/null +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/SystemWebAdaptersConversionExtensions.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Web; + +namespace Microsoft.AspNetCore.SystemWebAdapters; + +public static class SystemWebAdaptersConversionExtensions +{ + /// + /// Gets a representation of the as an . For any given + /// instance of , only a single will be returned. + /// + public static HttpContext AsSystemWeb(this HttpContextCore context) + { + ArgumentNullException.ThrowIfNull(context); + + var result = context.Features.Get(); + + if (result is null) + { + result = new(context); + context.Features.Set(result); + } + + return result; + } + + /// + /// Gets a representation of the as an . For any given + /// instance of , only a single will be returned. + /// + public static HttpRequest AsSystemWeb(this HttpRequestCore request) + { + ArgumentNullException.ThrowIfNull(request); + + return request.HttpContext.AsSystemWeb().Request; + } + + /// + /// Gets a representation of the as an . For any given + /// instance of , only a single will be returned. + /// + public static HttpResponse AsSystemWeb(this HttpResponseCore response) + { + ArgumentNullException.ThrowIfNull(response); + + return response.HttpContext.AsSystemWeb().Response; + } + + /// + /// Gets a representation of the as an . For any given + /// instance of , only a single will be returned. + /// + public static HttpContextCore AsAspNetCore(this HttpContext context) + { + ArgumentNullException.ThrowIfNull(context); + + return context.Context; + } + + /// + /// Gets a representation of the as an . For any given + /// instance of , only a single will be returned. + /// + public static HttpRequestCore AsAspNetCore(this HttpRequest request) + { + ArgumentNullException.ThrowIfNull(request); + + return request.Request; + } + + /// + /// Gets a representation of the as an . For any given + /// instance of , only a single will be returned. + /// + public static HttpResponseCore AsAspNetCore(this HttpResponse response) + { + ArgumentNullException.ThrowIfNull(response); + + return response.Response; + } + + internal static HttpContextBase AsSystemWebBase(this HttpContextCore context) + { + ArgumentNullException.ThrowIfNull(context); + + var result = context.Features.Get(); + + if (result is null) + { + result = new HttpContextWrapper(context.AsSystemWeb()); + context.Features.Set(result); + } + + return result; + } +} diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/TraceContext.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/TraceContext.cs index f82606de3f..401511a512 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/TraceContext.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/TraceContext.cs @@ -10,9 +10,9 @@ public sealed class TraceContext { private readonly ITraceContext? _context; - internal TraceContext(HttpContext context) + internal TraceContext(HttpContextCore context) { - _context = context.UnwrapAdapter().RequestServices.GetService(); + _context = context.RequestServices.GetService(); } public bool IsEnabled { get; set; } diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextAdapterExtensionsTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextAdapterExtensionsTests.cs index e86bc9b9c1..27297264a2 100644 --- a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextAdapterExtensionsTests.cs +++ b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextAdapterExtensionsTests.cs @@ -12,17 +12,14 @@ public class HttpContextAdapterExtensionsTests [Fact] public void NullTypesReturnNull() { - Assert.Null(((HttpContextCore)null!).GetAdapter()); - Assert.Null(((HttpRequestCore)null!).GetAdapter()); - Assert.Null(((HttpResponseCore)null!).GetAdapter()); + Assert.Null((HttpContext)(HttpContextCore)null!); + Assert.Null((HttpRequest)(HttpRequestCore)null!); + Assert.Null((HttpResponse)(HttpResponseCore)null!); - Assert.Null(((HttpContextCore)null!).GetAdapterBase()); - Assert.Null(((HttpRequestCore)null!).GetAdapterBase()); - Assert.Null(((HttpResponseCore)null!).GetAdapterBase()); - Assert.Null(((HttpContext)null!).UnwrapAdapter()); - Assert.Null(((HttpRequest)null!).UnwrapAdapter()); - Assert.Null(((HttpResponse)null!).UnwrapAdapter()); + Assert.Null((HttpContextCore)(HttpContext)null!); + Assert.Null((HttpRequestCore)(HttpRequest)null!); + Assert.Null((HttpResponseCore)(HttpResponse)null!); } [Fact] @@ -31,7 +28,7 @@ public void OriginalContextIsStored() var context = new DefaultHttpContext(); var adapter = new HttpContext(context); - Assert.Same(context, adapter.UnwrapAdapter()); + Assert.Same(context, adapter.AsAspNetCore()); } [Fact] @@ -39,16 +36,16 @@ public void AdaptersAreCached() { var context = new DefaultHttpContext(); - var contextAdapter1 = context.GetAdapter(); - var contextAdapter2 = context.GetAdapter(); + var contextAdapter1 = context.AsSystemWeb(); + var contextAdapter2 = context.AsSystemWeb(); Assert.Same(contextAdapter1, contextAdapter2); - var requestAdapter1 = context.Request.GetAdapter(); - var requestAdapter2 = context.Request.GetAdapter(); + var requestAdapter1 = context.Request.AsSystemWeb(); + var requestAdapter2 = context.Request.AsSystemWeb(); Assert.Same(requestAdapter1, requestAdapter2); - var responseAdapter1 = context.Response.GetAdapter(); - var responseAdapter2 = context.Response.GetAdapter(); + var responseAdapter1 = context.Response.AsSystemWeb(); + var responseAdapter2 = context.Response.AsSystemWeb(); Assert.Same(responseAdapter1, responseAdapter2); } @@ -56,8 +53,8 @@ public void AdaptersAreCached() public void AdapterHttpContextBaseIsCached() { var context = new DefaultHttpContext(); - var adapterBase1 = context.GetAdapterBase(); - var adapterBase2 = context.GetAdapterBase(); + var adapterBase1 = context.AsSystemWebBase(); + var adapterBase2 = context.AsSystemWebBase(); Assert.IsType(adapterBase1); Assert.Same(adapterBase1, adapterBase2); @@ -67,8 +64,8 @@ public void AdapterHttpContextBaseIsCached() public void AdapterHttpResponseBaseIsCached() { var context = new DefaultHttpContext(); - var adapterBase1 = context.Response.GetAdapterBase(); - var adapterBase2 = context.Response.GetAdapterBase(); + var adapterBase1 = (HttpResponseBase)context.Response; + var adapterBase2 = (HttpResponseBase)context.Response; Assert.IsType(adapterBase1); Assert.Same(adapterBase1, adapterBase2); @@ -78,8 +75,8 @@ public void AdapterHttpResponseBaseIsCached() public void AdapterHttpRequestBaseIsCached() { var context = new DefaultHttpContext(); - var adapterBase1 = context.Request.GetAdapterBase(); - var adapterBase2 = context.Request.GetAdapterBase(); + var adapterBase1 = (HttpRequestBase)context.Request; + var adapterBase2 = (HttpRequestBase)context.Request; Assert.IsType(adapterBase1); Assert.Same(adapterBase1, adapterBase2); diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextIntegrationTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextIntegrationTests.cs index 08991aa118..84d62ed22e 100644 --- a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextIntegrationTests.cs +++ b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/HttpContextIntegrationTests.cs @@ -22,7 +22,7 @@ public Task RequestInfo() Assert.Equal("/", context.Request.Path); Assert.Empty(context.Request.Query); - var adapter = (System.Web.HttpRequest)context.Request; + var adapter = context.Request.AsSystemWeb(); Assert.Equal("", adapter.PathInfo); Assert.Equal("/", adapter.FilePath); @@ -34,7 +34,7 @@ public Task RequestInfo() public Task RewriteRequestPath() => RunTest("/", context => { - var adapter = (System.Web.HttpContext)context; + var adapter = context.AsSystemWeb(); adapter.RewritePath("/some/path?q=1"); @@ -57,7 +57,7 @@ public Task RewriteRequestPath() public Task RewriteRequestPathInfo() => RunTest("/", context => { - var adapter = (System.Web.HttpContext)context; + var adapter = context.AsSystemWeb(); adapter.RewritePath("/some/path", "/pathInfo", "q=1"); @@ -80,7 +80,7 @@ public Task RewriteRequestPathInfo() public Task RewritePathViaCoreApis() => RunTest("/", context => { - var adapter = (System.Web.HttpContext)context; + var adapter = context.AsSystemWeb(); // This is the same as RewriteRequestPathInfo as above to get a custom PathInfo adapter.RewritePath("/some/path", "/pathInfo", "q=1"); @@ -106,7 +106,7 @@ public Task Timestamp() => RunTest("/", context => { var timestamp = context.RequestServices.GetRequiredService().GetLocalNow().DateTime; - Assert.Equal(timestamp, context.GetAdapter().Timestamp); + Assert.Equal(timestamp, context.AsSystemWeb().Timestamp); }); private static async Task RunTest(string path, Action run) diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/ResponseStreamTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/ResponseStreamTests.cs index 6527bc80fb..f6c96bf586 100644 --- a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/ResponseStreamTests.cs +++ b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/ResponseStreamTests.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -49,7 +48,7 @@ public async Task BufferedOutputIsFlushedOnceWithStart() var result = await RunAsync(async context => { context.Response.Write(ContentValue); - await ((HttpResponseCore)context.Response).StartAsync(); + await context.Response.AsAspNetCore().StartAsync(); }, builder => builder.BufferResponseStream()); Assert.Equal(ContentValue, result); @@ -61,7 +60,7 @@ public async Task BufferedOutputIsFlushedOnceWithComplete() var result = await RunAsync(async context => { context.Response.Write(ContentValue); - await ((HttpResponseCore)context.Response).CompleteAsync(); + await context.Response.AsAspNetCore().CompleteAsync(); }, builder => builder.BufferResponseStream()); Assert.Equal(ContentValue, result); diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/SetDefaultResponseHeadersMiddlewareTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/SetDefaultResponseHeadersMiddlewareTests.cs index 63a9723ba2..04ecd9c42a 100644 --- a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/SetDefaultResponseHeadersMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/SetDefaultResponseHeadersMiddlewareTests.cs @@ -65,7 +65,7 @@ public async Task AddedInLaterMiddleware(string name, string value) var next = Task (HttpContextCore context) => { - var adapter = context.GetAdapter(); + var adapter = context.AsSystemWeb(); adapter.Response.AppendHeader(name, value); return Task.CompletedTask;