From a450cb69b5e4549f5515cdb057a68771f56cefd7 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 5 Nov 2021 17:52:08 -0700 Subject: Use file scoped namespaces (#38076) * Use file scoped namespaces --- src/Http/Http.Results/src/AcceptedAtRouteResult.cs | 101 +- src/Http/Http.Results/src/AcceptedResult.cs | 97 +- .../Http.Results/src/BadRequestObjectResult.cs | 11 +- src/Http/Http.Results/src/ChallengeResult.cs | 169 ++- src/Http/Http.Results/src/ConflictObjectResult.cs | 11 +- src/Http/Http.Results/src/ContentResult.cs | 101 +- src/Http/Http.Results/src/CreatedAtRouteResult.cs | 101 +- src/Http/Http.Results/src/CreatedResult.cs | 81 +- src/Http/Http.Results/src/FileContentResult.cs | 105 +- src/Http/Http.Results/src/FileResult.cs | 123 ++- src/Http/Http.Results/src/FileStreamResult.cs | 123 ++- src/Http/Http.Results/src/ForbidResult.cs | 181 ++-- src/Http/Http.Results/src/IResultExtensions.cs | 15 +- src/Http/Http.Results/src/JsonResult.cs | 107 +- src/Http/Http.Results/src/LocalRedirectResult.cs | 163 ++- src/Http/Http.Results/src/NoContentResult.cs | 9 +- src/Http/Http.Results/src/NotFoundObjectResult.cs | 11 +- src/Http/Http.Results/src/ObjectResult.cs | 179 ++-- src/Http/Http.Results/src/OkObjectResult.cs | 11 +- src/Http/Http.Results/src/PhysicalFileResult.cs | 187 ++-- src/Http/Http.Results/src/RedirectResult.cs | 117 +- src/Http/Http.Results/src/RedirectToRouteResult.cs | 331 +++--- src/Http/Http.Results/src/ResultExtensions.cs | 15 +- src/Http/Http.Results/src/Results.cs | 1123 ++++++++++---------- src/Http/Http.Results/src/SignInResult.cs | 141 ++- src/Http/Http.Results/src/SignOutResult.cs | 183 ++-- src/Http/Http.Results/src/StatusCodeResult.cs | 79 +- src/Http/Http.Results/src/UnauthorizedResult.cs | 9 +- .../src/UnprocessableEntityObjectResult.cs | 11 +- src/Http/Http.Results/src/VirtualFileResult.cs | 171 ++- .../test/AcceptedAtRouteResultTests.cs | 141 ++- src/Http/Http.Results/test/AcceptedResultTests.cs | 93 +- .../test/BadRequestObjectResultTests.cs | 23 +- src/Http/Http.Results/test/ChallengeResultTest.cs | 93 +- .../Http.Results/test/ConflictObjectResultTest.cs | 23 +- src/Http/Http.Results/test/ContentResultTest.cs | 125 ++- .../Http.Results/test/CreatedAtRouteResultTests.cs | 115 +- src/Http/Http.Results/test/CreatedResultTest.cs | 105 +- .../Http.Results/test/FileContentResultTest.cs | 39 +- src/Http/Http.Results/test/FileStreamResultTest.cs | 121 ++- src/Http/Http.Results/test/ForbidResultTest.cs | 215 ++-- .../Http.Results/test/LocalRedirectResultTest.cs | 247 +++-- .../Http.Results/test/NotFoundObjectResultTest.cs | 87 +- src/Http/Http.Results/test/ObjectResultTests.cs | 295 +++-- src/Http/Http.Results/test/OkObjectResultTest.cs | 53 +- .../Http.Results/test/PhysicalFileResultTest.cs | 49 +- src/Http/Http.Results/test/RedirectResultTest.cs | 37 +- .../Http.Results/test/RedirectToRouteResultTest.cs | 185 ++-- src/Http/Http.Results/test/SignInResultTest.cs | 135 ++- src/Http/Http.Results/test/SignOutResultTest.cs | 137 ++- .../Http.Results/test/StatusCodeResultTests.cs | 51 +- src/Http/Http.Results/test/TestLinkGenerator.cs | 33 +- .../Http.Results/test/UnauthorizedResultTests.cs | 19 +- .../test/UnprocessableEntityObjectResultTests.cs | 23 +- .../Http.Results/test/VirtualFileResultTest.cs | 21 +- 55 files changed, 3238 insertions(+), 3293 deletions(-) (limited to 'src/Http/Http.Results') diff --git a/src/Http/Http.Results/src/AcceptedAtRouteResult.cs b/src/Http/Http.Results/src/AcceptedAtRouteResult.cs index e35d06a4fb..1958f7d402 100644 --- a/src/Http/Http.Results/src/AcceptedAtRouteResult.cs +++ b/src/Http/Http.Results/src/AcceptedAtRouteResult.cs @@ -4,64 +4,63 @@ using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class AcceptedAtRouteResult : ObjectResult { - internal sealed class AcceptedAtRouteResult : ObjectResult + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The route data to use for generating the URL. + /// The value to format in the entity body. + public AcceptedAtRouteResult(object? routeValues, object? value) + : this(routeName: null, routeValues: routeValues, value: value) { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The route data to use for generating the URL. - /// The value to format in the entity body. - public AcceptedAtRouteResult(object? routeValues, object? value) - : this(routeName: null, routeValues: routeValues, value: value) - { - } - - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The name of the route to use for generating the URL. - /// The route data to use for generating the URL. - /// The value to format in the entity body. - public AcceptedAtRouteResult( - string? routeName, - object? routeValues, - object? value) - : base(value, StatusCodes.Status202Accepted) - { - RouteName = routeName; - RouteValues = new RouteValueDictionary(routeValues); - } + } - /// - /// Gets the name of the route to use for generating the URL. - /// - public string? RouteName { get; } + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The name of the route to use for generating the URL. + /// The route data to use for generating the URL. + /// The value to format in the entity body. + public AcceptedAtRouteResult( + string? routeName, + object? routeValues, + object? value) + : base(value, StatusCodes.Status202Accepted) + { + RouteName = routeName; + RouteValues = new RouteValueDictionary(routeValues); + } - /// - /// Gets the route data to use for generating the URL. - /// - public RouteValueDictionary RouteValues { get; } + /// + /// Gets the name of the route to use for generating the URL. + /// + public string? RouteName { get; } - /// - protected override void ConfigureResponseHeaders(HttpContext context) - { - var linkGenerator = context.RequestServices.GetRequiredService(); - var url = linkGenerator.GetUriByAddress( - context, - RouteName, - RouteValues, - fragment: FragmentString.Empty); + /// + /// Gets the route data to use for generating the URL. + /// + public RouteValueDictionary RouteValues { get; } - if (string.IsNullOrEmpty(url)) - { - throw new InvalidOperationException("No route matches the supplied values."); - } + /// + protected override void ConfigureResponseHeaders(HttpContext context) + { + var linkGenerator = context.RequestServices.GetRequiredService(); + var url = linkGenerator.GetUriByAddress( + context, + RouteName, + RouteValues, + fragment: FragmentString.Empty); - context.Response.Headers.Location = url; + if (string.IsNullOrEmpty(url)) + { + throw new InvalidOperationException("No route matches the supplied values."); } + + context.Response.Headers.Location = url; } } diff --git a/src/Http/Http.Results/src/AcceptedResult.cs b/src/Http/Http.Results/src/AcceptedResult.cs index 9ef66d936c..4926e216f3 100644 --- a/src/Http/Http.Results/src/AcceptedResult.cs +++ b/src/Http/Http.Results/src/AcceptedResult.cs @@ -3,67 +3,66 @@ using System; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class AcceptedResult : ObjectResult { - internal sealed class AcceptedResult : ObjectResult + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + public AcceptedResult() + : base(value: null, StatusCodes.Status202Accepted) + { + } + + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The location at which the status of requested content can be monitored. + /// The value to format in the entity body. + public AcceptedResult(string? location, object? value) + : base(value, StatusCodes.Status202Accepted) { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - public AcceptedResult() - : base(value: null, StatusCodes.Status202Accepted) + Location = location; + } + + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The location at which the status of requested content can be monitored. + /// The value to format in the entity body. + public AcceptedResult(Uri locationUri, object? value) + : base(value, StatusCodes.Status202Accepted) + { + if (locationUri == null) { + throw new ArgumentNullException(nameof(locationUri)); } - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The location at which the status of requested content can be monitored. - /// The value to format in the entity body. - public AcceptedResult(string? location, object? value) - : base(value, StatusCodes.Status202Accepted) + if (locationUri.IsAbsoluteUri) { - Location = location; + Location = locationUri.AbsoluteUri; } - - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The location at which the status of requested content can be monitored. - /// The value to format in the entity body. - public AcceptedResult(Uri locationUri, object? value) - : base(value, StatusCodes.Status202Accepted) + else { - if (locationUri == null) - { - throw new ArgumentNullException(nameof(locationUri)); - } - - if (locationUri.IsAbsoluteUri) - { - Location = locationUri.AbsoluteUri; - } - else - { - Location = locationUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); - } + Location = locationUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); } + } - /// - /// Gets or sets the location at which the status of the requested content can be monitored. - /// - public string? Location { get; set; } + /// + /// Gets or sets the location at which the status of the requested content can be monitored. + /// + public string? Location { get; set; } - /// - protected override void ConfigureResponseHeaders(HttpContext context) + /// + protected override void ConfigureResponseHeaders(HttpContext context) + { + if (!string.IsNullOrEmpty(Location)) { - if (!string.IsNullOrEmpty(Location)) - { - context.Response.Headers.Location = Location; - } + context.Response.Headers.Location = Location; } } } diff --git a/src/Http/Http.Results/src/BadRequestObjectResult.cs b/src/Http/Http.Results/src/BadRequestObjectResult.cs index bdad2f4f0f..7f58b7c9d6 100644 --- a/src/Http/Http.Results/src/BadRequestObjectResult.cs +++ b/src/Http/Http.Results/src/BadRequestObjectResult.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class BadRequestObjectResult : ObjectResult { - internal sealed class BadRequestObjectResult : ObjectResult + public BadRequestObjectResult(object? error) + : base(error, StatusCodes.Status400BadRequest) { - public BadRequestObjectResult(object? error) - : base(error, StatusCodes.Status400BadRequest) - { - } } } diff --git a/src/Http/Http.Results/src/ChallengeResult.cs b/src/Http/Http.Results/src/ChallengeResult.cs index b9c15cfedd..c9948b943a 100644 --- a/src/Http/Http.Results/src/ChallengeResult.cs +++ b/src/Http/Http.Results/src/ChallengeResult.cs @@ -9,112 +9,111 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// An that on execution invokes . +/// +internal sealed partial class ChallengeResult : IResult { /// - /// An that on execution invokes . + /// Initializes a new instance of . /// - internal sealed partial class ChallengeResult : IResult + public ChallengeResult() + : this(Array.Empty()) { - /// - /// Initializes a new instance of . - /// - public ChallengeResult() - : this(Array.Empty()) - { - } + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme. - /// - /// The authentication scheme to challenge. - public ChallengeResult(string authenticationScheme) - : this(new[] { authenticationScheme }) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme. + /// + /// The authentication scheme to challenge. + public ChallengeResult(string authenticationScheme) + : this(new[] { authenticationScheme }) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication schemes. - /// - /// The authentication schemes to challenge. - public ChallengeResult(IList authenticationSchemes) - : this(authenticationSchemes, properties: null) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication schemes. + /// + /// The authentication schemes to challenge. + public ChallengeResult(IList authenticationSchemes) + : this(authenticationSchemes, properties: null) + { + } - /// - /// Initializes a new instance of with the - /// specified . - /// - /// used to perform the authentication - /// challenge. - public ChallengeResult(AuthenticationProperties? properties) - : this(Array.Empty(), properties) - { - } + /// + /// Initializes a new instance of with the + /// specified . + /// + /// used to perform the authentication + /// challenge. + public ChallengeResult(AuthenticationProperties? properties) + : this(Array.Empty(), properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme and . - /// - /// The authentication schemes to challenge. - /// used to perform the authentication - /// challenge. - public ChallengeResult(string authenticationScheme, AuthenticationProperties? properties) - : this(new[] { authenticationScheme }, properties) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme and . + /// + /// The authentication schemes to challenge. + /// used to perform the authentication + /// challenge. + public ChallengeResult(string authenticationScheme, AuthenticationProperties? properties) + : this(new[] { authenticationScheme }, properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication schemes and . - /// - /// The authentication scheme to challenge. - /// used to perform the authentication - /// challenge. - public ChallengeResult(IList authenticationSchemes, AuthenticationProperties? properties) - { - AuthenticationSchemes = authenticationSchemes; - Properties = properties; - } + /// + /// Initializes a new instance of with the + /// specified authentication schemes and . + /// + /// The authentication scheme to challenge. + /// used to perform the authentication + /// challenge. + public ChallengeResult(IList authenticationSchemes, AuthenticationProperties? properties) + { + AuthenticationSchemes = authenticationSchemes; + Properties = properties; + } - public IList AuthenticationSchemes { get; init; } = Array.Empty(); + public IList AuthenticationSchemes { get; init; } = Array.Empty(); - public AuthenticationProperties? Properties { get; init; } + public AuthenticationProperties? Properties { get; init; } - public async Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); + public async Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); - Log.ChallengeResultExecuting(logger, AuthenticationSchemes); + Log.ChallengeResultExecuting(logger, AuthenticationSchemes); - if (AuthenticationSchemes != null && AuthenticationSchemes.Count > 0) - { - foreach (var scheme in AuthenticationSchemes) - { - await httpContext.ChallengeAsync(scheme, Properties); - } - } - else + if (AuthenticationSchemes != null && AuthenticationSchemes.Count > 0) + { + foreach (var scheme in AuthenticationSchemes) { - await httpContext.ChallengeAsync(Properties); + await httpContext.ChallengeAsync(scheme, Properties); } } + else + { + await httpContext.ChallengeAsync(Properties); + } + } - private static partial class Log + private static partial class Log + { + public static void ChallengeResultExecuting(ILogger logger, IList authenticationSchemes) { - public static void ChallengeResultExecuting(ILogger logger, IList authenticationSchemes) + if (logger.IsEnabled(LogLevel.Information)) { - if (logger.IsEnabled(LogLevel.Information)) - { - ChallengeResultExecuting(logger, authenticationSchemes.ToArray()); - } + ChallengeResultExecuting(logger, authenticationSchemes.ToArray()); } - - [LoggerMessage(1, LogLevel.Information, "Executing ChallengeResult with authentication schemes ({Schemes}).", EventName = "ChallengeResultExecuting", SkipEnabledCheck = true)] - private static partial void ChallengeResultExecuting(ILogger logger, string[] schemes); } + + [LoggerMessage(1, LogLevel.Information, "Executing ChallengeResult with authentication schemes ({Schemes}).", EventName = "ChallengeResultExecuting", SkipEnabledCheck = true)] + private static partial void ChallengeResultExecuting(ILogger logger, string[] schemes); } } diff --git a/src/Http/Http.Results/src/ConflictObjectResult.cs b/src/Http/Http.Results/src/ConflictObjectResult.cs index 9a90eb7bc0..68308b14d2 100644 --- a/src/Http/Http.Results/src/ConflictObjectResult.cs +++ b/src/Http/Http.Results/src/ConflictObjectResult.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class ConflictObjectResult : ObjectResult { - internal sealed class ConflictObjectResult : ObjectResult + public ConflictObjectResult(object? error) : + base(error, StatusCodes.Status409Conflict) { - public ConflictObjectResult(object? error) : - base(error, StatusCodes.Status409Conflict) - { - } } } diff --git a/src/Http/Http.Results/src/ContentResult.cs b/src/Http/Http.Results/src/ContentResult.cs index 347c823d76..ebd987dfed 100644 --- a/src/Http/Http.Results/src/ContentResult.cs +++ b/src/Http/Http.Results/src/ContentResult.cs @@ -7,69 +7,68 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result -{ - internal sealed partial class ContentResult : IResult - { - private const string DefaultContentType = "text/plain; charset=utf-8"; - private static readonly Encoding DefaultEncoding = Encoding.UTF8; +namespace Microsoft.AspNetCore.Http.Result; - /// - /// Gets or set the content representing the body of the response. - /// - public string? Content { get; init; } +internal sealed partial class ContentResult : IResult +{ + private const string DefaultContentType = "text/plain; charset=utf-8"; + private static readonly Encoding DefaultEncoding = Encoding.UTF8; - /// - /// Gets or sets the Content-Type header for the response. - /// - public string? ContentType { get; init; } + /// + /// Gets or set the content representing the body of the response. + /// + public string? Content { get; init; } - /// - /// Gets or sets the HTTP status code. - /// - public int? StatusCode { get; init; } + /// + /// Gets or sets the Content-Type header for the response. + /// + public string? ContentType { get; init; } - /// - /// Writes the content to the HTTP response. - /// - /// The for the current request. - /// A task that represents the asynchronous execute operation. - public async Task ExecuteAsync(HttpContext httpContext) - { - var response = httpContext.Response; + /// + /// Gets or sets the HTTP status code. + /// + public int? StatusCode { get; init; } - ResponseContentTypeHelper.ResolveContentTypeAndEncoding( - ContentType, - response.ContentType, - (DefaultContentType, DefaultEncoding), - ResponseContentTypeHelper.GetEncoding, - out var resolvedContentType, - out var resolvedContentTypeEncoding); + /// + /// Writes the content to the HTTP response. + /// + /// The for the current request. + /// A task that represents the asynchronous execute operation. + public async Task ExecuteAsync(HttpContext httpContext) + { + var response = httpContext.Response; - response.ContentType = resolvedContentType; + ResponseContentTypeHelper.ResolveContentTypeAndEncoding( + ContentType, + response.ContentType, + (DefaultContentType, DefaultEncoding), + ResponseContentTypeHelper.GetEncoding, + out var resolvedContentType, + out var resolvedContentTypeEncoding); - if (StatusCode != null) - { - response.StatusCode = StatusCode.Value; - } + response.ContentType = resolvedContentType; - var logger = httpContext.RequestServices.GetRequiredService>(); + if (StatusCode != null) + { + response.StatusCode = StatusCode.Value; + } - Log.ContentResultExecuting(logger, resolvedContentType); + var logger = httpContext.RequestServices.GetRequiredService>(); - if (Content != null) - { - response.ContentLength = resolvedContentTypeEncoding.GetByteCount(Content); - await response.WriteAsync(Content, resolvedContentTypeEncoding); - } - } + Log.ContentResultExecuting(logger, resolvedContentType); - private static partial class Log + if (Content != null) { - [LoggerMessage(1, LogLevel.Information, - "Executing ContentResult with HTTP Response ContentType of {ContentType}", - EventName = "ContentResultExecuting")] - internal static partial void ContentResultExecuting(ILogger logger, string contentType); + response.ContentLength = resolvedContentTypeEncoding.GetByteCount(Content); + await response.WriteAsync(Content, resolvedContentTypeEncoding); } } + + private static partial class Log + { + [LoggerMessage(1, LogLevel.Information, + "Executing ContentResult with HTTP Response ContentType of {ContentType}", + EventName = "ContentResultExecuting")] + internal static partial void ContentResultExecuting(ILogger logger, string contentType); + } } diff --git a/src/Http/Http.Results/src/CreatedAtRouteResult.cs b/src/Http/Http.Results/src/CreatedAtRouteResult.cs index e561e32435..4b0bc00747 100644 --- a/src/Http/Http.Results/src/CreatedAtRouteResult.cs +++ b/src/Http/Http.Results/src/CreatedAtRouteResult.cs @@ -5,64 +5,63 @@ using System; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class CreatedAtRouteResult : ObjectResult { - internal sealed class CreatedAtRouteResult : ObjectResult + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The route data to use for generating the URL. + /// The value to format in the entity body. + public CreatedAtRouteResult(object? routeValues, object? value) + : this(routeName: null, routeValues: routeValues, value: value) { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The route data to use for generating the URL. - /// The value to format in the entity body. - public CreatedAtRouteResult(object? routeValues, object? value) - : this(routeName: null, routeValues: routeValues, value: value) - { - } - - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The name of the route to use for generating the URL. - /// The route data to use for generating the URL. - /// The value to format in the entity body. - public CreatedAtRouteResult( - string? routeName, - object? routeValues, - object? value) - : base(value, StatusCodes.Status201Created) - { - RouteName = routeName; - RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues); - } + } - /// - /// Gets or sets the name of the route to use for generating the URL. - /// - public string? RouteName { get; set; } + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The name of the route to use for generating the URL. + /// The route data to use for generating the URL. + /// The value to format in the entity body. + public CreatedAtRouteResult( + string? routeName, + object? routeValues, + object? value) + : base(value, StatusCodes.Status201Created) + { + RouteName = routeName; + RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues); + } - /// - /// Gets or sets the route data to use for generating the URL. - /// - public RouteValueDictionary? RouteValues { get; set; } + /// + /// Gets or sets the name of the route to use for generating the URL. + /// + public string? RouteName { get; set; } - /// - protected override void ConfigureResponseHeaders(HttpContext context) - { - var linkGenerator = context.RequestServices.GetRequiredService(); - var url = linkGenerator.GetUriByRouteValues( - context, - RouteName, - RouteValues, - fragment: FragmentString.Empty); + /// + /// Gets or sets the route data to use for generating the URL. + /// + public RouteValueDictionary? RouteValues { get; set; } - if (string.IsNullOrEmpty(url)) - { - throw new InvalidOperationException("No route matches the supplied values."); - } + /// + protected override void ConfigureResponseHeaders(HttpContext context) + { + var linkGenerator = context.RequestServices.GetRequiredService(); + var url = linkGenerator.GetUriByRouteValues( + context, + RouteName, + RouteValues, + fragment: FragmentString.Empty); - context.Response.Headers.Location = url; + if (string.IsNullOrEmpty(url)) + { + throw new InvalidOperationException("No route matches the supplied values."); } + + context.Response.Headers.Location = url; } } diff --git a/src/Http/Http.Results/src/CreatedResult.cs b/src/Http/Http.Results/src/CreatedResult.cs index b5b2d04bbf..6979c2160b 100644 --- a/src/Http/Http.Results/src/CreatedResult.cs +++ b/src/Http/Http.Results/src/CreatedResult.cs @@ -3,55 +3,54 @@ using System; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class CreatedResult : ObjectResult { - internal sealed class CreatedResult : ObjectResult + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The location at which the content has been created. + /// The value to format in the entity body. + public CreatedResult(string location, object? value) + : base(value, StatusCodes.Status201Created) + { + Location = location; + } + + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The location at which the content has been created. + /// The value to format in the entity body. + public CreatedResult(Uri location, object? value) + : base(value, StatusCodes.Status201Created) { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The location at which the content has been created. - /// The value to format in the entity body. - public CreatedResult(string location, object? value) - : base(value, StatusCodes.Status201Created) + if (location == null) { - Location = location; + throw new ArgumentNullException(nameof(location)); } - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The location at which the content has been created. - /// The value to format in the entity body. - public CreatedResult(Uri location, object? value) - : base(value, StatusCodes.Status201Created) + if (location.IsAbsoluteUri) { - if (location == null) - { - throw new ArgumentNullException(nameof(location)); - } - - if (location.IsAbsoluteUri) - { - Location = location.AbsoluteUri; - } - else - { - Location = location.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); - } + Location = location.AbsoluteUri; } - - /// - /// Gets or sets the location at which the content has been created. - /// - public string Location { get; init; } - - /// - protected override void ConfigureResponseHeaders(HttpContext context) + else { - context.Response.Headers.Location = Location; + Location = location.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); } } + + /// + /// Gets or sets the location at which the content has been created. + /// + public string Location { get; init; } + + /// + protected override void ConfigureResponseHeaders(HttpContext context) + { + context.Response.Headers.Location = Location; + } } diff --git a/src/Http/Http.Results/src/FileContentResult.cs b/src/Http/Http.Results/src/FileContentResult.cs index 04c341a18b..b00da02890 100644 --- a/src/Http/Http.Results/src/FileContentResult.cs +++ b/src/Http/Http.Results/src/FileContentResult.cs @@ -5,68 +5,67 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed partial class FileContentResult : FileResult, IResult { - internal sealed partial class FileContentResult : FileResult, IResult + /// + /// Creates a new instance with + /// the provided and the + /// provided . + /// + /// The bytes that represent the file contents. + /// The Content-Type header of the response. + public FileContentResult(byte[] fileContents, string? contentType) + : base(contentType) { - /// - /// Creates a new instance with - /// the provided and the - /// provided . - /// - /// The bytes that represent the file contents. - /// The Content-Type header of the response. - public FileContentResult(byte[] fileContents, string? contentType) - : base(contentType) - { - FileContents = fileContents; - } - - /// - /// Gets or sets the file contents. - /// - public byte[] FileContents { get; init; } + FileContents = fileContents; + } - public Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); - Log.ExecutingFileResult(logger, this); + /// + /// Gets or sets the file contents. + /// + public byte[] FileContents { get; init; } - var fileResultInfo = new FileResultInfo - { - ContentType = ContentType, - EnableRangeProcessing = EnableRangeProcessing, - EntityTag = EntityTag, - FileDownloadName = FileDownloadName, - LastModified = LastModified, - }; + public Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); + Log.ExecutingFileResult(logger, this); - var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( - httpContext, - fileResultInfo, - FileContents.Length, - EnableRangeProcessing, - LastModified, - EntityTag, - logger); + var fileResultInfo = new FileResultInfo + { + ContentType = ContentType, + EnableRangeProcessing = EnableRangeProcessing, + EntityTag = EntityTag, + FileDownloadName = FileDownloadName, + LastModified = LastModified, + }; - if (!serveBody) - { - return Task.CompletedTask; - } + var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( + httpContext, + fileResultInfo, + FileContents.Length, + EnableRangeProcessing, + LastModified, + EntityTag, + logger); - if (range != null && rangeLength == 0) - { - return Task.CompletedTask; - } + if (!serveBody) + { + return Task.CompletedTask; + } - if (range != null) - { - FileResultHelper.Log.WritingRangeToBody(logger); - } + if (range != null && rangeLength == 0) + { + return Task.CompletedTask; + } - var fileContentStream = new MemoryStream(FileContents); - return FileResultHelper.WriteFileAsync(httpContext, fileContentStream, range, rangeLength); + if (range != null) + { + FileResultHelper.Log.WritingRangeToBody(logger); } + + var fileContentStream = new MemoryStream(FileContents); + return FileResultHelper.WriteFileAsync(httpContext, fileContentStream, range, rangeLength); } } diff --git a/src/Http/Http.Results/src/FileResult.cs b/src/Http/Http.Results/src/FileResult.cs index d6a4afea79..d3be83f96f 100644 --- a/src/Http/Http.Results/src/FileResult.cs +++ b/src/Http/Http.Results/src/FileResult.cs @@ -5,83 +5,82 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal abstract partial class FileResult { - internal abstract partial class FileResult - { - private string? _fileDownloadName; + private string? _fileDownloadName; - /// - /// Creates a new instance with - /// the provided . - /// - /// The Content-Type header of the response. - protected FileResult(string? contentType) - { - ContentType = contentType ?? "application/octet-stream"; - } + /// + /// Creates a new instance with + /// the provided . + /// + /// The Content-Type header of the response. + protected FileResult(string? contentType) + { + ContentType = contentType ?? "application/octet-stream"; + } - /// - /// Gets the Content-Type header for the response. - /// - public string ContentType { get; } + /// + /// Gets the Content-Type header for the response. + /// + public string ContentType { get; } - /// - /// Gets the file name that will be used in the Content-Disposition header of the response. - /// - [AllowNull] - public string FileDownloadName - { - get { return _fileDownloadName ?? string.Empty; } - init { _fileDownloadName = value; } - } + /// + /// Gets the file name that will be used in the Content-Disposition header of the response. + /// + [AllowNull] + public string FileDownloadName + { + get { return _fileDownloadName ?? string.Empty; } + init { _fileDownloadName = value; } + } - /// - /// Gets or sets the last modified information associated with the . - /// - public DateTimeOffset? LastModified { get; init; } + /// + /// Gets or sets the last modified information associated with the . + /// + public DateTimeOffset? LastModified { get; init; } - /// - /// Gets or sets the etag associated with the . - /// - public EntityTagHeaderValue? EntityTag { get; init; } + /// + /// Gets or sets the etag associated with the . + /// + public EntityTagHeaderValue? EntityTag { get; init; } - /// - /// Gets or sets the value that enables range processing for the . - /// - public bool EnableRangeProcessing { get; init; } + /// + /// Gets or sets the value that enables range processing for the . + /// + public bool EnableRangeProcessing { get; init; } - protected static partial class Log + protected static partial class Log + { + public static void ExecutingFileResult(ILogger logger, FileResult fileResult) { - public static void ExecutingFileResult(ILogger logger, FileResult fileResult) + if (logger.IsEnabled(LogLevel.Information)) { - if (logger.IsEnabled(LogLevel.Information)) - { - var fileResultType = fileResult.GetType().Name; - ExecutingFileResultWithNoFileName(logger, fileResultType, fileResult.FileDownloadName); - } + var fileResultType = fileResult.GetType().Name; + ExecutingFileResultWithNoFileName(logger, fileResultType, fileResult.FileDownloadName); } + } - public static void ExecutingFileResult(ILogger logger, FileResult fileResult, string fileName) + public static void ExecutingFileResult(ILogger logger, FileResult fileResult, string fileName) + { + if (logger.IsEnabled(LogLevel.Information)) { - if (logger.IsEnabled(LogLevel.Information)) - { - var fileResultType = fileResult.GetType().Name; - ExecutingFileResult(logger, fileResultType, fileName, fileResult.FileDownloadName); - } + var fileResultType = fileResult.GetType().Name; + ExecutingFileResult(logger, fileResultType, fileName, fileResult.FileDownloadName); } + } - [LoggerMessage(1, LogLevel.Information, - "Executing {FileResultType}, sending file with download name '{FileDownloadName}'.", - EventName = "ExecutingFileResultWithNoFileName", - SkipEnabledCheck = true)] - private static partial void ExecutingFileResultWithNoFileName(ILogger logger, string fileResultType, string fileDownloadName); + [LoggerMessage(1, LogLevel.Information, + "Executing {FileResultType}, sending file with download name '{FileDownloadName}'.", + EventName = "ExecutingFileResultWithNoFileName", + SkipEnabledCheck = true)] + private static partial void ExecutingFileResultWithNoFileName(ILogger logger, string fileResultType, string fileDownloadName); - [LoggerMessage(2, LogLevel.Information, - "Executing {FileResultType}, sending file '{FileDownloadPath}' with download name '{FileDownloadName}'.", - EventName = "ExecutingFileResult", - SkipEnabledCheck = true)] - private static partial void ExecutingFileResult(ILogger logger, string fileResultType, string fileDownloadPath, string fileDownloadName); - } + [LoggerMessage(2, LogLevel.Information, + "Executing {FileResultType}, sending file '{FileDownloadPath}' with download name '{FileDownloadName}'.", + EventName = "ExecutingFileResult", + SkipEnabledCheck = true)] + private static partial void ExecutingFileResult(ILogger logger, string fileResultType, string fileDownloadPath, string fileDownloadName); } } diff --git a/src/Http/Http.Results/src/FileStreamResult.cs b/src/Http/Http.Results/src/FileStreamResult.cs index aa69a1db36..ed4202cb5c 100644 --- a/src/Http/Http.Results/src/FileStreamResult.cs +++ b/src/Http/Http.Results/src/FileStreamResult.cs @@ -5,84 +5,83 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// Represents an that when executed will +/// write a file from a stream to the response. +/// +internal sealed class FileStreamResult : FileResult, IResult { /// - /// Represents an that when executed will - /// write a file from a stream to the response. + /// Creates a new instance with + /// the provided and the + /// provided . /// - internal sealed class FileStreamResult : FileResult, IResult + /// The stream with the file. + /// The Content-Type header of the response. + public FileStreamResult(Stream fileStream, string? contentType) + : base(contentType) { - /// - /// Creates a new instance with - /// the provided and the - /// provided . - /// - /// The stream with the file. - /// The Content-Type header of the response. - public FileStreamResult(Stream fileStream, string? contentType) - : base(contentType) + if (fileStream == null) { - if (fileStream == null) - { - throw new ArgumentNullException(nameof(fileStream)); - } - - FileStream = fileStream; + throw new ArgumentNullException(nameof(fileStream)); } - /// - /// Gets or sets the stream with the file that will be sent back as the response. - /// - public Stream FileStream { get; } + FileStream = fileStream; + } - public async Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); - await using (FileStream) - { - Log.ExecutingFileResult(logger, this); + /// + /// Gets or sets the stream with the file that will be sent back as the response. + /// + public Stream FileStream { get; } - long? fileLength = null; - if (FileStream.CanSeek) - { - fileLength = FileStream.Length; - } + public async Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); + await using (FileStream) + { + Log.ExecutingFileResult(logger, this); - var fileResultInfo = new FileResultInfo - { - ContentType = ContentType, - EnableRangeProcessing = EnableRangeProcessing, - EntityTag = EntityTag, - FileDownloadName = FileDownloadName, - }; + long? fileLength = null; + if (FileStream.CanSeek) + { + fileLength = FileStream.Length; + } - var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( - httpContext, - fileResultInfo, - fileLength, - EnableRangeProcessing, - LastModified, - EntityTag, - logger); + var fileResultInfo = new FileResultInfo + { + ContentType = ContentType, + EnableRangeProcessing = EnableRangeProcessing, + EntityTag = EntityTag, + FileDownloadName = FileDownloadName, + }; - if (!serveBody) - { - return; - } + var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( + httpContext, + fileResultInfo, + fileLength, + EnableRangeProcessing, + LastModified, + EntityTag, + logger); - if (range != null && rangeLength == 0) - { - return; - } + if (!serveBody) + { + return; + } - if (range != null) - { - FileResultHelper.Log.WritingRangeToBody(logger); - } + if (range != null && rangeLength == 0) + { + return; + } - await FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength); + if (range != null) + { + FileResultHelper.Log.WritingRangeToBody(logger); } + + await FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength); } } } diff --git a/src/Http/Http.Results/src/ForbidResult.cs b/src/Http/Http.Results/src/ForbidResult.cs index 9c87eb65a1..d0745fe9e8 100644 --- a/src/Http/Http.Results/src/ForbidResult.cs +++ b/src/Http/Http.Results/src/ForbidResult.cs @@ -9,117 +9,116 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed partial class ForbidResult : IResult { - internal sealed partial class ForbidResult : IResult + /// + /// Initializes a new instance of . + /// + public ForbidResult() + : this(Array.Empty()) { - /// - /// Initializes a new instance of . - /// - public ForbidResult() - : this(Array.Empty()) - { - } + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme. - /// - /// The authentication scheme to challenge. - public ForbidResult(string authenticationScheme) - : this(new[] { authenticationScheme }) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme. + /// + /// The authentication scheme to challenge. + public ForbidResult(string authenticationScheme) + : this(new[] { authenticationScheme }) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication schemes. - /// - /// The authentication schemes to challenge. - public ForbidResult(IList authenticationSchemes) - : this(authenticationSchemes, properties: null) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication schemes. + /// + /// The authentication schemes to challenge. + public ForbidResult(IList authenticationSchemes) + : this(authenticationSchemes, properties: null) + { + } - /// - /// Initializes a new instance of with the - /// specified . - /// - /// used to perform the authentication - /// challenge. - public ForbidResult(AuthenticationProperties? properties) - : this(Array.Empty(), properties) - { - } + /// + /// Initializes a new instance of with the + /// specified . + /// + /// used to perform the authentication + /// challenge. + public ForbidResult(AuthenticationProperties? properties) + : this(Array.Empty(), properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme and . - /// - /// The authentication schemes to challenge. - /// used to perform the authentication - /// challenge. - public ForbidResult(string authenticationScheme, AuthenticationProperties? properties) - : this(new[] { authenticationScheme }, properties) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme and . + /// + /// The authentication schemes to challenge. + /// used to perform the authentication + /// challenge. + public ForbidResult(string authenticationScheme, AuthenticationProperties? properties) + : this(new[] { authenticationScheme }, properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication schemes and . - /// - /// The authentication scheme to challenge. - /// used to perform the authentication - /// challenge. - public ForbidResult(IList authenticationSchemes, AuthenticationProperties? properties) - { - AuthenticationSchemes = authenticationSchemes; - Properties = properties; - } + /// + /// Initializes a new instance of with the + /// specified authentication schemes and . + /// + /// The authentication scheme to challenge. + /// used to perform the authentication + /// challenge. + public ForbidResult(IList authenticationSchemes, AuthenticationProperties? properties) + { + AuthenticationSchemes = authenticationSchemes; + Properties = properties; + } - /// - /// Gets or sets the authentication schemes that are challenged. - /// - public IList AuthenticationSchemes { get; init; } + /// + /// Gets or sets the authentication schemes that are challenged. + /// + public IList AuthenticationSchemes { get; init; } - /// - /// Gets or sets the used to perform the authentication challenge. - /// - public AuthenticationProperties? Properties { get; init; } + /// + /// Gets or sets the used to perform the authentication challenge. + /// + public AuthenticationProperties? Properties { get; init; } - /// - public async Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); + /// + public async Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); - Log.ForbidResultExecuting(logger, AuthenticationSchemes); + Log.ForbidResultExecuting(logger, AuthenticationSchemes); - if (AuthenticationSchemes != null && AuthenticationSchemes.Count > 0) - { - for (var i = 0; i < AuthenticationSchemes.Count; i++) - { - await httpContext.ForbidAsync(AuthenticationSchemes[i], Properties); - } - } - else + if (AuthenticationSchemes != null && AuthenticationSchemes.Count > 0) + { + for (var i = 0; i < AuthenticationSchemes.Count; i++) { - await httpContext.ForbidAsync(Properties); + await httpContext.ForbidAsync(AuthenticationSchemes[i], Properties); } } + else + { + await httpContext.ForbidAsync(Properties); + } + } - private static partial class Log + private static partial class Log + { + public static void ForbidResultExecuting(ILogger logger, IList authenticationSchemes) { - public static void ForbidResultExecuting(ILogger logger, IList authenticationSchemes) + if (logger.IsEnabled(LogLevel.Information)) { - if (logger.IsEnabled(LogLevel.Information)) - { - ForbidResultExecuting(logger, authenticationSchemes.ToArray()); - } + ForbidResultExecuting(logger, authenticationSchemes.ToArray()); } - - [LoggerMessage(1, LogLevel.Information, "Executing ChallengeResult with authentication schemes ({Schemes}).", EventName = "ChallengeResultExecuting", SkipEnabledCheck = true)] - private static partial void ForbidResultExecuting(ILogger logger, string[] schemes); } + [LoggerMessage(1, LogLevel.Information, "Executing ChallengeResult with authentication schemes ({Schemes}).", EventName = "ChallengeResultExecuting", SkipEnabledCheck = true)] + private static partial void ForbidResultExecuting(ILogger logger, string[] schemes); } + } diff --git a/src/Http/Http.Results/src/IResultExtensions.cs b/src/Http/Http.Results/src/IResultExtensions.cs index 1905055d0f..eaddb35180 100644 --- a/src/Http/Http.Results/src/IResultExtensions.cs +++ b/src/Http/Http.Results/src/IResultExtensions.cs @@ -1,11 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http -{ - /// - /// Provides an interface to registering external methods that provide - /// custom IResult instances. - /// - public interface IResultExtensions { } -} \ No newline at end of file +namespace Microsoft.AspNetCore.Http; + +/// +/// Provides an interface to registering external methods that provide +/// custom IResult instances. +/// +public interface IResultExtensions { } diff --git a/src/Http/Http.Results/src/JsonResult.cs b/src/Http/Http.Results/src/JsonResult.cs index 59e7f9cba4..797f62f8e9 100644 --- a/src/Http/Http.Results/src/JsonResult.cs +++ b/src/Http/Http.Results/src/JsonResult.cs @@ -6,73 +6,72 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// An action result which formats the given object as JSON. +/// +internal sealed partial class JsonResult : IResult { /// - /// An action result which formats the given object as JSON. + /// Gets or sets the representing the Content-Type header of the response. /// - internal sealed partial class JsonResult : IResult - { - /// - /// Gets or sets the representing the Content-Type header of the response. - /// - public string? ContentType { get; init; } - - /// - /// Gets or sets the serializer settings. - /// - /// When using System.Text.Json, this should be an instance of - /// - /// - /// When using Newtonsoft.Json, this should be an instance of JsonSerializerSettings. - /// - /// - public JsonSerializerOptions? JsonSerializerOptions { get; init; } + public string? ContentType { get; init; } - /// - /// Gets or sets the HTTP status code. - /// - public int? StatusCode { get; init; } + /// + /// Gets or sets the serializer settings. + /// + /// When using System.Text.Json, this should be an instance of + /// + /// + /// When using Newtonsoft.Json, this should be an instance of JsonSerializerSettings. + /// + /// + public JsonSerializerOptions? JsonSerializerOptions { get; init; } - /// - /// Gets or sets the value to be formatted. - /// - public object? Value { get; init; } + /// + /// Gets or sets the HTTP status code. + /// + public int? StatusCode { get; init; } - /// - /// Write the result as JSON to the HTTP response. - /// - /// The for the current request. - /// A task that represents the asynchronous execute operation. - Task IResult.ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); - Log.JsonResultExecuting(logger, Value); + /// + /// Gets or sets the value to be formatted. + /// + public object? Value { get; init; } - if (StatusCode is int statusCode) - { - httpContext.Response.StatusCode = statusCode; - } + /// + /// Write the result as JSON to the HTTP response. + /// + /// The for the current request. + /// A task that represents the asynchronous execute operation. + Task IResult.ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); + Log.JsonResultExecuting(logger, Value); - return httpContext.Response.WriteAsJsonAsync(Value, JsonSerializerOptions, ContentType); + if (StatusCode is int statusCode) + { + httpContext.Response.StatusCode = statusCode; } - private static partial class Log + return httpContext.Response.WriteAsJsonAsync(Value, JsonSerializerOptions, ContentType); + } + + private static partial class Log + { + public static void JsonResultExecuting(ILogger logger, object? value) { - public static void JsonResultExecuting(ILogger logger, object? value) + if (logger.IsEnabled(LogLevel.Information)) { - if (logger.IsEnabled(LogLevel.Information)) - { - var type = value == null ? "null" : value.GetType().FullName!; - JsonResultExecuting(logger, type); - } + var type = value == null ? "null" : value.GetType().FullName!; + JsonResultExecuting(logger, type); } - - [LoggerMessage(1, LogLevel.Information, - "Executing JsonResult, writing value of type '{Type}'.", - EventName = "JsonResultExecuting", - SkipEnabledCheck = true)] - private static partial void JsonResultExecuting(ILogger logger, string type); } + + [LoggerMessage(1, LogLevel.Information, + "Executing JsonResult, writing value of type '{Type}'.", + EventName = "JsonResultExecuting", + SkipEnabledCheck = true)] + private static partial void JsonResultExecuting(ILogger logger, string type); } } diff --git a/src/Http/Http.Results/src/LocalRedirectResult.cs b/src/Http/Http.Results/src/LocalRedirectResult.cs index d7a2efb9ec..c7ad5b8d8b 100644 --- a/src/Http/Http.Results/src/LocalRedirectResult.cs +++ b/src/Http/Http.Results/src/LocalRedirectResult.cs @@ -7,105 +7,104 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// An that returns a Found (302), Moved Permanently (301), Temporary Redirect (307), +/// or Permanent Redirect (308) response with a Location header to the supplied local URL. +/// +internal sealed partial class LocalRedirectResult : IResult { /// - /// An that returns a Found (302), Moved Permanently (301), Temporary Redirect (307), - /// or Permanent Redirect (308) response with a Location header to the supplied local URL. + /// Initializes a new instance of the class with the values + /// provided. /// - internal sealed partial class LocalRedirectResult : IResult + /// The local URL to redirect to. + public LocalRedirectResult(string localUrl) + : this(localUrl, permanent: false) { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The local URL to redirect to. - public LocalRedirectResult(string localUrl) - : this(localUrl, permanent: false) - { - } + } - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The local URL to redirect to. - /// Specifies whether the redirect should be permanent (301) or temporary (302). - public LocalRedirectResult(string localUrl, bool permanent) - : this(localUrl, permanent, preserveMethod: false) + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The local URL to redirect to. + /// Specifies whether the redirect should be permanent (301) or temporary (302). + public LocalRedirectResult(string localUrl, bool permanent) + : this(localUrl, permanent, preserveMethod: false) + { + } + + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The local URL to redirect to. + /// Specifies whether the redirect should be permanent (301) or temporary (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request's method. + public LocalRedirectResult(string localUrl, bool permanent, bool preserveMethod) + { + if (string.IsNullOrEmpty(localUrl)) { + throw new ArgumentException("Argument cannot be null or empty", nameof(localUrl)); } - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The local URL to redirect to. - /// Specifies whether the redirect should be permanent (301) or temporary (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request's method. - public LocalRedirectResult(string localUrl, bool permanent, bool preserveMethod) + Permanent = permanent; + PreserveMethod = preserveMethod; + Url = localUrl; + } + + /// + /// Gets or sets the value that specifies that the redirect should be permanent if true or temporary if false. + /// + public bool Permanent { get; } + + /// + /// Gets or sets an indication that the redirect preserves the initial request method. + /// + public bool PreserveMethod { get; } + + /// + /// Gets or sets the local URL to redirect to. + /// + public string Url { get; } + + /// + public Task ExecuteAsync(HttpContext httpContext) + { + if (!SharedUrlHelper.IsLocalUrl(Url)) { - if (string.IsNullOrEmpty(localUrl)) - { - throw new ArgumentException("Argument cannot be null or empty", nameof(localUrl)); - } - - Permanent = permanent; - PreserveMethod = preserveMethod; - Url = localUrl; + throw new InvalidOperationException("The supplied URL is not local. A URL with an absolute path is considered local if it does not have a host/authority part. URLs using virtual paths ('~/') are also local."); } - /// - /// Gets or sets the value that specifies that the redirect should be permanent if true or temporary if false. - /// - public bool Permanent { get; } + var destinationUrl = SharedUrlHelper.Content(httpContext, Url); - /// - /// Gets or sets an indication that the redirect preserves the initial request method. - /// - public bool PreserveMethod { get; } + // IsLocalUrl is called to handle URLs starting with '~/'. + var logger = httpContext.RequestServices.GetRequiredService>(); - /// - /// Gets or sets the local URL to redirect to. - /// - public string Url { get; } + Log.LocalRedirectResultExecuting(logger, destinationUrl); - /// - public Task ExecuteAsync(HttpContext httpContext) + if (PreserveMethod) { - if (!SharedUrlHelper.IsLocalUrl(Url)) - { - throw new InvalidOperationException("The supplied URL is not local. A URL with an absolute path is considered local if it does not have a host/authority part. URLs using virtual paths ('~/') are also local."); - } - - var destinationUrl = SharedUrlHelper.Content(httpContext, Url); - - // IsLocalUrl is called to handle URLs starting with '~/'. - var logger = httpContext.RequestServices.GetRequiredService>(); - - Log.LocalRedirectResultExecuting(logger, destinationUrl); - - if (PreserveMethod) - { - httpContext.Response.StatusCode = Permanent - ? StatusCodes.Status308PermanentRedirect - : StatusCodes.Status307TemporaryRedirect; - httpContext.Response.Headers.Location = destinationUrl; - } - else - { - httpContext.Response.Redirect(destinationUrl, Permanent); - } - - return Task.CompletedTask; + httpContext.Response.StatusCode = Permanent + ? StatusCodes.Status308PermanentRedirect + : StatusCodes.Status307TemporaryRedirect; + httpContext.Response.Headers.Location = destinationUrl; } - - private static partial class Log + else { - [LoggerMessage(1, LogLevel.Information, - "Executing LocalRedirectResult, redirecting to {Destination}.", - EventName = "LocalRedirectResultExecuting")] - public static partial void LocalRedirectResultExecuting(ILogger logger, string destination); + httpContext.Response.Redirect(destinationUrl, Permanent); } + + return Task.CompletedTask; + } + + private static partial class Log + { + [LoggerMessage(1, LogLevel.Information, + "Executing LocalRedirectResult, redirecting to {Destination}.", + EventName = "LocalRedirectResultExecuting")] + public static partial void LocalRedirectResultExecuting(ILogger logger, string destination); } } diff --git a/src/Http/Http.Results/src/NoContentResult.cs b/src/Http/Http.Results/src/NoContentResult.cs index 7b143e8578..582484c406 100644 --- a/src/Http/Http.Results/src/NoContentResult.cs +++ b/src/Http/Http.Results/src/NoContentResult.cs @@ -1,12 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal class NoContentResult : StatusCodeResult { - internal class NoContentResult : StatusCodeResult + public NoContentResult() : base(StatusCodes.Status204NoContent) { - public NoContentResult() : base(StatusCodes.Status204NoContent) - { - } } } diff --git a/src/Http/Http.Results/src/NotFoundObjectResult.cs b/src/Http/Http.Results/src/NotFoundObjectResult.cs index 2588567c54..5ce0e6083b 100644 --- a/src/Http/Http.Results/src/NotFoundObjectResult.cs +++ b/src/Http/Http.Results/src/NotFoundObjectResult.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class NotFoundObjectResult : ObjectResult { - internal sealed class NotFoundObjectResult : ObjectResult + public NotFoundObjectResult(object? value) + : base(value, StatusCodes.Status404NotFound) { - public NotFoundObjectResult(object? value) - : base(value, StatusCodes.Status404NotFound) - { - } } } diff --git a/src/Http/Http.Results/src/ObjectResult.cs b/src/Http/Http.Results/src/ObjectResult.cs index 1b57682474..3204d866b5 100644 --- a/src/Http/Http.Results/src/ObjectResult.cs +++ b/src/Http/Http.Results/src/ObjectResult.cs @@ -6,131 +6,130 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal partial class ObjectResult : IResult { - internal partial class ObjectResult : IResult + /// + /// Creates a new instance with the provided . + /// + public ObjectResult(object? value) + { + Value = value; + } + + /// + /// Creates a new instance with the provided . + /// + public ObjectResult(object? value, int? statusCode) { - /// - /// Creates a new instance with the provided . - /// - public ObjectResult(object? value) + Value = value; + StatusCode = statusCode; + } + + /// + /// The object result. + /// + public object? Value { get; } + + /// + /// Gets the HTTP status code. + /// + public int? StatusCode { get; set; } + + /// + /// Gets the value for the Content-Type header. + /// + public string? ContentType { get; set; } + + public Task ExecuteAsync(HttpContext httpContext) + { + var loggerFactory = httpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(GetType()); + Log.ObjectResultExecuting(logger, Value, StatusCode); + + if (Value is ProblemDetails problemDetails) { - Value = value; + ApplyProblemDetailsDefaults(problemDetails); } - /// - /// Creates a new instance with the provided . - /// - public ObjectResult(object? value, int? statusCode) + if (StatusCode is { } statusCode) { - Value = value; - StatusCode = statusCode; + httpContext.Response.StatusCode = statusCode; } - /// - /// The object result. - /// - public object? Value { get; } + ConfigureResponseHeaders(httpContext); - /// - /// Gets the HTTP status code. - /// - public int? StatusCode { get; set; } + if (Value is null) + { + return Task.CompletedTask; + } - /// - /// Gets the value for the Content-Type header. - /// - public string? ContentType { get; set; } + OnFormatting(httpContext); + return httpContext.Response.WriteAsJsonAsync(Value, Value.GetType(), options: null, contentType: ContentType); + } - public Task ExecuteAsync(HttpContext httpContext) - { - var loggerFactory = httpContext.RequestServices.GetRequiredService(); - var logger = loggerFactory.CreateLogger(GetType()); - Log.ObjectResultExecuting(logger, Value, StatusCode); + protected virtual void OnFormatting(HttpContext httpContext) + { + } - if (Value is ProblemDetails problemDetails) - { - ApplyProblemDetailsDefaults(problemDetails); - } + protected virtual void ConfigureResponseHeaders(HttpContext httpContext) + { + } - if (StatusCode is { } statusCode) + private void ApplyProblemDetailsDefaults(ProblemDetails problemDetails) + { + // We allow StatusCode to be specified either on ProblemDetails or on the ObjectResult and use it to configure the other. + // This lets users write return Conflict(new Problem("some description")) + // or return Problem("some-problem", 422) and have the response have consistent fields. + if (problemDetails.Status is null) + { + if (StatusCode is not null) { - httpContext.Response.StatusCode = statusCode; + problemDetails.Status = StatusCode; } - - ConfigureResponseHeaders(httpContext); - - if (Value is null) + else { - return Task.CompletedTask; + problemDetails.Status = problemDetails is HttpValidationProblemDetails ? + StatusCodes.Status400BadRequest : + StatusCodes.Status500InternalServerError; } - - OnFormatting(httpContext); - return httpContext.Response.WriteAsJsonAsync(Value, Value.GetType(), options: null, contentType: ContentType); } - protected virtual void OnFormatting(HttpContext httpContext) + if (StatusCode is null) { + StatusCode = problemDetails.Status; } - protected virtual void ConfigureResponseHeaders(HttpContext httpContext) + if (ProblemDetailsDefaults.Defaults.TryGetValue(problemDetails.Status.Value, out var defaults)) { + problemDetails.Title ??= defaults.Title; + problemDetails.Type ??= defaults.Type; } + } - private void ApplyProblemDetailsDefaults(ProblemDetails problemDetails) + private static partial class Log + { + public static void ObjectResultExecuting(ILogger logger, object? value, int? statusCode) { - // We allow StatusCode to be specified either on ProblemDetails or on the ObjectResult and use it to configure the other. - // This lets users write return Conflict(new Problem("some description")) - // or return Problem("some-problem", 422) and have the response have consistent fields. - if (problemDetails.Status is null) + if (logger.IsEnabled(LogLevel.Information)) { - if (StatusCode is not null) + if (value is null) { - problemDetails.Status = StatusCode; + ObjectResultExecutingWithoutValue(logger, statusCode ?? StatusCodes.Status200OK); } else { - problemDetails.Status = problemDetails is HttpValidationProblemDetails ? - StatusCodes.Status400BadRequest : - StatusCodes.Status500InternalServerError; + var valueType = value.GetType().FullName!; + ObjectResultExecuting(logger, valueType, statusCode ?? StatusCodes.Status200OK); } } - - if (StatusCode is null) - { - StatusCode = problemDetails.Status; - } - - if (ProblemDetailsDefaults.Defaults.TryGetValue(problemDetails.Status.Value, out var defaults)) - { - problemDetails.Title ??= defaults.Title; - problemDetails.Type ??= defaults.Type; - } } - private static partial class Log - { - public static void ObjectResultExecuting(ILogger logger, object? value, int? statusCode) - { - if (logger.IsEnabled(LogLevel.Information)) - { - if (value is null) - { - ObjectResultExecutingWithoutValue(logger, statusCode ?? StatusCodes.Status200OK); - } - else - { - var valueType = value.GetType().FullName!; - ObjectResultExecuting(logger, valueType, statusCode ?? StatusCodes.Status200OK); - } - } - } - - [LoggerMessage(1, LogLevel.Information, "Writing value of type '{Type}' with status code '{StatusCode}'.", EventName = "ObjectResultExecuting", SkipEnabledCheck = true)] - private static partial void ObjectResultExecuting(ILogger logger, string type, int statusCode); + [LoggerMessage(1, LogLevel.Information, "Writing value of type '{Type}' with status code '{StatusCode}'.", EventName = "ObjectResultExecuting", SkipEnabledCheck = true)] + private static partial void ObjectResultExecuting(ILogger logger, string type, int statusCode); - [LoggerMessage(2, LogLevel.Information, "Executing result with status code '{StatusCode}'.", EventName = "ObjectResultExecutingWithoutValue", SkipEnabledCheck = true)] - private static partial void ObjectResultExecutingWithoutValue(ILogger logger, int statusCode); - } + [LoggerMessage(2, LogLevel.Information, "Executing result with status code '{StatusCode}'.", EventName = "ObjectResultExecutingWithoutValue", SkipEnabledCheck = true)] + private static partial void ObjectResultExecutingWithoutValue(ILogger logger, int statusCode); } } diff --git a/src/Http/Http.Results/src/OkObjectResult.cs b/src/Http/Http.Results/src/OkObjectResult.cs index 830beadac2..70013671de 100644 --- a/src/Http/Http.Results/src/OkObjectResult.cs +++ b/src/Http/Http.Results/src/OkObjectResult.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class OkObjectResult : ObjectResult { - internal sealed class OkObjectResult : ObjectResult + public OkObjectResult(object? value) + : base(value, StatusCodes.Status200OK) { - public OkObjectResult(object? value) - : base(value, StatusCodes.Status200OK) - { - } } } diff --git a/src/Http/Http.Results/src/PhysicalFileResult.cs b/src/Http/Http.Results/src/PhysicalFileResult.cs index af01f4bd43..8c02e03270 100644 --- a/src/Http/Http.Results/src/PhysicalFileResult.cs +++ b/src/Http/Http.Results/src/PhysicalFileResult.cs @@ -5,116 +5,115 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// A on execution will write a file from disk to the response +/// using mechanisms provided by the host. +/// +internal sealed partial class PhysicalFileResult : FileResult, IResult { /// - /// A on execution will write a file from disk to the response - /// using mechanisms provided by the host. + /// Creates a new instance with + /// the provided and the provided . + /// + /// The path to the file. The path must be an absolute path. + /// The Content-Type header of the response. + public PhysicalFileResult(string fileName, string? contentType) + : base(contentType) + { + FileName = fileName; + } + + /// + /// Gets or sets the path to the file that will be sent back as the response. /// - internal sealed partial class PhysicalFileResult : FileResult, IResult + public string FileName { get; } + + // For testing + public Func GetFileInfoWrapper { get; init; } = + static path => new FileInfoWrapper(path); + + public Task ExecuteAsync(HttpContext httpContext) { - /// - /// Creates a new instance with - /// the provided and the provided . - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type header of the response. - public PhysicalFileResult(string fileName, string? contentType) - : base(contentType) + var fileInfo = GetFileInfoWrapper(FileName); + if (!fileInfo.Exists) { - FileName = fileName; + throw new FileNotFoundException($"Could not find file: {FileName}", FileName); } - /// - /// Gets or sets the path to the file that will be sent back as the response. - /// - public string FileName { get; } + var logger = httpContext.RequestServices.GetRequiredService>(); + + Log.ExecutingFileResult(logger, this, FileName); + + var lastModified = LastModified ?? fileInfo.LastWriteTimeUtc; + var fileResultInfo = new FileResultInfo + { + ContentType = ContentType, + EnableRangeProcessing = EnableRangeProcessing, + EntityTag = EntityTag, + FileDownloadName = FileDownloadName, + LastModified = lastModified, + }; + + var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( + httpContext, + fileResultInfo, + fileInfo.Length, + EnableRangeProcessing, + lastModified, + EntityTag, + logger); + + if (!serveBody) + { + return Task.CompletedTask; + } - // For testing - public Func GetFileInfoWrapper { get; init; } = - static path => new FileInfoWrapper(path); + if (range != null && rangeLength == 0) + { + return Task.CompletedTask; + } - public Task ExecuteAsync(HttpContext httpContext) + var response = httpContext.Response; + if (!Path.IsPathRooted(FileName)) { - var fileInfo = GetFileInfoWrapper(FileName); - if (!fileInfo.Exists) - { - throw new FileNotFoundException($"Could not find file: {FileName}", FileName); - } - - var logger = httpContext.RequestServices.GetRequiredService>(); - - Log.ExecutingFileResult(logger, this, FileName); - - var lastModified = LastModified ?? fileInfo.LastWriteTimeUtc; - var fileResultInfo = new FileResultInfo - { - ContentType = ContentType, - EnableRangeProcessing = EnableRangeProcessing, - EntityTag = EntityTag, - FileDownloadName = FileDownloadName, - LastModified = lastModified, - }; - - var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( - httpContext, - fileResultInfo, - fileInfo.Length, - EnableRangeProcessing, - lastModified, - EntityTag, - logger); - - if (!serveBody) - { - return Task.CompletedTask; - } - - if (range != null && rangeLength == 0) - { - return Task.CompletedTask; - } - - var response = httpContext.Response; - if (!Path.IsPathRooted(FileName)) - { - throw new NotSupportedException($"Path '{FileName}' was not rooted."); - } - - if (range != null) - { - FileResultHelper.Log.WritingRangeToBody(logger); - } - - var offset = 0L; - var count = (long?)null; - if (range != null) - { - offset = range.From ?? 0L; - count = rangeLength; - } - - return response.SendFileAsync( - FileName, - offset: offset, - count: count); + throw new NotSupportedException($"Path '{FileName}' was not rooted."); } - internal readonly struct FileInfoWrapper + if (range != null) { - public FileInfoWrapper(string path) - { - var fileInfo = new FileInfo(path); - Exists = fileInfo.Exists; - Length = fileInfo.Length; - LastWriteTimeUtc = fileInfo.LastWriteTimeUtc; - } + FileResultHelper.Log.WritingRangeToBody(logger); + } - public bool Exists { get; init; } + var offset = 0L; + var count = (long?)null; + if (range != null) + { + offset = range.From ?? 0L; + count = rangeLength; + } - public long Length { get; init; } + return response.SendFileAsync( + FileName, + offset: offset, + count: count); + } - public DateTimeOffset LastWriteTimeUtc { get; init; } + internal readonly struct FileInfoWrapper + { + public FileInfoWrapper(string path) + { + var fileInfo = new FileInfo(path); + Exists = fileInfo.Exists; + Length = fileInfo.Length; + LastWriteTimeUtc = fileInfo.LastWriteTimeUtc; } + + public bool Exists { get; init; } + + public long Length { get; init; } + + public DateTimeOffset LastWriteTimeUtc { get; init; } } } diff --git a/src/Http/Http.Results/src/RedirectResult.cs b/src/Http/Http.Results/src/RedirectResult.cs index ac4c3ea2dd..f8c89e5821 100644 --- a/src/Http/Http.Results/src/RedirectResult.cs +++ b/src/Http/Http.Results/src/RedirectResult.cs @@ -7,80 +7,79 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed partial class RedirectResult : IResult { - internal sealed partial class RedirectResult : IResult + /// + /// Initializes a new instance of the class with the values + /// provided. + /// + /// The URL to redirect to. + /// Specifies whether the redirect should be permanent (301) or temporary (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. + public RedirectResult(string url, bool permanent, bool preserveMethod) { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The URL to redirect to. - /// Specifies whether the redirect should be permanent (301) or temporary (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. - public RedirectResult(string url, bool permanent, bool preserveMethod) + if (url == null) { - if (url == null) - { - throw new ArgumentNullException(nameof(url)); - } - - if (string.IsNullOrEmpty(url)) - { - throw new ArgumentException("Argument cannot be null or empty", nameof(url)); - } + throw new ArgumentNullException(nameof(url)); + } - Permanent = permanent; - PreserveMethod = preserveMethod; - Url = url; + if (string.IsNullOrEmpty(url)) + { + throw new ArgumentException("Argument cannot be null or empty", nameof(url)); } - /// - /// Gets or sets the value that specifies that the redirect should be permanent if true or temporary if false. - /// - public bool Permanent { get; } + Permanent = permanent; + PreserveMethod = preserveMethod; + Url = url; + } - /// - /// Gets or sets an indication that the redirect preserves the initial request method. - /// - public bool PreserveMethod { get; } + /// + /// Gets or sets the value that specifies that the redirect should be permanent if true or temporary if false. + /// + public bool Permanent { get; } - /// - /// Gets or sets the URL to redirect to. - /// - public string Url { get; } + /// + /// Gets or sets an indication that the redirect preserves the initial request method. + /// + public bool PreserveMethod { get; } - /// - public Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); + /// + /// Gets or sets the URL to redirect to. + /// + public string Url { get; } - // IsLocalUrl is called to handle URLs starting with '~/'. - var destinationUrl = SharedUrlHelper.IsLocalUrl(Url) ? SharedUrlHelper.Content(httpContext, Url) : Url; + /// + public Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); - Log.RedirectResultExecuting(logger, destinationUrl); + // IsLocalUrl is called to handle URLs starting with '~/'. + var destinationUrl = SharedUrlHelper.IsLocalUrl(Url) ? SharedUrlHelper.Content(httpContext, Url) : Url; - if (PreserveMethod) - { - httpContext.Response.StatusCode = Permanent - ? StatusCodes.Status308PermanentRedirect - : StatusCodes.Status307TemporaryRedirect; - httpContext.Response.Headers.Location = destinationUrl; - } - else - { - httpContext.Response.Redirect(destinationUrl, Permanent); - } + Log.RedirectResultExecuting(logger, destinationUrl); - return Task.CompletedTask; + if (PreserveMethod) + { + httpContext.Response.StatusCode = Permanent + ? StatusCodes.Status308PermanentRedirect + : StatusCodes.Status307TemporaryRedirect; + httpContext.Response.Headers.Location = destinationUrl; } - - private static partial class Log + else { - [LoggerMessage(1, LogLevel.Information, - "Executing RedirectResult, redirecting to {Destination}.", - EventName = "RedirectResultExecuting")] - public static partial void RedirectResultExecuting(ILogger logger, string destination); + httpContext.Response.Redirect(destinationUrl, Permanent); } + + return Task.CompletedTask; + } + + private static partial class Log + { + [LoggerMessage(1, LogLevel.Information, + "Executing RedirectResult, redirecting to {Destination}.", + EventName = "RedirectResultExecuting")] + public static partial void RedirectResultExecuting(ILogger logger, string destination); } } diff --git a/src/Http/Http.Results/src/RedirectToRouteResult.cs b/src/Http/Http.Results/src/RedirectToRouteResult.cs index e531a11837..b45ca52995 100644 --- a/src/Http/Http.Results/src/RedirectToRouteResult.cs +++ b/src/Http/Http.Results/src/RedirectToRouteResult.cs @@ -7,188 +7,187 @@ using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// An that returns a Found (302), Moved Permanently (301), Temporary Redirect (307), +/// or Permanent Redirect (308) response with a Location header. +/// Targets a registered route. +/// +internal sealed partial class RedirectToRouteResult : IResult { /// - /// An that returns a Found (302), Moved Permanently (301), Temporary Redirect (307), - /// or Permanent Redirect (308) response with a Location header. - /// Targets a registered route. + /// Initializes a new instance of the with the values + /// provided. /// - internal sealed partial class RedirectToRouteResult : IResult + /// The parameters for the route. + public RedirectToRouteResult(object? routeValues) + : this(routeName: null, routeValues: routeValues) { - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The parameters for the route. - public RedirectToRouteResult(object? routeValues) - : this(routeName: null, routeValues: routeValues) - { - } + } - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The name of the route. - /// The parameters for the route. - public RedirectToRouteResult( - string? routeName, - object? routeValues) - : this(routeName, routeValues, permanent: false) - { - } + /// + /// Initializes a new instance of the with the values + /// provided. + /// + /// The name of the route. + /// The parameters for the route. + public RedirectToRouteResult( + string? routeName, + object? routeValues) + : this(routeName, routeValues, permanent: false) + { + } - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The name of the route. - /// The parameters for the route. - /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). - public RedirectToRouteResult( - string? routeName, - object? routeValues, - bool permanent) - : this(routeName, routeValues, permanent, fragment: null) - { - } + /// + /// Initializes a new instance of the with the values + /// provided. + /// + /// The name of the route. + /// The parameters for the route. + /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). + public RedirectToRouteResult( + string? routeName, + object? routeValues, + bool permanent) + : this(routeName, routeValues, permanent, fragment: null) + { + } - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The name of the route. - /// The parameters for the route. - /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. - public RedirectToRouteResult( - string? routeName, - object? routeValues, - bool permanent, - bool preserveMethod) - : this(routeName, routeValues, permanent, preserveMethod, fragment: null) - { - } + /// + /// Initializes a new instance of the with the values + /// provided. + /// + /// The name of the route. + /// The parameters for the route. + /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. + public RedirectToRouteResult( + string? routeName, + object? routeValues, + bool permanent, + bool preserveMethod) + : this(routeName, routeValues, permanent, preserveMethod, fragment: null) + { + } - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The name of the route. - /// The parameters for the route. - /// The fragment to add to the URL. - public RedirectToRouteResult( - string? routeName, - object? routeValues, - string? fragment) - : this(routeName, routeValues, permanent: false, fragment: fragment) - { - } + /// + /// Initializes a new instance of the with the values + /// provided. + /// + /// The name of the route. + /// The parameters for the route. + /// The fragment to add to the URL. + public RedirectToRouteResult( + string? routeName, + object? routeValues, + string? fragment) + : this(routeName, routeValues, permanent: false, fragment: fragment) + { + } - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The name of the route. - /// The parameters for the route. - /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). - /// The fragment to add to the URL. - public RedirectToRouteResult( - string? routeName, - object? routeValues, - bool permanent, - string? fragment) - : this(routeName, routeValues, permanent, preserveMethod: false, fragment: fragment) - { - } + /// + /// Initializes a new instance of the with the values + /// provided. + /// + /// The name of the route. + /// The parameters for the route. + /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). + /// The fragment to add to the URL. + public RedirectToRouteResult( + string? routeName, + object? routeValues, + bool permanent, + string? fragment) + : this(routeName, routeValues, permanent, preserveMethod: false, fragment: fragment) + { + } + + /// + /// Initializes a new instance of the with the values + /// provided. + /// + /// The name of the route. + /// The parameters for the route. + /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. + /// The fragment to add to the URL. + public RedirectToRouteResult( + string? routeName, + object? routeValues, + bool permanent, + bool preserveMethod, + string? fragment) + { + RouteName = routeName; + RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues); + PreserveMethod = preserveMethod; + Permanent = permanent; + Fragment = fragment; + } + + /// + /// Gets or sets the name of the route to use for generating the URL. + /// + public string? RouteName { get; } + + /// + /// Gets or sets the route data to use for generating the URL. + /// + public RouteValueDictionary? RouteValues { get; } + + /// + /// Gets or sets an indication that the redirect is permanent. + /// + public bool Permanent { get; } + + /// + /// Gets or sets an indication that the redirect preserves the initial request method. + /// + public bool PreserveMethod { get; } + + /// + /// Gets or sets the fragment to add to the URL. + /// + public string? Fragment { get; } - /// - /// Initializes a new instance of the with the values - /// provided. - /// - /// The name of the route. - /// The parameters for the route. - /// If set to true, makes the redirect permanent (301). Otherwise a temporary redirect is used (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. - /// The fragment to add to the URL. - public RedirectToRouteResult( - string? routeName, - object? routeValues, - bool permanent, - bool preserveMethod, - string? fragment) + /// + public Task ExecuteAsync(HttpContext httpContext) + { + var linkGenerator = httpContext.RequestServices.GetRequiredService(); + + var destinationUrl = linkGenerator.GetUriByRouteValues( + httpContext, + RouteName, + RouteValues, + fragment: Fragment == null ? FragmentString.Empty : new FragmentString("#" + Fragment)); + if (string.IsNullOrEmpty(destinationUrl)) { - RouteName = routeName; - RouteValues = routeValues == null ? null : new RouteValueDictionary(routeValues); - PreserveMethod = preserveMethod; - Permanent = permanent; - Fragment = fragment; + throw new InvalidOperationException("No route matches the supplied values."); } - /// - /// Gets or sets the name of the route to use for generating the URL. - /// - public string? RouteName { get; } - - /// - /// Gets or sets the route data to use for generating the URL. - /// - public RouteValueDictionary? RouteValues { get; } - - /// - /// Gets or sets an indication that the redirect is permanent. - /// - public bool Permanent { get; } - - /// - /// Gets or sets an indication that the redirect preserves the initial request method. - /// - public bool PreserveMethod { get; } - - /// - /// Gets or sets the fragment to add to the URL. - /// - public string? Fragment { get; } - - /// - public Task ExecuteAsync(HttpContext httpContext) + var logger = httpContext.RequestServices.GetRequiredService>(); + Log.RedirectToRouteResultExecuting(logger, destinationUrl, RouteName); + + if (PreserveMethod) { - var linkGenerator = httpContext.RequestServices.GetRequiredService(); - - var destinationUrl = linkGenerator.GetUriByRouteValues( - httpContext, - RouteName, - RouteValues, - fragment: Fragment == null ? FragmentString.Empty : new FragmentString("#" + Fragment)); - if (string.IsNullOrEmpty(destinationUrl)) - { - throw new InvalidOperationException("No route matches the supplied values."); - } - - var logger = httpContext.RequestServices.GetRequiredService>(); - Log.RedirectToRouteResultExecuting(logger, destinationUrl, RouteName); - - if (PreserveMethod) - { - httpContext.Response.StatusCode = Permanent ? - StatusCodes.Status308PermanentRedirect : StatusCodes.Status307TemporaryRedirect; - httpContext.Response.Headers.Location = destinationUrl; - } - else - { - httpContext.Response.Redirect(destinationUrl, Permanent); - } - - return Task.CompletedTask; + httpContext.Response.StatusCode = Permanent ? + StatusCodes.Status308PermanentRedirect : StatusCodes.Status307TemporaryRedirect; + httpContext.Response.Headers.Location = destinationUrl; } - - private static partial class Log + else { - [LoggerMessage(1, LogLevel.Information, - "Executing RedirectToRouteResult, redirecting to {Destination} from route {RouteName}.", - EventName = "RedirectToRouteResultExecuting")] - public static partial void RedirectToRouteResultExecuting(ILogger logger, string destination, string? routeName); + httpContext.Response.Redirect(destinationUrl, Permanent); } + + return Task.CompletedTask; + } + + private static partial class Log + { + [LoggerMessage(1, LogLevel.Information, + "Executing RedirectToRouteResult, redirecting to {Destination} from route {RouteName}.", + EventName = "RedirectToRouteResultExecuting")] + public static partial void RedirectToRouteResultExecuting(ILogger logger, string destination, string? routeName); } } diff --git a/src/Http/Http.Results/src/ResultExtensions.cs b/src/Http/Http.Results/src/ResultExtensions.cs index cab72d4ff2..d10a3bd59a 100644 --- a/src/Http/Http.Results/src/ResultExtensions.cs +++ b/src/Http/Http.Results/src/ResultExtensions.cs @@ -1,11 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http -{ - /// - /// Implements an interface for registering external methods that provide - /// custom IResult instances. - /// - internal class ResultExtensions : IResultExtensions { } -} \ No newline at end of file +namespace Microsoft.AspNetCore.Http; + +/// +/// Implements an interface for registering external methods that provide +/// custom IResult instances. +/// +internal class ResultExtensions : IResultExtensions { } diff --git a/src/Http/Http.Results/src/Results.cs b/src/Http/Http.Results/src/Results.cs index 9632ac0a3b..0b7f0a228d 100644 --- a/src/Http/Http.Results/src/Results.cs +++ b/src/Http/Http.Results/src/Results.cs @@ -11,622 +11,621 @@ using Microsoft.AspNetCore.Http.Result; using Microsoft.AspNetCore.Mvc; using Microsoft.Net.Http.Headers; -namespace Microsoft.AspNetCore.Http +namespace Microsoft.AspNetCore.Http; + +/// +/// A factory for . +/// +public static class Results { /// - /// A factory for . + /// Creates an that on execution invokes . + /// + /// The behavior of this method depends on the in use. + /// and + /// are among likely status results. + /// + /// + /// used to perform the authentication + /// challenge. + /// The authentication schemes to challenge. + /// The created for the response. + public static IResult Challenge( + AuthenticationProperties? properties = null, + IList? authenticationSchemes = null) + => new ChallengeResult { AuthenticationSchemes = authenticationSchemes ?? Array.Empty(), Properties = properties }; + + /// + /// Creates a that on execution invokes . + /// + /// By default, executing this result returns a . Some authentication schemes, such as cookies, + /// will convert to a redirect to show a login page. + /// + /// + /// used to perform the authentication + /// challenge. + /// The authentication schemes to challenge. + /// The created for the response. + /// + /// Some authentication schemes, such as cookies, will convert to + /// a redirect to show a login page. + /// + public static IResult Forbid(AuthenticationProperties? properties = null, IList? authenticationSchemes = null) + => new ForbidResult { Properties = properties, AuthenticationSchemes = authenticationSchemes ?? Array.Empty(), }; + + /// + /// Creates an that on execution invokes . + /// + /// The containing the user claims. + /// used to perform the sign-in operation. + /// The authentication scheme to use for the sign-in operation. + /// The created for the response. + public static IResult SignIn( + ClaimsPrincipal principal, + AuthenticationProperties? properties = null, + string? authenticationScheme = null) + => new SignInResult(authenticationScheme, principal, properties); + + /// + /// Creates an that on execution invokes . + /// + /// used to perform the sign-out operation. + /// The authentication scheme to use for the sign-out operation. + /// The created for the response. + public static IResult SignOut(AuthenticationProperties? properties = null, IList? authenticationSchemes = null) + => new SignOutResult(authenticationSchemes ?? Array.Empty(), properties); + + /// + /// Writes the string to the HTTP response. + /// + /// This is an alias for . + /// + /// + /// The content to write to the response. + /// The content type (MIME type). + /// The content encoding. + /// The created object for the response. + /// + /// If encoding is provided by both the 'charset' and the parameters, then + /// the parameter is chosen as the final encoding. + /// + public static IResult Content(string content, string? contentType = null, Encoding? contentEncoding = null) + => Text(content, contentType, contentEncoding); + + /// + /// Writes the string to the HTTP response. + /// + /// This is an alias for . + /// /// - public static class Results + /// The content to write to the response. + /// The content type (MIME type). + /// The content encoding. + /// The created object for the response. + /// + /// If encoding is provided by both the 'charset' and the parameters, then + /// the parameter is chosen as the final encoding. + /// + public static IResult Text(string content, string? contentType = null, Encoding? contentEncoding = null) { - /// - /// Creates an that on execution invokes . - /// - /// The behavior of this method depends on the in use. - /// and - /// are among likely status results. - /// - /// - /// used to perform the authentication - /// challenge. - /// The authentication schemes to challenge. - /// The created for the response. - public static IResult Challenge( - AuthenticationProperties? properties = null, - IList? authenticationSchemes = null) - => new ChallengeResult { AuthenticationSchemes = authenticationSchemes ?? Array.Empty(), Properties = properties }; - - /// - /// Creates a that on execution invokes . - /// - /// By default, executing this result returns a . Some authentication schemes, such as cookies, - /// will convert to a redirect to show a login page. - /// - /// - /// used to perform the authentication - /// challenge. - /// The authentication schemes to challenge. - /// The created for the response. - /// - /// Some authentication schemes, such as cookies, will convert to - /// a redirect to show a login page. - /// - public static IResult Forbid(AuthenticationProperties? properties = null, IList? authenticationSchemes = null) - => new ForbidResult { Properties = properties, AuthenticationSchemes = authenticationSchemes ?? Array.Empty(), }; - - /// - /// Creates an that on execution invokes . - /// - /// The containing the user claims. - /// used to perform the sign-in operation. - /// The authentication scheme to use for the sign-in operation. - /// The created for the response. - public static IResult SignIn( - ClaimsPrincipal principal, - AuthenticationProperties? properties = null, - string? authenticationScheme = null) - => new SignInResult(authenticationScheme, principal, properties); - - /// - /// Creates an that on execution invokes . - /// - /// used to perform the sign-out operation. - /// The authentication scheme to use for the sign-out operation. - /// The created for the response. - public static IResult SignOut(AuthenticationProperties? properties = null, IList? authenticationSchemes = null) - => new SignOutResult(authenticationSchemes ?? Array.Empty(), properties); - - /// - /// Writes the string to the HTTP response. - /// - /// This is an alias for . - /// - /// - /// The content to write to the response. - /// The content type (MIME type). - /// The content encoding. - /// The created object for the response. - /// - /// If encoding is provided by both the 'charset' and the parameters, then - /// the parameter is chosen as the final encoding. - /// - public static IResult Content(string content, string? contentType = null, Encoding? contentEncoding = null) - => Text(content, contentType, contentEncoding); - - /// - /// Writes the string to the HTTP response. - /// - /// This is an alias for . - /// - /// - /// The content to write to the response. - /// The content type (MIME type). - /// The content encoding. - /// The created object for the response. - /// - /// If encoding is provided by both the 'charset' and the parameters, then - /// the parameter is chosen as the final encoding. - /// - public static IResult Text(string content, string? contentType = null, Encoding? contentEncoding = null) + MediaTypeHeaderValue? mediaTypeHeaderValue = null; + if (contentType is not null) { - MediaTypeHeaderValue? mediaTypeHeaderValue = null; - if (contentType is not null) - { - mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); - mediaTypeHeaderValue.Encoding = contentEncoding ?? mediaTypeHeaderValue.Encoding; - } - - return new ContentResult - { - Content = content, - ContentType = mediaTypeHeaderValue?.ToString() - }; + mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); + mediaTypeHeaderValue.Encoding = contentEncoding ?? mediaTypeHeaderValue.Encoding; } - /// - /// Writes the string to the HTTP response. - /// - /// The content to write to the response. - /// The content type (MIME type). - /// The created object for the response. - public static IResult Content(string content, MediaTypeHeaderValue contentType) - => new ContentResult - { - Content = content, - ContentType = contentType.ToString() - }; + return new ContentResult + { + Content = content, + ContentType = mediaTypeHeaderValue?.ToString() + }; + } - /// - /// Creates a that serializes the specified object to JSON. - /// - /// The object to write as JSON. - /// The serializer options use when serializing the value. - /// The content-type to set on the response. - /// The status code to set on the response. - /// The created that serializes the specified - /// as JSON format for the response. - /// Callers should cache an instance of serializer settings to avoid - /// recreating cached data with each call. - public static IResult Json(object? data, JsonSerializerOptions? options = null, string? contentType = null, int? statusCode = null) - => new JsonResult - { - Value = data, - JsonSerializerOptions = options, - ContentType = contentType, - StatusCode = statusCode, - }; + /// + /// Writes the string to the HTTP response. + /// + /// The content to write to the response. + /// The content type (MIME type). + /// The created object for the response. + public static IResult Content(string content, MediaTypeHeaderValue contentType) + => new ContentResult + { + Content = content, + ContentType = contentType.ToString() + }; - /// - /// Writes the byte-array content to the response. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// This API is an alias for . - /// - /// The file contents. - /// The Content-Type of the file. - /// The suggested file name. - /// Set to true to enable range requests processing. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. + /// + /// Creates a that serializes the specified object to JSON. + /// + /// The object to write as JSON. + /// The serializer options use when serializing the value. + /// The content-type to set on the response. + /// The status code to set on the response. + /// The created that serializes the specified + /// as JSON format for the response. + /// Callers should cache an instance of serializer settings to avoid + /// recreating cached data with each call. + public static IResult Json(object? data, JsonSerializerOptions? options = null, string? contentType = null, int? statusCode = null) + => new JsonResult + { + Value = data, + JsonSerializerOptions = options, + ContentType = contentType, + StatusCode = statusCode, + }; + + /// + /// Writes the byte-array content to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// This API is an alias for . + /// + /// The file contents. + /// The Content-Type of the file. + /// The suggested file name. + /// Set to true to enable range requests processing. + /// The of when the file was last modified. + /// The associated with the file. + /// The created for the response. #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters - public static IResult File( + public static IResult File( #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters byte[] fileContents, - string? contentType = null, - string? fileDownloadName = null, - bool enableRangeProcessing = false, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue? entityTag = null) - => new FileContentResult(fileContents, contentType) - { - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - LastModified = lastModified, - EntityTag = entityTag, - }; + string? contentType = null, + string? fileDownloadName = null, + bool enableRangeProcessing = false, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue? entityTag = null) + => new FileContentResult(fileContents, contentType) + { + FileDownloadName = fileDownloadName, + EnableRangeProcessing = enableRangeProcessing, + LastModified = lastModified, + EntityTag = entityTag, + }; - /// - /// Writes the byte-array content to the response. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// This API is an alias for . - /// - /// The file contents. - /// The Content-Type of the file. - /// The suggested file name. - /// Set to true to enable range requests processing. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult Bytes( - byte[] contents, - string? contentType = null, - string? fileDownloadName = null, - bool enableRangeProcessing = false, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue? entityTag = null) - => new FileContentResult(contents, contentType) - { - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - LastModified = lastModified, - EntityTag = entityTag, - }; + /// + /// Writes the byte-array content to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// This API is an alias for . + /// + /// The file contents. + /// The Content-Type of the file. + /// The suggested file name. + /// Set to true to enable range requests processing. + /// The of when the file was last modified. + /// The associated with the file. + /// The created for the response. + public static IResult Bytes( + byte[] contents, + string? contentType = null, + string? fileDownloadName = null, + bool enableRangeProcessing = false, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue? entityTag = null) + => new FileContentResult(contents, contentType) + { + FileDownloadName = fileDownloadName, + EnableRangeProcessing = enableRangeProcessing, + LastModified = lastModified, + EntityTag = entityTag, + }; - /// - /// Writes the specified to the response. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// This API is an alias for . - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// The the file name to be used in the Content-Disposition header. - /// The of when the file was last modified. - /// Used to configure the Last-Modified response header and perform conditional range requests. - /// The to be configure the ETag response header - /// and perform conditional requests. - /// Set to true to enable range requests processing. - /// The created for the response. - /// - /// The parameter is disposed after the response is sent. - /// + /// + /// Writes the specified to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// This API is an alias for . + /// + /// + /// The with the contents of the file. + /// The Content-Type of the file. + /// The the file name to be used in the Content-Disposition header. + /// The of when the file was last modified. + /// Used to configure the Last-Modified response header and perform conditional range requests. + /// The to be configure the ETag response header + /// and perform conditional requests. + /// Set to true to enable range requests processing. + /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters - public static IResult File( + public static IResult File( #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters Stream fileStream, - string? contentType = null, - string? fileDownloadName = null, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue? entityTag = null, - bool enableRangeProcessing = false) + string? contentType = null, + string? fileDownloadName = null, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue? entityTag = null, + bool enableRangeProcessing = false) + { + return new FileStreamResult(fileStream, contentType) { - return new FileStreamResult(fileStream, contentType) + LastModified = lastModified, + EntityTag = entityTag, + FileDownloadName = fileDownloadName, + EnableRangeProcessing = enableRangeProcessing, + }; + } + + /// + /// Writes the specified to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// This API is an alias for . + /// + /// + /// The to write to the response. + /// The Content-Type of the response. Defaults to application/octet-stream. + /// The the file name to be used in the Content-Disposition header. + /// The of when the file was last modified. + /// Used to configure the Last-Modified response header and perform conditional range requests. + /// The to be configure the ETag response header + /// and perform conditional requests. + /// Set to true to enable range requests processing. + /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// + public static IResult Stream( + Stream stream, + string? contentType = null, + string? fileDownloadName = null, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue? entityTag = null, + bool enableRangeProcessing = false) + { + return new FileStreamResult(stream, contentType) + { + LastModified = lastModified, + EntityTag = entityTag, + FileDownloadName = fileDownloadName, + EnableRangeProcessing = enableRangeProcessing, + }; + } + + /// + /// Writes the file at the specified to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// The path to the file. When not rooted, resolves the path relative to . + /// The Content-Type of the file. + /// The suggested file name. + /// The of when the file was last modified. + /// The associated with the file. + /// Set to true to enable range requests processing. + /// The created for the response. +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters + public static IResult File( +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters + string path, + string? contentType = null, + string? fileDownloadName = null, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue? entityTag = null, + bool enableRangeProcessing = false) + { + if (Path.IsPathRooted(path)) + { + return new PhysicalFileResult(path, contentType) { + FileDownloadName = fileDownloadName, LastModified = lastModified, EntityTag = entityTag, - FileDownloadName = fileDownloadName, EnableRangeProcessing = enableRangeProcessing, }; } - - /// - /// Writes the specified to the response. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// This API is an alias for . - /// - /// - /// The to write to the response. - /// The Content-Type of the response. Defaults to application/octet-stream. - /// The the file name to be used in the Content-Disposition header. - /// The of when the file was last modified. - /// Used to configure the Last-Modified response header and perform conditional range requests. - /// The to be configure the ETag response header - /// and perform conditional requests. - /// Set to true to enable range requests processing. - /// The created for the response. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult Stream( - Stream stream, - string? contentType = null, - string? fileDownloadName = null, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue? entityTag = null, - bool enableRangeProcessing = false) + else { - return new FileStreamResult(stream, contentType) + return new VirtualFileResult(path, contentType) { + FileDownloadName = fileDownloadName, LastModified = lastModified, EntityTag = entityTag, - FileDownloadName = fileDownloadName, EnableRangeProcessing = enableRangeProcessing, }; } + } - /// - /// Writes the file at the specified to the response. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. When not rooted, resolves the path relative to . - /// The Content-Type of the file. - /// The suggested file name. - /// The of when the file was last modified. - /// The associated with the file. - /// Set to true to enable range requests processing. - /// The created for the response. -#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters - public static IResult File( -#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters - string path, - string? contentType = null, - string? fileDownloadName = null, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue? entityTag = null, - bool enableRangeProcessing = false) + /// + /// Redirects to the specified . + /// + /// When and are set, sets the status code. + /// When is set, sets the status code. + /// When is set, sets the status code. + /// Otherwise, configures . + /// + /// + /// The URL to redirect to. + /// Specifies whether the redirect should be permanent (301) or temporary (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. + /// The created for the response. + public static IResult Redirect(string url, bool permanent = false, bool preserveMethod = false) + => new RedirectResult(url, permanent, preserveMethod); + + /// + /// Redirects to the specified . + /// + /// When and are set, sets the status code. + /// When is set, sets the status code. + /// When is set, sets the status code. + /// Otherwise, configures . + /// + /// + /// The local URL to redirect to. + /// Specifies whether the redirect should be permanent (301) or temporary (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. + /// The created for the response. + public static IResult LocalRedirect(string localUrl, bool permanent = false, bool preserveMethod = false) + => new LocalRedirectResult(localUrl, permanent, preserveMethod); + + /// + /// Redirects to the specified route. + /// + /// When and are set, sets the status code. + /// When is set, sets the status code. + /// When is set, sets the status code. + /// Otherwise, configures . + /// + /// + /// The name of the route. + /// The parameters for a route. + /// Specifies whether the redirect should be permanent (301) or temporary (302). + /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. + /// The fragment to add to the URL. + /// The created for the response. + public static IResult RedirectToRoute(string? routeName = null, object? routeValues = null, bool permanent = false, bool preserveMethod = false, string? fragment = null) + => new RedirectToRouteResult( + routeName: routeName, + routeValues: routeValues, + permanent: permanent, + preserveMethod: preserveMethod, + fragment: fragment); + + /// + /// Creates a object by specifying a . + /// + /// The status code to set on the response. + /// The created object for the response. + public static IResult StatusCode(int statusCode) + => new StatusCodeResult(statusCode); + + /// + /// Produces a response. + /// + /// The value to be included in the HTTP response body. + /// The created for the response. + public static IResult NotFound(object? value = null) + => new NotFoundObjectResult(value); + + /// + /// Produces a response. + /// + /// The created for the response. + public static IResult Unauthorized() + => new UnauthorizedResult(); + + /// + /// Produces a response. + /// + /// An error object to be included in the HTTP response body. + /// The created for the response. + public static IResult BadRequest(object? error = null) + => new BadRequestObjectResult(error); + + /// + /// Produces a response. + /// + /// An error object to be included in the HTTP response body. + /// The created for the response. + public static IResult Conflict(object? error = null) + => new ConflictObjectResult(error); + + /// + /// Produces a response. + /// + /// The created for the response. + public static IResult NoContent() + => new NoContentResult(); + + /// + /// Produces a response. + /// + /// The value to be included in the HTTP response body. + /// The created for the response. + public static IResult Ok(object? value = null) + => new OkObjectResult(value); + + /// + /// Produces a response. + /// + /// An error object to be included in the HTTP response body. + /// The created for the response. + public static IResult UnprocessableEntity(object? error = null) + => new UnprocessableEntityObjectResult(error); + + /// + /// Produces a response. + /// + /// The value for . + /// The value for . + /// The value for . + /// The value for . + /// The value for . + /// The value for . + /// The created for the response. + public static IResult Problem( + string? detail = null, + string? instance = null, + int? statusCode = null, + string? title = null, + string? type = null, + IDictionary? extensions = null) + { + var problemDetails = new ProblemDetails { - if (Path.IsPathRooted(path)) - { - return new PhysicalFileResult(path, contentType) - { - FileDownloadName = fileDownloadName, - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; - } - else + Detail = detail, + Instance = instance, + Status = statusCode, + Title = title, + Type = type, + }; + + if (extensions is not null) + { + foreach (var extension in extensions) { - return new VirtualFileResult(path, contentType) - { - FileDownloadName = fileDownloadName, - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; + problemDetails.Extensions.Add(extension); } } - /// - /// Redirects to the specified . - /// - /// When and are set, sets the status code. - /// When is set, sets the status code. - /// When is set, sets the status code. - /// Otherwise, configures . - /// - /// - /// The URL to redirect to. - /// Specifies whether the redirect should be permanent (301) or temporary (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. - /// The created for the response. - public static IResult Redirect(string url, bool permanent = false, bool preserveMethod = false) - => new RedirectResult(url, permanent, preserveMethod); - - /// - /// Redirects to the specified . - /// - /// When and are set, sets the status code. - /// When is set, sets the status code. - /// When is set, sets the status code. - /// Otherwise, configures . - /// - /// - /// The local URL to redirect to. - /// Specifies whether the redirect should be permanent (301) or temporary (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. - /// The created for the response. - public static IResult LocalRedirect(string localUrl, bool permanent = false, bool preserveMethod = false) - => new LocalRedirectResult(localUrl, permanent, preserveMethod); - - /// - /// Redirects to the specified route. - /// - /// When and are set, sets the status code. - /// When is set, sets the status code. - /// When is set, sets the status code. - /// Otherwise, configures . - /// - /// - /// The name of the route. - /// The parameters for a route. - /// Specifies whether the redirect should be permanent (301) or temporary (302). - /// If set to true, make the temporary redirect (307) or permanent redirect (308) preserve the initial request method. - /// The fragment to add to the URL. - /// The created for the response. - public static IResult RedirectToRoute(string? routeName = null, object? routeValues = null, bool permanent = false, bool preserveMethod = false, string? fragment = null) - => new RedirectToRouteResult( - routeName: routeName, - routeValues: routeValues, - permanent: permanent, - preserveMethod: preserveMethod, - fragment: fragment); - - /// - /// Creates a object by specifying a . - /// - /// The status code to set on the response. - /// The created object for the response. - public static IResult StatusCode(int statusCode) - => new StatusCodeResult(statusCode); - - /// - /// Produces a response. - /// - /// The value to be included in the HTTP response body. - /// The created for the response. - public static IResult NotFound(object? value = null) - => new NotFoundObjectResult(value); - - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult Unauthorized() - => new UnauthorizedResult(); - - /// - /// Produces a response. - /// - /// An error object to be included in the HTTP response body. - /// The created for the response. - public static IResult BadRequest(object? error = null) - => new BadRequestObjectResult(error); - - /// - /// Produces a response. - /// - /// An error object to be included in the HTTP response body. - /// The created for the response. - public static IResult Conflict(object? error = null) - => new ConflictObjectResult(error); - - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult NoContent() - => new NoContentResult(); - - /// - /// Produces a response. - /// - /// The value to be included in the HTTP response body. - /// The created for the response. - public static IResult Ok(object? value = null) - => new OkObjectResult(value); - - /// - /// Produces a response. - /// - /// An error object to be included in the HTTP response body. - /// The created for the response. - public static IResult UnprocessableEntity(object? error = null) - => new UnprocessableEntityObjectResult(error); - - /// - /// Produces a response. - /// - /// The value for . - /// The value for . - /// The value for . - /// The value for . - /// The value for . - /// The value for . - /// The created for the response. - public static IResult Problem( - string? detail = null, - string? instance = null, - int? statusCode = null, - string? title = null, - string? type = null, - IDictionary? extensions = null) + return new ObjectResult(problemDetails) { - var problemDetails = new ProblemDetails - { - Detail = detail, - Instance = instance, - Status = statusCode, - Title = title, - Type = type, - }; - - if (extensions is not null) - { - foreach (var extension in extensions) - { - problemDetails.Extensions.Add(extension); - } - } - - return new ObjectResult(problemDetails) - { - ContentType = "application/problem+json", - }; - } + ContentType = "application/problem+json", + }; + } - /// - /// Produces a response. - /// - /// The object to produce a response from. - /// The created for the response. - public static IResult Problem(ProblemDetails problemDetails) + /// + /// Produces a response. + /// + /// The object to produce a response from. + /// The created for the response. + public static IResult Problem(ProblemDetails problemDetails) + { + return new ObjectResult(problemDetails) { - return new ObjectResult(problemDetails) - { - ContentType = "application/problem+json", - }; - } + ContentType = "application/problem+json", + }; + } - /// - /// Produces a response - /// with a value. - /// - /// One or more validation errors. - /// The value for . - /// The value for . - /// The status code. - /// The value for . Defaults to "One or more validation errors occurred." - /// The value for . - /// The value for . - /// The created for the response. - public static IResult ValidationProblem( - IDictionary errors, - string? detail = null, - string? instance = null, - int? statusCode = null, - string? title = null, - string? type = null, - IDictionary? extensions = null) + /// + /// Produces a response + /// with a value. + /// + /// One or more validation errors. + /// The value for . + /// The value for . + /// The status code. + /// The value for . Defaults to "One or more validation errors occurred." + /// The value for . + /// The value for . + /// The created for the response. + public static IResult ValidationProblem( + IDictionary errors, + string? detail = null, + string? instance = null, + int? statusCode = null, + string? title = null, + string? type = null, + IDictionary? extensions = null) + { + var problemDetails = new HttpValidationProblemDetails(errors) { - var problemDetails = new HttpValidationProblemDetails(errors) - { - Detail = detail, - Instance = instance, - Type = type, - Status = statusCode, - }; - - problemDetails.Title = title ?? problemDetails.Title; + Detail = detail, + Instance = instance, + Type = type, + Status = statusCode, + }; - if (extensions is not null) - { - foreach (var extension in extensions) - { - problemDetails.Extensions.Add(extension); - } - } + problemDetails.Title = title ?? problemDetails.Title; - return new ObjectResult(problemDetails) + if (extensions is not null) + { + foreach (var extension in extensions) { - ContentType = "application/problem+json", - }; + problemDetails.Extensions.Add(extension); + } } - /// - /// Produces a response. - /// - /// The URI at which the content has been created. - /// The value to be included in the HTTP response body. - /// The created for the response. - public static IResult Created(string uri, object? value) + return new ObjectResult(problemDetails) { - if (uri == null) - { - throw new ArgumentNullException(nameof(uri)); - } + ContentType = "application/problem+json", + }; + } - return new CreatedResult(uri, value); + /// + /// Produces a response. + /// + /// The URI at which the content has been created. + /// The value to be included in the HTTP response body. + /// The created for the response. + public static IResult Created(string uri, object? value) + { + if (uri == null) + { + throw new ArgumentNullException(nameof(uri)); } - /// - /// Produces a response. - /// - /// The URI at which the content has been created. - /// The value to be included in the HTTP response body. - /// The created for the response. - public static IResult Created(Uri uri, object? value) - { - if (uri == null) - { - throw new ArgumentNullException(nameof(uri)); - } + return new CreatedResult(uri, value); + } - return new CreatedResult(uri, value); + /// + /// Produces a response. + /// + /// The URI at which the content has been created. + /// The value to be included in the HTTP response body. + /// The created for the response. + public static IResult Created(Uri uri, object? value) + { + if (uri == null) + { + throw new ArgumentNullException(nameof(uri)); } - /// - /// Produces a response. - /// - /// The name of the route to use for generating the URL. - /// The route data to use for generating the URL. - /// The value to be included in the HTTP response body. - /// The created for the response. - public static IResult CreatedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) - => new CreatedAtRouteResult(routeName, routeValues, value); - - /// - /// Produces a response. - /// - /// The URI with the location at which the status of requested content can be monitored. - /// The optional content value to format in the response body. - /// The created for the response. - public static IResult Accepted(string? uri = null, object? value = null) - => new AcceptedResult(uri, value); - - /// - /// Produces a response. - /// - /// The name of the route to use for generating the URL. - /// The route data to use for generating the URL. - /// The optional content value to format in the response body. - /// The created for the response. - public static IResult AcceptedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) - => new AcceptedAtRouteResult(routeName, routeValues, value); - - /// - /// Provides a container for external libraries to extend - /// the default `Results` set with their own samples. - /// - public static IResultExtensions Extensions { get; } = new ResultExtensions(); + return new CreatedResult(uri, value); } + + /// + /// Produces a response. + /// + /// The name of the route to use for generating the URL. + /// The route data to use for generating the URL. + /// The value to be included in the HTTP response body. + /// The created for the response. + public static IResult CreatedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) + => new CreatedAtRouteResult(routeName, routeValues, value); + + /// + /// Produces a response. + /// + /// The URI with the location at which the status of requested content can be monitored. + /// The optional content value to format in the response body. + /// The created for the response. + public static IResult Accepted(string? uri = null, object? value = null) + => new AcceptedResult(uri, value); + + /// + /// Produces a response. + /// + /// The name of the route to use for generating the URL. + /// The route data to use for generating the URL. + /// The optional content value to format in the response body. + /// The created for the response. + public static IResult AcceptedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) + => new AcceptedAtRouteResult(routeName, routeValues, value); + + /// + /// Provides a container for external libraries to extend + /// the default `Results` set with their own samples. + /// + public static IResultExtensions Extensions { get; } = new ResultExtensions(); } diff --git a/src/Http/Http.Results/src/SignInResult.cs b/src/Http/Http.Results/src/SignInResult.cs index 3efa8919d5..9ce2b632d4 100644 --- a/src/Http/Http.Results/src/SignInResult.cs +++ b/src/Http/Http.Results/src/SignInResult.cs @@ -8,90 +8,89 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// An that on execution invokes . +/// +internal sealed partial class SignInResult : IResult { /// - /// An that on execution invokes . + /// Initializes a new instance of with the + /// default authentication scheme. /// - internal sealed partial class SignInResult : IResult + /// The claims principal containing the user claims. + public SignInResult(ClaimsPrincipal principal) + : this(authenticationScheme: null, principal, properties: null) { - /// - /// Initializes a new instance of with the - /// default authentication scheme. - /// - /// The claims principal containing the user claims. - public SignInResult(ClaimsPrincipal principal) - : this(authenticationScheme: null, principal, properties: null) - { - } + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme. - /// - /// The authentication scheme to use when signing in the user. - /// The claims principal containing the user claims. - public SignInResult(string? authenticationScheme, ClaimsPrincipal principal) - : this(authenticationScheme, principal, properties: null) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme. + /// + /// The authentication scheme to use when signing in the user. + /// The claims principal containing the user claims. + public SignInResult(string? authenticationScheme, ClaimsPrincipal principal) + : this(authenticationScheme, principal, properties: null) + { + } - /// - /// Initializes a new instance of with the - /// default authentication scheme and . - /// - /// The claims principal containing the user claims. - /// used to perform the sign-in operation. - public SignInResult(ClaimsPrincipal principal, AuthenticationProperties? properties) - : this(authenticationScheme: null, principal, properties) - { - } + /// + /// Initializes a new instance of with the + /// default authentication scheme and . + /// + /// The claims principal containing the user claims. + /// used to perform the sign-in operation. + public SignInResult(ClaimsPrincipal principal, AuthenticationProperties? properties) + : this(authenticationScheme: null, principal, properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme and . - /// - /// The authentication schemes to use when signing in the user. - /// The claims principal containing the user claims. - /// used to perform the sign-in operation. - public SignInResult(string? authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties? properties) - { - Principal = principal ?? throw new ArgumentNullException(nameof(principal)); - AuthenticationScheme = authenticationScheme; - Properties = properties; - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme and . + /// + /// The authentication schemes to use when signing in the user. + /// The claims principal containing the user claims. + /// used to perform the sign-in operation. + public SignInResult(string? authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties? properties) + { + Principal = principal ?? throw new ArgumentNullException(nameof(principal)); + AuthenticationScheme = authenticationScheme; + Properties = properties; + } - /// - /// Gets or sets the authentication scheme that is used to perform the sign-in operation. - /// - public string? AuthenticationScheme { get; set; } + /// + /// Gets or sets the authentication scheme that is used to perform the sign-in operation. + /// + public string? AuthenticationScheme { get; set; } - /// - /// Gets or sets the containing the user claims. - /// - public ClaimsPrincipal Principal { get; set; } + /// + /// Gets or sets the containing the user claims. + /// + public ClaimsPrincipal Principal { get; set; } - /// - /// Gets or sets the used to perform the sign-in operation. - /// - public AuthenticationProperties? Properties { get; set; } + /// + /// Gets or sets the used to perform the sign-in operation. + /// + public AuthenticationProperties? Properties { get; set; } - /// - public Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); + /// + public Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); - Log.SignInResultExecuting(logger, AuthenticationScheme, Principal); + Log.SignInResultExecuting(logger, AuthenticationScheme, Principal); - return httpContext.SignInAsync(AuthenticationScheme, Principal, Properties); - } + return httpContext.SignInAsync(AuthenticationScheme, Principal, Properties); + } - private static partial class Log - { - [LoggerMessage(1, LogLevel.Information, - "Executing SignInResult with authentication scheme ({Scheme}) and the following principal: {Principal}.", - EventName = "SignInResultExecuting")] - public static partial void SignInResultExecuting(ILogger logger, string? scheme, ClaimsPrincipal principal); - } + private static partial class Log + { + [LoggerMessage(1, LogLevel.Information, + "Executing SignInResult with authentication scheme ({Scheme}) and the following principal: {Principal}.", + EventName = "SignInResultExecuting")] + public static partial void SignInResultExecuting(ILogger logger, string? scheme, ClaimsPrincipal principal); } } diff --git a/src/Http/Http.Results/src/SignOutResult.cs b/src/Http/Http.Results/src/SignOutResult.cs index 6698aa71e4..7b99b5a1fa 100644 --- a/src/Http/Http.Results/src/SignOutResult.cs +++ b/src/Http/Http.Results/src/SignOutResult.cs @@ -9,119 +9,118 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// An that on execution invokes . +/// +internal sealed partial class SignOutResult : IResult { /// - /// An that on execution invokes . + /// Initializes a new instance of with the default sign out scheme. /// - internal sealed partial class SignOutResult : IResult + public SignOutResult() + : this(Array.Empty()) { - /// - /// Initializes a new instance of with the default sign out scheme. - /// - public SignOutResult() - : this(Array.Empty()) - { - } + } - /// - /// Initializes a new instance of with the default sign out scheme. - /// specified authentication scheme and . - /// - /// used to perform the sign-out operation. - public SignOutResult(AuthenticationProperties properties) - : this(Array.Empty(), properties) - { - } + /// + /// Initializes a new instance of with the default sign out scheme. + /// specified authentication scheme and . + /// + /// used to perform the sign-out operation. + public SignOutResult(AuthenticationProperties properties) + : this(Array.Empty(), properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme. - /// - /// The authentication scheme to use when signing out the user. - public SignOutResult(string authenticationScheme) - : this(new[] { authenticationScheme }) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme. + /// + /// The authentication scheme to use when signing out the user. + public SignOutResult(string authenticationScheme) + : this(new[] { authenticationScheme }) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication schemes. - /// - /// The authentication schemes to use when signing out the user. - public SignOutResult(IList authenticationSchemes) - : this(authenticationSchemes, properties: null) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication schemes. + /// + /// The authentication schemes to use when signing out the user. + public SignOutResult(IList authenticationSchemes) + : this(authenticationSchemes, properties: null) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication scheme and . - /// - /// The authentication schemes to use when signing out the user. - /// used to perform the sign-out operation. - public SignOutResult(string authenticationScheme, AuthenticationProperties? properties) - : this(new[] { authenticationScheme }, properties) - { - } + /// + /// Initializes a new instance of with the + /// specified authentication scheme and . + /// + /// The authentication schemes to use when signing out the user. + /// used to perform the sign-out operation. + public SignOutResult(string authenticationScheme, AuthenticationProperties? properties) + : this(new[] { authenticationScheme }, properties) + { + } - /// - /// Initializes a new instance of with the - /// specified authentication schemes and . - /// - /// The authentication scheme to use when signing out the user. - /// used to perform the sign-out operation. - public SignOutResult(IList authenticationSchemes, AuthenticationProperties? properties) - { - AuthenticationSchemes = authenticationSchemes ?? throw new ArgumentNullException(nameof(authenticationSchemes)); - Properties = properties; - } + /// + /// Initializes a new instance of with the + /// specified authentication schemes and . + /// + /// The authentication scheme to use when signing out the user. + /// used to perform the sign-out operation. + public SignOutResult(IList authenticationSchemes, AuthenticationProperties? properties) + { + AuthenticationSchemes = authenticationSchemes ?? throw new ArgumentNullException(nameof(authenticationSchemes)); + Properties = properties; + } - /// - /// Gets or sets the authentication schemes that are challenged. - /// - public IList AuthenticationSchemes { get; init; } + /// + /// Gets or sets the authentication schemes that are challenged. + /// + public IList AuthenticationSchemes { get; init; } - /// - /// Gets or sets the used to perform the sign-out operation. - /// - public AuthenticationProperties? Properties { get; init; } + /// + /// Gets or sets the used to perform the sign-out operation. + /// + public AuthenticationProperties? Properties { get; init; } - /// - public async Task ExecuteAsync(HttpContext httpContext) - { - var logger = httpContext.RequestServices.GetRequiredService>(); + /// + public async Task ExecuteAsync(HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); - Log.SignOutResultExecuting(logger, AuthenticationSchemes); + Log.SignOutResultExecuting(logger, AuthenticationSchemes); - if (AuthenticationSchemes.Count == 0) - { - await httpContext.SignOutAsync(Properties); - } - else + if (AuthenticationSchemes.Count == 0) + { + await httpContext.SignOutAsync(Properties); + } + else + { + for (var i = 0; i < AuthenticationSchemes.Count; i++) { - for (var i = 0; i < AuthenticationSchemes.Count; i++) - { - await httpContext.SignOutAsync(AuthenticationSchemes[i], Properties); - } + await httpContext.SignOutAsync(AuthenticationSchemes[i], Properties); } } + } - private static partial class Log + private static partial class Log + { + public static void SignOutResultExecuting(ILogger logger, IList authenticationSchemes) { - public static void SignOutResultExecuting(ILogger logger, IList authenticationSchemes) + if (logger.IsEnabled(LogLevel.Information)) { - if (logger.IsEnabled(LogLevel.Information)) - { - SignOutResultExecuting(logger, authenticationSchemes.ToArray()); - } + SignOutResultExecuting(logger, authenticationSchemes.ToArray()); } - - [LoggerMessage(1, LogLevel.Information, - "Executing SignOutResult with authentication schemes ({Schemes}).", - EventName = "SignOutResultExecuting", - SkipEnabledCheck = true)] - private static partial void SignOutResultExecuting(ILogger logger, string[] schemes); } + + [LoggerMessage(1, LogLevel.Information, + "Executing SignOutResult with authentication schemes ({Schemes}).", + EventName = "SignOutResultExecuting", + SkipEnabledCheck = true)] + private static partial void SignOutResultExecuting(ILogger logger, string[] schemes); } } diff --git a/src/Http/Http.Results/src/StatusCodeResult.cs b/src/Http/Http.Results/src/StatusCodeResult.cs index 0a7c171f51..58d1461329 100644 --- a/src/Http/Http.Results/src/StatusCodeResult.cs +++ b/src/Http/Http.Results/src/StatusCodeResult.cs @@ -5,47 +5,46 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal partial class StatusCodeResult : IResult { - internal partial class StatusCodeResult : IResult + /// + /// Initializes a new instance of the class + /// with the given . + /// + /// The HTTP status code of the response. + public StatusCodeResult(int statusCode) + { + StatusCode = statusCode; + } + + /// + /// Gets the HTTP status code. + /// + public int StatusCode { get; } + + /// + /// Sets the status code on the HTTP response. + /// + /// The for the current request. + /// A task that represents the asynchronous execute operation. + public Task ExecuteAsync(HttpContext httpContext) + { + var factory = httpContext.RequestServices.GetRequiredService(); + var logger = factory.CreateLogger(GetType()); + + Log.StatusCodeResultExecuting(logger, StatusCode); + + httpContext.Response.StatusCode = StatusCode; + return Task.CompletedTask; + } + + private static partial class Log { - /// - /// Initializes a new instance of the class - /// with the given . - /// - /// The HTTP status code of the response. - public StatusCodeResult(int statusCode) - { - StatusCode = statusCode; - } - - /// - /// Gets the HTTP status code. - /// - public int StatusCode { get; } - - /// - /// Sets the status code on the HTTP response. - /// - /// The for the current request. - /// A task that represents the asynchronous execute operation. - public Task ExecuteAsync(HttpContext httpContext) - { - var factory = httpContext.RequestServices.GetRequiredService(); - var logger = factory.CreateLogger(GetType()); - - Log.StatusCodeResultExecuting(logger, StatusCode); - - httpContext.Response.StatusCode = StatusCode; - return Task.CompletedTask; - } - - private static partial class Log - { - [LoggerMessage(1, LogLevel.Information, - "Executing StatusCodeResult, setting HTTP status code {StatusCode}.", - EventName = "StatusCodeResultExecuting")] - public static partial void StatusCodeResultExecuting(ILogger logger, int statusCode); - } + [LoggerMessage(1, LogLevel.Information, + "Executing StatusCodeResult, setting HTTP status code {StatusCode}.", + EventName = "StatusCodeResultExecuting")] + public static partial void StatusCodeResultExecuting(ILogger logger, int statusCode); } } diff --git a/src/Http/Http.Results/src/UnauthorizedResult.cs b/src/Http/Http.Results/src/UnauthorizedResult.cs index fd2135362e..28ec97eaf4 100644 --- a/src/Http/Http.Results/src/UnauthorizedResult.cs +++ b/src/Http/Http.Results/src/UnauthorizedResult.cs @@ -1,12 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class UnauthorizedResult : StatusCodeResult { - internal sealed class UnauthorizedResult : StatusCodeResult + public UnauthorizedResult() : base(StatusCodes.Status401Unauthorized) { - public UnauthorizedResult() : base(StatusCodes.Status401Unauthorized) - { - } } } diff --git a/src/Http/Http.Results/src/UnprocessableEntityObjectResult.cs b/src/Http/Http.Results/src/UnprocessableEntityObjectResult.cs index 3be9fa3608..fd7b456eb8 100644 --- a/src/Http/Http.Results/src/UnprocessableEntityObjectResult.cs +++ b/src/Http/Http.Results/src/UnprocessableEntityObjectResult.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class UnprocessableEntityObjectResult : ObjectResult { - internal sealed class UnprocessableEntityObjectResult : ObjectResult + public UnprocessableEntityObjectResult(object? error) + : base(error, StatusCodes.Status422UnprocessableEntity) { - public UnprocessableEntityObjectResult(object? error) - : base(error, StatusCodes.Status422UnprocessableEntity) - { - } } } diff --git a/src/Http/Http.Results/src/VirtualFileResult.cs b/src/Http/Http.Results/src/VirtualFileResult.cs index b5cb0bc9e4..2e83b13625 100644 --- a/src/Http/Http.Results/src/VirtualFileResult.cs +++ b/src/Http/Http.Results/src/VirtualFileResult.cs @@ -8,106 +8,105 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +/// +/// A that on execution writes the file specified using a virtual path to the response +/// using mechanisms provided by the host. +/// +internal sealed class VirtualFileResult : FileResult, IResult { + private string _fileName; + /// - /// A that on execution writes the file specified using a virtual path to the response - /// using mechanisms provided by the host. + /// Creates a new instance with the provided + /// and the provided . /// - internal sealed class VirtualFileResult : FileResult, IResult + /// The path to the file. The path must be relative/virtual. + /// The Content-Type header of the response. + public VirtualFileResult(string fileName, string? contentType) + : base(contentType) { - private string _fileName; - - /// - /// Creates a new instance with the provided - /// and the provided . - /// - /// The path to the file. The path must be relative/virtual. - /// The Content-Type header of the response. - public VirtualFileResult(string fileName, string? contentType) - : base(contentType) + FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); + } + + /// + /// Gets or sets the path to the file that will be sent back as the response. + /// + public string FileName + { + get => _fileName; + [MemberNotNull(nameof(_fileName))] + set => _fileName = value ?? throw new ArgumentNullException(nameof(value)); + } + + /// + public Task ExecuteAsync(HttpContext httpContext) + { + var hostingEnvironment = httpContext.RequestServices.GetRequiredService(); + var logger = httpContext.RequestServices.GetRequiredService>(); + + var fileInfo = GetFileInformation(hostingEnvironment.WebRootFileProvider); + if (!fileInfo.Exists) { - FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); + throw new FileNotFoundException($"Could not find file: {FileName}.", FileName); } - /// - /// Gets or sets the path to the file that will be sent back as the response. - /// - public string FileName + Log.ExecutingFileResult(logger, this); + + var lastModified = LastModified ?? fileInfo.LastModified; + var fileResultInfo = new FileResultInfo + { + ContentType = ContentType, + FileDownloadName = FileDownloadName, + EnableRangeProcessing = EnableRangeProcessing, + EntityTag = EntityTag, + LastModified = lastModified, + }; + + var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( + httpContext, + fileResultInfo, + fileInfo.Length, + EnableRangeProcessing, + lastModified, + EntityTag, + logger); + + if (!serveBody) { - get => _fileName; - [MemberNotNull(nameof(_fileName))] - set => _fileName = value ?? throw new ArgumentNullException(nameof(value)); + return Task.CompletedTask; } - /// - public Task ExecuteAsync(HttpContext httpContext) + if (range != null) { - var hostingEnvironment = httpContext.RequestServices.GetRequiredService(); - var logger = httpContext.RequestServices.GetRequiredService>(); - - var fileInfo = GetFileInformation(hostingEnvironment.WebRootFileProvider); - if (!fileInfo.Exists) - { - throw new FileNotFoundException($"Could not find file: {FileName}.", FileName); - } - - Log.ExecutingFileResult(logger, this); - - var lastModified = LastModified ?? fileInfo.LastModified; - var fileResultInfo = new FileResultInfo - { - ContentType = ContentType, - FileDownloadName = FileDownloadName, - EnableRangeProcessing = EnableRangeProcessing, - EntityTag = EntityTag, - LastModified = lastModified, - }; - - var (range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( - httpContext, - fileResultInfo, - fileInfo.Length, - EnableRangeProcessing, - lastModified, - EntityTag, - logger); - - if (!serveBody) - { - return Task.CompletedTask; - } - - if (range != null) - { - FileResultHelper.Log.WritingRangeToBody(logger); - } - - var response = httpContext.Response; - var offset = 0L; - var count = (long?)null; - if (range != null) - { - offset = range.From ?? 0L; - count = rangeLength; - } - - return response.SendFileAsync( - fileInfo, - offset, - count); + FileResultHelper.Log.WritingRangeToBody(logger); } - internal IFileInfo GetFileInformation(IFileProvider fileProvider) + var response = httpContext.Response; + var offset = 0L; + var count = (long?)null; + if (range != null) { - var normalizedPath = FileName; - if (normalizedPath.StartsWith("~", StringComparison.Ordinal)) - { - normalizedPath = normalizedPath.Substring(1); - } - - var fileInfo = fileProvider.GetFileInfo(normalizedPath); - return fileInfo; + offset = range.From ?? 0L; + count = rangeLength; } + + return response.SendFileAsync( + fileInfo, + offset, + count); + } + + internal IFileInfo GetFileInformation(IFileProvider fileProvider) + { + var normalizedPath = FileName; + if (normalizedPath.StartsWith("~", StringComparison.Ordinal)) + { + normalizedPath = normalizedPath.Substring(1); + } + + var fileInfo = fileProvider.GetFileInfo(normalizedPath); + return fileInfo; } } diff --git a/src/Http/Http.Results/test/AcceptedAtRouteResultTests.cs b/src/Http/Http.Results/test/AcceptedAtRouteResultTests.cs index c2f1e31339..f9626d7df5 100644 --- a/src/Http/Http.Results/test/AcceptedAtRouteResultTests.cs +++ b/src/Http/Http.Results/test/AcceptedAtRouteResultTests.cs @@ -12,43 +12,43 @@ using Microsoft.Extensions.DependencyInjection; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class AcceptedAtRouteResultTests { - public class AcceptedAtRouteResultTests + [Fact] + public async Task ExecuteResultAsync_FormatsData() { - [Fact] - public async Task ExecuteResultAsync_FormatsData() - { - // Arrange - var url = "testAction"; - var linkGenerator = new TestLinkGenerator { Url = url }; - var httpContext = GetHttpContext(linkGenerator); - var stream = new MemoryStream(); - httpContext.Response.Body = stream; + // Arrange + var url = "testAction"; + var linkGenerator = new TestLinkGenerator { Url = url }; + var httpContext = GetHttpContext(linkGenerator); + var stream = new MemoryStream(); + httpContext.Response.Body = stream; - var routeValues = new RouteValueDictionary(new Dictionary() + var routeValues = new RouteValueDictionary(new Dictionary() { { "test", "case" }, { "sample", "route" } }); - // Act - var result = new AcceptedAtRouteResult( - routeName: "sample", - routeValues: routeValues, - value: "Hello world"); - await result.ExecuteAsync(httpContext); + // Act + var result = new AcceptedAtRouteResult( + routeName: "sample", + routeValues: routeValues, + value: "Hello world"); + await result.ExecuteAsync(httpContext); - // Assert - var response = Encoding.UTF8.GetString(stream.ToArray()); - Assert.Equal("\"Hello world\"", response); - } + // Assert + var response = Encoding.UTF8.GetString(stream.ToArray()); + Assert.Equal("\"Hello world\"", response); + } - public static TheoryData AcceptedAtRouteData + public static TheoryData AcceptedAtRouteData + { + get { - get - { - return new TheoryData + return new TheoryData { null, new Dictionary() @@ -62,59 +62,58 @@ namespace Microsoft.AspNetCore.Http.Result { "sample", "route" } }), }; - } } + } - [Theory] - [MemberData(nameof(AcceptedAtRouteData))] - public async Task ExecuteResultAsync_SetsStatusCodeAndLocationHeader(object values) - { - // Arrange - var expectedUrl = "testAction"; - var linkGenerator = new TestLinkGenerator { Url = expectedUrl }; - var httpContext = GetHttpContext(linkGenerator); + [Theory] + [MemberData(nameof(AcceptedAtRouteData))] + public async Task ExecuteResultAsync_SetsStatusCodeAndLocationHeader(object values) + { + // Arrange + var expectedUrl = "testAction"; + var linkGenerator = new TestLinkGenerator { Url = expectedUrl }; + var httpContext = GetHttpContext(linkGenerator); - // Act - var result = new AcceptedAtRouteResult(routeValues: values, value: null); - await result.ExecuteAsync(httpContext); + // Act + var result = new AcceptedAtRouteResult(routeValues: values, value: null); + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status202Accepted, httpContext.Response.StatusCode); - Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); - } + // Assert + Assert.Equal(StatusCodes.Status202Accepted, httpContext.Response.StatusCode); + Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); + } - [Fact] - public async Task ExecuteResultAsync_ThrowsIfRouteUrlIsNull() - { - // Arrange - var linkGenerator = new TestLinkGenerator(); - var httpContext = GetHttpContext(linkGenerator); + [Fact] + public async Task ExecuteResultAsync_ThrowsIfRouteUrlIsNull() + { + // Arrange + var linkGenerator = new TestLinkGenerator(); + var httpContext = GetHttpContext(linkGenerator); - // Act - var result = new AcceptedAtRouteResult( - routeName: null, - routeValues: new Dictionary(), - value: null); + // Act + var result = new AcceptedAtRouteResult( + routeName: null, + routeValues: new Dictionary(), + value: null); - // Assert - await ExceptionAssert.ThrowsAsync(() => - result.ExecuteAsync(httpContext), - "No route matches the supplied values."); - } + // Assert + await ExceptionAssert.ThrowsAsync(() => + result.ExecuteAsync(httpContext), + "No route matches the supplied values."); + } - private static HttpContext GetHttpContext(LinkGenerator linkGenerator) - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(linkGenerator); - return httpContext; - } + private static HttpContext GetHttpContext(LinkGenerator linkGenerator) + { + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices(linkGenerator); + return httpContext; + } - private static IServiceProvider CreateServices(LinkGenerator linkGenerator) - { - var services = new ServiceCollection(); - services.AddLogging(); - services.AddSingleton(linkGenerator); - return services.BuildServiceProvider(); - } + private static IServiceProvider CreateServices(LinkGenerator linkGenerator) + { + var services = new ServiceCollection(); + services.AddLogging(); + services.AddSingleton(linkGenerator); + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/AcceptedResultTests.cs b/src/Http/Http.Results/test/AcceptedResultTests.cs index bb54726153..3074a1c50f 100644 --- a/src/Http/Http.Results/test/AcceptedResultTests.cs +++ b/src/Http/Http.Results/test/AcceptedResultTests.cs @@ -8,54 +8,53 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class AcceptedResultTests { - public class AcceptedResultTests + [Fact] + public async Task ExecuteResultAsync_FormatsData() + { + // Arrange + var httpContext = GetHttpContext(); + var stream = new MemoryStream(); + httpContext.Response.Body = stream; + // Act + var result = new AcceptedResult("my-location", value: "Hello world"); + await result.ExecuteAsync(httpContext); + + // Assert + var response = Encoding.UTF8.GetString(stream.ToArray()); + Assert.Equal("\"Hello world\"", response); + } + + [Fact] + public async Task ExecuteResultAsync_SetsStatusCodeAndLocationHeader() + { + // Arrange + var expectedUrl = "testAction"; + var httpContext = GetHttpContext(); + + // Act + var result = new AcceptedResult(expectedUrl, value: "some-value"); + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(StatusCodes.Status202Accepted, httpContext.Response.StatusCode); + Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); + } + + private static HttpContext GetHttpContext() + { + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices(); + return httpContext; + } + + private static IServiceProvider CreateServices() { - [Fact] - public async Task ExecuteResultAsync_FormatsData() - { - // Arrange - var httpContext = GetHttpContext(); - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - // Act - var result = new AcceptedResult("my-location", value: "Hello world"); - await result.ExecuteAsync(httpContext); - - // Assert - var response = Encoding.UTF8.GetString(stream.ToArray()); - Assert.Equal("\"Hello world\"", response); - } - - [Fact] - public async Task ExecuteResultAsync_SetsStatusCodeAndLocationHeader() - { - // Arrange - var expectedUrl = "testAction"; - var httpContext = GetHttpContext(); - - // Act - var result = new AcceptedResult(expectedUrl, value: "some-value"); - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(StatusCodes.Status202Accepted, httpContext.Response.StatusCode); - Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); - } - - private static HttpContext GetHttpContext() - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(); - return httpContext; - } - - private static IServiceProvider CreateServices() - { - var services = new ServiceCollection(); - services.AddLogging(); - return services.BuildServiceProvider(); - } + var services = new ServiceCollection(); + services.AddLogging(); + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/BadRequestObjectResultTests.cs b/src/Http/Http.Results/test/BadRequestObjectResultTests.cs index 7c3c57be31..ccec17c255 100644 --- a/src/Http/Http.Results/test/BadRequestObjectResultTests.cs +++ b/src/Http/Http.Results/test/BadRequestObjectResultTests.cs @@ -3,20 +3,19 @@ using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class BadRequestObjectResultTests { - public class BadRequestObjectResultTests + [Fact] + public void BadRequestObjectResult_SetsStatusCodeAndValue() { - [Fact] - public void BadRequestObjectResult_SetsStatusCodeAndValue() - { - // Arrange & Act - var obj = new object(); - var badRequestObjectResult = new BadRequestObjectResult(obj); + // Arrange & Act + var obj = new object(); + var badRequestObjectResult = new BadRequestObjectResult(obj); - // Assert - Assert.Equal(StatusCodes.Status400BadRequest, badRequestObjectResult.StatusCode); - Assert.Equal(obj, badRequestObjectResult.Value); - } + // Assert + Assert.Equal(StatusCodes.Status400BadRequest, badRequestObjectResult.StatusCode); + Assert.Equal(obj, badRequestObjectResult.Value); } } diff --git a/src/Http/Http.Results/test/ChallengeResultTest.cs b/src/Http/Http.Results/test/ChallengeResultTest.cs index 672d3b34ae..3bed9c0378 100644 --- a/src/Http/Http.Results/test/ChallengeResultTest.cs +++ b/src/Http/Http.Results/test/ChallengeResultTest.cs @@ -9,54 +9,53 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class ChallengeResultTest { - public class ChallengeResultTest + [Fact] + public async Task ChallengeResult_ExecuteAsync() + { + // Arrange + var result = new ChallengeResult("", null); + var auth = new Mock(); + var httpContext = GetHttpContext(auth); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + auth.Verify(c => c.ChallengeAsync(httpContext, "", null), Times.Exactly(1)); + } + + [Fact] + public async Task ChallengeResult_ExecuteAsync_NoSchemes() + { + // Arrange + var result = new ChallengeResult(new string[] { }, null); + var auth = new Mock(); + var httpContext = GetHttpContext(auth); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + auth.Verify(c => c.ChallengeAsync(httpContext, null, null), Times.Exactly(1)); + } + + private static DefaultHttpContext GetHttpContext(Mock auth) + { + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices() + .AddSingleton(auth.Object) + .BuildServiceProvider(); + return httpContext; + } + + private static IServiceCollection CreateServices() { - [Fact] - public async Task ChallengeResult_ExecuteAsync() - { - // Arrange - var result = new ChallengeResult("", null); - var auth = new Mock(); - var httpContext = GetHttpContext(auth); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - auth.Verify(c => c.ChallengeAsync(httpContext, "", null), Times.Exactly(1)); - } - - [Fact] - public async Task ChallengeResult_ExecuteAsync_NoSchemes() - { - // Arrange - var result = new ChallengeResult(new string[] { }, null); - var auth = new Mock(); - var httpContext = GetHttpContext(auth); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - auth.Verify(c => c.ChallengeAsync(httpContext, null, null), Times.Exactly(1)); - } - - private static DefaultHttpContext GetHttpContext(Mock auth) - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices() - .AddSingleton(auth.Object) - .BuildServiceProvider(); - return httpContext; - } - - private static IServiceCollection CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); - return services; - } + var services = new ServiceCollection(); + services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); + return services; } } diff --git a/src/Http/Http.Results/test/ConflictObjectResultTest.cs b/src/Http/Http.Results/test/ConflictObjectResultTest.cs index fba55eecce..1b2c573102 100644 --- a/src/Http/Http.Results/test/ConflictObjectResultTest.cs +++ b/src/Http/Http.Results/test/ConflictObjectResultTest.cs @@ -3,20 +3,19 @@ using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class ConflictObjectResultTest { - public class ConflictObjectResultTest + [Fact] + public void ConflictObjectResult_SetsStatusCodeAndValue() { - [Fact] - public void ConflictObjectResult_SetsStatusCodeAndValue() - { - // Arrange & Act - var obj = new object(); - var conflictObjectResult = new ConflictObjectResult(obj); + // Arrange & Act + var obj = new object(); + var conflictObjectResult = new ConflictObjectResult(obj); - // Assert - Assert.Equal(StatusCodes.Status409Conflict, conflictObjectResult.StatusCode); - Assert.Equal(obj, conflictObjectResult.Value); - } + // Assert + Assert.Equal(StatusCodes.Status409Conflict, conflictObjectResult.StatusCode); + Assert.Equal(obj, conflictObjectResult.Value); } } diff --git a/src/Http/Http.Results/test/ContentResultTest.cs b/src/Http/Http.Results/test/ContentResultTest.cs index 1f50e0001a..09e0ada15d 100644 --- a/src/Http/Http.Results/test/ContentResultTest.cs +++ b/src/Http/Http.Results/test/ContentResultTest.cs @@ -10,37 +10,37 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Net.Http.Headers; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class ContentResultTest { - public class ContentResultTest + [Fact] + public async Task ContentResult_ExecuteAsync_Response_NullContent_SetsContentTypeAndEncoding() { - [Fact] - public async Task ContentResult_ExecuteAsync_Response_NullContent_SetsContentTypeAndEncoding() + // Arrange + var contentResult = new ContentResult { - // Arrange - var contentResult = new ContentResult + Content = null, + ContentType = new MediaTypeHeaderValue("text/plain") { - Content = null, - ContentType = new MediaTypeHeaderValue("text/plain") - { - Encoding = Encoding.Unicode - }.ToString() - }; - var httpContext = GetHttpContext(); + Encoding = Encoding.Unicode + }.ToString() + }; + var httpContext = GetHttpContext(); - // Act - await contentResult.ExecuteAsync(httpContext); + // Act + await contentResult.ExecuteAsync(httpContext); - // Assert - Assert.Equal("text/plain; charset=utf-16", httpContext.Response.ContentType); - } + // Assert + Assert.Equal("text/plain; charset=utf-16", httpContext.Response.ContentType); + } - public static TheoryData ContentResultContentTypeData + public static TheoryData ContentResultContentTypeData + { + get { - get - { - // contentType, content, responseContentType, expectedContentType, expectedData - return new TheoryData + // contentType, content, responseContentType, expectedContentType, expectedData + return new TheoryData { { null, @@ -99,54 +99,53 @@ namespace Microsoft.AspNetCore.Http.Result new byte[] { 97, 98, 99, 100 } }, }; - } } + } - [Theory] - [MemberData(nameof(ContentResultContentTypeData))] - public async Task ContentResult_ExecuteAsync_SetContentTypeAndEncoding_OnResponse( - MediaTypeHeaderValue contentType, - string content, - string responseContentType, - string expectedContentType, - byte[] expectedContentData) + [Theory] + [MemberData(nameof(ContentResultContentTypeData))] + public async Task ContentResult_ExecuteAsync_SetContentTypeAndEncoding_OnResponse( + MediaTypeHeaderValue contentType, + string content, + string responseContentType, + string expectedContentType, + byte[] expectedContentData) + { + // Arrange + var contentResult = new ContentResult { - // Arrange - var contentResult = new ContentResult - { - Content = content, - ContentType = contentType?.ToString() - }; - var httpContext = GetHttpContext(); - var memoryStream = new MemoryStream(); - httpContext.Response.Body = memoryStream; - httpContext.Response.ContentType = responseContentType; + Content = content, + ContentType = contentType?.ToString() + }; + var httpContext = GetHttpContext(); + var memoryStream = new MemoryStream(); + httpContext.Response.Body = memoryStream; + httpContext.Response.ContentType = responseContentType; - // Act - await contentResult.ExecuteAsync(httpContext); + // Act + await contentResult.ExecuteAsync(httpContext); - // Assert - var finalResponseContentType = httpContext.Response.ContentType; - Assert.Equal(expectedContentType, finalResponseContentType); - Assert.Equal(expectedContentData, memoryStream.ToArray()); - Assert.Equal(expectedContentData.Length, httpContext.Response.ContentLength); - } + // Assert + var finalResponseContentType = httpContext.Response.ContentType; + Assert.Equal(expectedContentType, finalResponseContentType); + Assert.Equal(expectedContentData, memoryStream.ToArray()); + Assert.Equal(expectedContentData.Length, httpContext.Response.ContentLength); + } - private static IServiceCollection CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); - return services; - } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); + return services; + } - private static HttpContext GetHttpContext() - { - var services = CreateServices(); + private static HttpContext GetHttpContext() + { + var services = CreateServices(); - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = services.BuildServiceProvider(); + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); - return httpContext; - } + return httpContext; } } diff --git a/src/Http/Http.Results/test/CreatedAtRouteResultTests.cs b/src/Http/Http.Results/test/CreatedAtRouteResultTests.cs index 7f4cd28dd9..7fdedb717f 100644 --- a/src/Http/Http.Results/test/CreatedAtRouteResultTests.cs +++ b/src/Http/Http.Results/test/CreatedAtRouteResultTests.cs @@ -12,82 +12,81 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public partial class CreatedAtRouteResultTests { - public partial class CreatedAtRouteResultTests + public static IEnumerable CreatedAtRouteData { - public static IEnumerable CreatedAtRouteData + get { - get - { - yield return new object[] { null }; - yield return - new object[] { + yield return new object[] { null }; + yield return + new object[] { new Dictionary() { { "hello", "world" } } - }; - yield return - new object[] { + }; + yield return + new object[] { new RouteValueDictionary(new Dictionary() { { "test", "case" }, { "sample", "route" } }) - }; - } + }; } + } - [Theory] - [MemberData(nameof(CreatedAtRouteData))] - public async Task CreatedAtRouteResult_ReturnsStatusCode_SetsLocationHeader(object values) - { - // Arrange - var expectedUrl = "testAction"; - var httpContext = GetHttpContext(expectedUrl); + [Theory] + [MemberData(nameof(CreatedAtRouteData))] + public async Task CreatedAtRouteResult_ReturnsStatusCode_SetsLocationHeader(object values) + { + // Arrange + var expectedUrl = "testAction"; + var httpContext = GetHttpContext(expectedUrl); - // Act - var result = new CreatedAtRouteResult(routeName: null, routeValues: values, value: null); - await result.ExecuteAsync(httpContext); + // Act + var result = new CreatedAtRouteResult(routeName: null, routeValues: values, value: null); + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode); - Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); - } + // Assert + Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode); + Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); + } - [Fact] - public async Task CreatedAtRouteResult_ThrowsOnNullUrl() - { - // Arrange - var httpContext = GetHttpContext(expectedUrl: null); + [Fact] + public async Task CreatedAtRouteResult_ThrowsOnNullUrl() + { + // Arrange + var httpContext = GetHttpContext(expectedUrl: null); - var result = new CreatedAtRouteResult( - routeName: null, - routeValues: new Dictionary(), - value: null); + var result = new CreatedAtRouteResult( + routeName: null, + routeValues: new Dictionary(), + value: null); - // Act & Assert - await ExceptionAssert.ThrowsAsync( - async () => await result.ExecuteAsync(httpContext), - "No route matches the supplied values."); - } + // Act & Assert + await ExceptionAssert.ThrowsAsync( + async () => await result.ExecuteAsync(httpContext), + "No route matches the supplied values."); + } - private static HttpContext GetHttpContext(string expectedUrl) - { - var httpContext = new DefaultHttpContext(); - httpContext.Request.PathBase = new PathString(""); - httpContext.Response.Body = new MemoryStream(); - httpContext.RequestServices = CreateServices(expectedUrl); - return httpContext; - } + private static HttpContext GetHttpContext(string expectedUrl) + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.PathBase = new PathString(""); + httpContext.Response.Body = new MemoryStream(); + httpContext.RequestServices = CreateServices(expectedUrl); + return httpContext; + } - private static IServiceProvider CreateServices(string expectedUrl) + private static IServiceProvider CreateServices(string expectedUrl) + { + var services = new ServiceCollection(); + services.AddSingleton(); + services.AddSingleton(new TestLinkGenerator { - var services = new ServiceCollection(); - services.AddSingleton(); - services.AddSingleton(new TestLinkGenerator - { - Url = expectedUrl - }); + Url = expectedUrl + }); - return services.BuildServiceProvider(); - } + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/CreatedResultTest.cs b/src/Http/Http.Results/test/CreatedResultTest.cs index 28f4868e8f..06bc459d36 100644 --- a/src/Http/Http.Results/test/CreatedResultTest.cs +++ b/src/Http/Http.Results/test/CreatedResultTest.cs @@ -9,71 +9,70 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class CreatedResultTests { - public class CreatedResultTests + [Fact] + public void CreatedResult_SetsLocation() { - [Fact] - public void CreatedResult_SetsLocation() - { - // Arrange - var location = "http://test/location"; + // Arrange + var location = "http://test/location"; - // Act - var result = new CreatedResult(location, "testInput"); + // Act + var result = new CreatedResult(location, "testInput"); - // Assert - Assert.Same(location, result.Location); - } + // Assert + Assert.Same(location, result.Location); + } - [Fact] - public async Task CreatedResult_ReturnsStatusCode_SetsLocationHeader() - { - // Arrange - var location = "/test/"; - var httpContext = GetHttpContext(); - var result = new CreatedResult(location, "testInput"); + [Fact] + public async Task CreatedResult_ReturnsStatusCode_SetsLocationHeader() + { + // Arrange + var location = "/test/"; + var httpContext = GetHttpContext(); + var result = new CreatedResult(location, "testInput"); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode); - Assert.Equal(location, httpContext.Response.Headers["Location"]); - } + // Assert + Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode); + Assert.Equal(location, httpContext.Response.Headers["Location"]); + } - [Fact] - public async Task CreatedResult_OverwritesLocationHeader() - { - // Arrange - var location = "/test/"; - var httpContext = GetHttpContext(); - httpContext.Response.Headers["Location"] = "/different/location/"; - var result = new CreatedResult(location, "testInput"); + [Fact] + public async Task CreatedResult_OverwritesLocationHeader() + { + // Arrange + var location = "/test/"; + var httpContext = GetHttpContext(); + httpContext.Response.Headers["Location"] = "/different/location/"; + var result = new CreatedResult(location, "testInput"); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode); - Assert.Equal(location, httpContext.Response.Headers["Location"]); - } + // Assert + Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode); + Assert.Equal(location, httpContext.Response.Headers["Location"]); + } - private static HttpContext GetHttpContext() - { - var httpContext = new DefaultHttpContext(); - httpContext.Request.PathBase = new PathString(""); - httpContext.Response.Body = new MemoryStream(); - httpContext.RequestServices = CreateServices(); - return httpContext; - } + private static HttpContext GetHttpContext() + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.PathBase = new PathString(""); + httpContext.Response.Body = new MemoryStream(); + httpContext.RequestServices = CreateServices(); + return httpContext; + } - private static IServiceProvider CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(); + private static IServiceProvider CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(); - return services.BuildServiceProvider(); - } + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/FileContentResultTest.cs b/src/Http/Http.Results/test/FileContentResultTest.cs index 6a2205c2b2..02ab23f267 100644 --- a/src/Http/Http.Results/test/FileContentResultTest.cs +++ b/src/Http/Http.Results/test/FileContentResultTest.cs @@ -9,30 +9,29 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Net.Http.Headers; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class FileContentResultTest : FileContentResultTestBase { - public class FileContentResultTest : FileContentResultTestBase + protected override Task ExecuteAsync( + HttpContext httpContext, + byte[] buffer, + string contentType, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue entityTag = null, + bool enableRangeProcessing = false) { - protected override Task ExecuteAsync( - HttpContext httpContext, - byte[] buffer, - string contentType, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue entityTag = null, - bool enableRangeProcessing = false) + var result = new FileContentResult(buffer, contentType) { - var result = new FileContentResult(buffer, contentType) - { - EntityTag = entityTag, - LastModified = lastModified, - EnableRangeProcessing = enableRangeProcessing, - }; + EntityTag = entityTag, + LastModified = lastModified, + EnableRangeProcessing = enableRangeProcessing, + }; - httpContext.RequestServices = new ServiceCollection() - .AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)) - .BuildServiceProvider(); + httpContext.RequestServices = new ServiceCollection() + .AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)) + .BuildServiceProvider(); - return result.ExecuteAsync(httpContext); - } + return result.ExecuteAsync(httpContext); } } diff --git a/src/Http/Http.Results/test/FileStreamResultTest.cs b/src/Http/Http.Results/test/FileStreamResultTest.cs index fca9982ac3..6fc5cf6209 100644 --- a/src/Http/Http.Results/test/FileStreamResultTest.cs +++ b/src/Http/Http.Results/test/FileStreamResultTest.cs @@ -8,79 +8,78 @@ using Microsoft.AspNetCore.Internal; using Microsoft.Net.Http.Headers; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class FileStreamResultTest : FileStreamResultTestBase { - public class FileStreamResultTest : FileStreamResultTestBase + protected override Task ExecuteAsync( + HttpContext httpContext, + Stream stream, + string contentType, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue entityTag = null, + bool enableRangeProcessing = false) { - protected override Task ExecuteAsync( - HttpContext httpContext, - Stream stream, - string contentType, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue entityTag = null, - bool enableRangeProcessing = false) + var fileStreamResult = new FileStreamResult(stream, contentType) { - var fileStreamResult = new FileStreamResult(stream, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing - }; - - return fileStreamResult.ExecuteAsync(httpContext); - } + LastModified = lastModified, + EntityTag = entityTag, + EnableRangeProcessing = enableRangeProcessing + }; - [Fact] - public void Constructor_SetsFileName() - { - // Arrange - var stream = Stream.Null; + return fileStreamResult.ExecuteAsync(httpContext); + } - // Act - var result = new FileStreamResult(stream, "text/plain"); + [Fact] + public void Constructor_SetsFileName() + { + // Arrange + var stream = Stream.Null; - // Assert - Assert.Equal(stream, result.FileStream); - } + // Act + var result = new FileStreamResult(stream, "text/plain"); - [Fact] - public void Constructor_SetsContentTypeAndParameters() - { - // Arrange - var stream = Stream.Null; - var contentType = "text/plain; charset=us-ascii; p1=p1-value"; - var expectedMediaType = contentType; + // Assert + Assert.Equal(stream, result.FileStream); + } - // Act - var result = new FileStreamResult(stream, contentType); + [Fact] + public void Constructor_SetsContentTypeAndParameters() + { + // Arrange + var stream = Stream.Null; + var contentType = "text/plain; charset=us-ascii; p1=p1-value"; + var expectedMediaType = contentType; - // Assert - Assert.Equal(stream, result.FileStream); - Assert.Equal(expectedMediaType, result.ContentType); - } + // Act + var result = new FileStreamResult(stream, contentType); - [Fact] - public void Constructor_SetsLastModifiedAndEtag() - { - // Arrange - var stream = Stream.Null; - var contentType = "text/plain"; - var expectedMediaType = contentType; - var lastModified = new DateTimeOffset(); - var entityTag = new EntityTagHeaderValue("\"Etag\""); + // Assert + Assert.Equal(stream, result.FileStream); + Assert.Equal(expectedMediaType, result.ContentType); + } - // Act - var result = new FileStreamResult(stream, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - }; + [Fact] + public void Constructor_SetsLastModifiedAndEtag() + { + // Arrange + var stream = Stream.Null; + var contentType = "text/plain"; + var expectedMediaType = contentType; + var lastModified = new DateTimeOffset(); + var entityTag = new EntityTagHeaderValue("\"Etag\""); - // Assert - Assert.Equal(lastModified, result.LastModified); - Assert.Equal(entityTag, result.EntityTag); - Assert.Equal(expectedMediaType, result.ContentType); - } + // Act + var result = new FileStreamResult(stream, contentType) + { + LastModified = lastModified, + EntityTag = entityTag, + }; + // Assert + Assert.Equal(lastModified, result.LastModified); + Assert.Equal(entityTag, result.EntityTag); + Assert.Equal(expectedMediaType, result.ContentType); } + } diff --git a/src/Http/Http.Results/test/ForbidResultTest.cs b/src/Http/Http.Results/test/ForbidResultTest.cs index f123d38469..42236c0066 100644 --- a/src/Http/Http.Results/test/ForbidResultTest.cs +++ b/src/Http/Http.Results/test/ForbidResultTest.cs @@ -10,120 +10,119 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class ForbidResultTest { - public class ForbidResultTest + [Fact] + public async Task ExecuteResultAsync_InvokesForbidAsyncOnAuthenticationService() { - [Fact] - public async Task ExecuteResultAsync_InvokesForbidAsyncOnAuthenticationService() - { - // Arrange - var auth = new Mock(); - auth - .Setup(c => c.ForbidAsync(It.IsAny(), "", null)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new ForbidResult("", null); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - auth.Verify(); - } - - [Fact] - public async Task ExecuteResultAsync_InvokesForbidAsyncOnAllConfiguredSchemes() + // Arrange + var auth = new Mock(); + auth + .Setup(c => c.ForbidAsync(It.IsAny(), "", null)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new ForbidResult("", null); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + auth.Verify(); + } + + [Fact] + public async Task ExecuteResultAsync_InvokesForbidAsyncOnAllConfiguredSchemes() + { + // Arrange + var authProperties = new AuthenticationProperties(); + var auth = new Mock(); + auth + .Setup(c => c.ForbidAsync(It.IsAny(), "Scheme1", authProperties)) + .Returns(Task.CompletedTask) + .Verifiable(); + auth + .Setup(c => c.ForbidAsync(It.IsAny(), "Scheme2", authProperties)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new ForbidResult(new[] { "Scheme1", "Scheme2" }, authProperties); + var routeData = new RouteData(); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + auth.Verify(); + } + + public static TheoryData ExecuteResultAsync_InvokesForbidAsyncWithAuthPropertiesData => + new TheoryData { - // Arrange - var authProperties = new AuthenticationProperties(); - var auth = new Mock(); - auth - .Setup(c => c.ForbidAsync(It.IsAny(), "Scheme1", authProperties)) - .Returns(Task.CompletedTask) - .Verifiable(); - auth - .Setup(c => c.ForbidAsync(It.IsAny(), "Scheme2", authProperties)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new ForbidResult(new[] { "Scheme1", "Scheme2" }, authProperties); - var routeData = new RouteData(); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - auth.Verify(); - } - - public static TheoryData ExecuteResultAsync_InvokesForbidAsyncWithAuthPropertiesData => - new TheoryData - { null, new AuthenticationProperties() - }; + }; - [Theory] - [MemberData(nameof(ExecuteResultAsync_InvokesForbidAsyncWithAuthPropertiesData))] - public async Task ExecuteResultAsync_InvokesForbidAsyncWithAuthProperties(AuthenticationProperties expected) - { - // Arrange - var auth = new Mock(); - auth - .Setup(c => c.ForbidAsync(It.IsAny(), null, expected)) - .Returns(Task.CompletedTask) - .Verifiable(); - var result = new ForbidResult(expected); - var httpContext = GetHttpContext(auth.Object); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - auth.Verify(); - } - - [Theory] - [MemberData(nameof(ExecuteResultAsync_InvokesForbidAsyncWithAuthPropertiesData))] - public async Task ExecuteResultAsync_InvokesForbidAsyncWithAuthProperties_WhenAuthenticationSchemesIsEmpty( - AuthenticationProperties expected) - { - // Arrange - var auth = new Mock(); - auth - .Setup(c => c.ForbidAsync(It.IsAny(), null, expected)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new ForbidResult(expected) - { - AuthenticationSchemes = new string[0] - }; - var routeData = new RouteData(); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - auth.Verify(); - } - - private static DefaultHttpContext GetHttpContext(IAuthenticationService auth) - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices() - .AddSingleton(auth) - .BuildServiceProvider(); - return httpContext; - } - - private static IServiceCollection CreateServices() + [Theory] + [MemberData(nameof(ExecuteResultAsync_InvokesForbidAsyncWithAuthPropertiesData))] + public async Task ExecuteResultAsync_InvokesForbidAsyncWithAuthProperties(AuthenticationProperties expected) + { + // Arrange + var auth = new Mock(); + auth + .Setup(c => c.ForbidAsync(It.IsAny(), null, expected)) + .Returns(Task.CompletedTask) + .Verifiable(); + var result = new ForbidResult(expected); + var httpContext = GetHttpContext(auth.Object); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + auth.Verify(); + } + + [Theory] + [MemberData(nameof(ExecuteResultAsync_InvokesForbidAsyncWithAuthPropertiesData))] + public async Task ExecuteResultAsync_InvokesForbidAsyncWithAuthProperties_WhenAuthenticationSchemesIsEmpty( + AuthenticationProperties expected) + { + // Arrange + var auth = new Mock(); + auth + .Setup(c => c.ForbidAsync(It.IsAny(), null, expected)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new ForbidResult(expected) { - var services = new ServiceCollection(); - services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); - return services; - } + AuthenticationSchemes = new string[0] + }; + var routeData = new RouteData(); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + auth.Verify(); + } + + private static DefaultHttpContext GetHttpContext(IAuthenticationService auth) + { + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices() + .AddSingleton(auth) + .BuildServiceProvider(); + return httpContext; + } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); + return services; } } diff --git a/src/Http/Http.Results/test/LocalRedirectResultTest.cs b/src/Http/Http.Results/test/LocalRedirectResultTest.cs index d059f50540..c641cfcb06 100644 --- a/src/Http/Http.Results/test/LocalRedirectResultTest.cs +++ b/src/Http/Http.Results/test/LocalRedirectResultTest.cs @@ -8,131 +8,130 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class LocalRedirectResultTest { - public class LocalRedirectResultTest + [Fact] + public void Constructor_WithParameterUrl_SetsResultUrlAndNotPermanentOrPreserveMethod() + { + // Arrange + var url = "/test/url"; + + // Act + var result = new LocalRedirectResult(url); + + // Assert + Assert.False(result.PreserveMethod); + Assert.False(result.Permanent); + Assert.Same(url, result.Url); + } + + [Fact] + public void Constructor_WithParameterUrlAndPermanent_SetsResultUrlAndPermanentNotPreserveMethod() + { + // Arrange + var url = "/test/url"; + + // Act + var result = new LocalRedirectResult(url, permanent: true); + + // Assert + Assert.False(result.PreserveMethod); + Assert.True(result.Permanent); + Assert.Same(url, result.Url); + } + + [Fact] + public void Constructor_WithParameterUrlAndPermanent_SetsResultUrlPermanentAndPreserveMethod() + { + // Arrange + var url = "/test/url"; + + // Act + var result = new LocalRedirectResult(url, permanent: true, preserveMethod: true); + + // Assert + Assert.True(result.PreserveMethod); + Assert.True(result.Permanent); + Assert.Same(url, result.Url); + } + + [Fact] + public async Task Execute_ReturnsExpectedValues() + { + // Arrange + var appRoot = "/"; + var contentPath = "~/Home/About"; + var expectedPath = "/Home/About"; + + var httpContext = GetHttpContext(appRoot); + var result = new LocalRedirectResult(contentPath); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(expectedPath, httpContext.Response.Headers.Location.ToString()); + Assert.Equal(StatusCodes.Status302Found, httpContext.Response.StatusCode); + } + + [Theory] + [InlineData("", "//")] + [InlineData("", "/\\")] + [InlineData("", "//foo")] + [InlineData("", "/\\foo")] + [InlineData("", "Home/About")] + [InlineData("/myapproot", "http://www.example.com")] + public async Task Execute_Throws_ForNonLocalUrl( + string appRoot, + string contentPath) + { + // Arrange + var httpContext = GetHttpContext(appRoot); + var result = new LocalRedirectResult(contentPath); + + // Act & Assert + var exception = await Assert.ThrowsAsync(() => result.ExecuteAsync(httpContext)); + Assert.Equal( + "The supplied URL is not local. A URL with an absolute path is considered local if it does not " + + "have a host/authority part. URLs using virtual paths ('~/') are also local.", + exception.Message); + } + + [Theory] + [InlineData("", "~//")] + [InlineData("", "~/\\")] + [InlineData("", "~//foo")] + [InlineData("", "~/\\foo")] + public async Task Execute_Throws_ForNonLocalUrlTilde( + string appRoot, + string contentPath) + { + // Arrange + var httpContext = GetHttpContext(appRoot); + var result = new LocalRedirectResult(contentPath); + + // Act & Assert + var exception = await Assert.ThrowsAsync(() => result.ExecuteAsync(httpContext)); + Assert.Equal( + "The supplied URL is not local. A URL with an absolute path is considered local if it does not " + + "have a host/authority part. URLs using virtual paths ('~/') are also local.", + exception.Message); + } + + private static IServiceProvider GetServiceProvider() + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(typeof(ILogger<>), typeof(NullLogger<>)); + return serviceCollection.BuildServiceProvider(); + } + + private static HttpContext GetHttpContext(string appRoot) { - [Fact] - public void Constructor_WithParameterUrl_SetsResultUrlAndNotPermanentOrPreserveMethod() - { - // Arrange - var url = "/test/url"; - - // Act - var result = new LocalRedirectResult(url); - - // Assert - Assert.False(result.PreserveMethod); - Assert.False(result.Permanent); - Assert.Same(url, result.Url); - } - - [Fact] - public void Constructor_WithParameterUrlAndPermanent_SetsResultUrlAndPermanentNotPreserveMethod() - { - // Arrange - var url = "/test/url"; - - // Act - var result = new LocalRedirectResult(url, permanent: true); - - // Assert - Assert.False(result.PreserveMethod); - Assert.True(result.Permanent); - Assert.Same(url, result.Url); - } - - [Fact] - public void Constructor_WithParameterUrlAndPermanent_SetsResultUrlPermanentAndPreserveMethod() - { - // Arrange - var url = "/test/url"; - - // Act - var result = new LocalRedirectResult(url, permanent: true, preserveMethod: true); - - // Assert - Assert.True(result.PreserveMethod); - Assert.True(result.Permanent); - Assert.Same(url, result.Url); - } - - [Fact] - public async Task Execute_ReturnsExpectedValues() - { - // Arrange - var appRoot = "/"; - var contentPath = "~/Home/About"; - var expectedPath = "/Home/About"; - - var httpContext = GetHttpContext(appRoot); - var result = new LocalRedirectResult(contentPath); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(expectedPath, httpContext.Response.Headers.Location.ToString()); - Assert.Equal(StatusCodes.Status302Found, httpContext.Response.StatusCode); - } - - [Theory] - [InlineData("", "//")] - [InlineData("", "/\\")] - [InlineData("", "//foo")] - [InlineData("", "/\\foo")] - [InlineData("", "Home/About")] - [InlineData("/myapproot", "http://www.example.com")] - public async Task Execute_Throws_ForNonLocalUrl( - string appRoot, - string contentPath) - { - // Arrange - var httpContext = GetHttpContext(appRoot); - var result = new LocalRedirectResult(contentPath); - - // Act & Assert - var exception = await Assert.ThrowsAsync(() => result.ExecuteAsync(httpContext)); - Assert.Equal( - "The supplied URL is not local. A URL with an absolute path is considered local if it does not " + - "have a host/authority part. URLs using virtual paths ('~/') are also local.", - exception.Message); - } - - [Theory] - [InlineData("", "~//")] - [InlineData("", "~/\\")] - [InlineData("", "~//foo")] - [InlineData("", "~/\\foo")] - public async Task Execute_Throws_ForNonLocalUrlTilde( - string appRoot, - string contentPath) - { - // Arrange - var httpContext = GetHttpContext(appRoot); - var result = new LocalRedirectResult(contentPath); - - // Act & Assert - var exception = await Assert.ThrowsAsync(() => result.ExecuteAsync(httpContext)); - Assert.Equal( - "The supplied URL is not local. A URL with an absolute path is considered local if it does not " + - "have a host/authority part. URLs using virtual paths ('~/') are also local.", - exception.Message); - } - - private static IServiceProvider GetServiceProvider() - { - var serviceCollection = new ServiceCollection(); - serviceCollection.AddTransient(typeof(ILogger<>), typeof(NullLogger<>)); - return serviceCollection.BuildServiceProvider(); - } - - private static HttpContext GetHttpContext(string appRoot) - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = GetServiceProvider(); - httpContext.Request.PathBase = new PathString(appRoot); - return httpContext; - } + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = GetServiceProvider(); + httpContext.Request.PathBase = new PathString(appRoot); + return httpContext; } } diff --git a/src/Http/Http.Results/test/NotFoundObjectResultTest.cs b/src/Http/Http.Results/test/NotFoundObjectResultTest.cs index af6387f9fa..59604dc062 100644 --- a/src/Http/Http.Results/test/NotFoundObjectResultTest.cs +++ b/src/Http/Http.Results/test/NotFoundObjectResultTest.cs @@ -9,59 +9,58 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class NotFoundObjectResultTest { - public class NotFoundObjectResultTest + [Fact] + public void NotFoundObjectResult_InitializesStatusCode() { - [Fact] - public void NotFoundObjectResult_InitializesStatusCode() - { - // Arrange & act - var notFound = new NotFoundObjectResult(null); + // Arrange & act + var notFound = new NotFoundObjectResult(null); - // Assert - Assert.Equal(StatusCodes.Status404NotFound, notFound.StatusCode); - } + // Assert + Assert.Equal(StatusCodes.Status404NotFound, notFound.StatusCode); + } - [Fact] - public void NotFoundObjectResult_InitializesStatusCodeAndResponseContent() - { - // Arrange & act - var notFound = new NotFoundObjectResult("Test Content"); + [Fact] + public void NotFoundObjectResult_InitializesStatusCodeAndResponseContent() + { + // Arrange & act + var notFound = new NotFoundObjectResult("Test Content"); - // Assert - Assert.Equal(StatusCodes.Status404NotFound, notFound.StatusCode); - Assert.Equal("Test Content", notFound.Value); - } + // Assert + Assert.Equal(StatusCodes.Status404NotFound, notFound.StatusCode); + Assert.Equal("Test Content", notFound.Value); + } - [Fact] - public async Task NotFoundObjectResult_ExecuteSuccessful() - { - // Arrange - var httpContext = GetHttpContext(); - var result = new NotFoundObjectResult("Test Content"); + [Fact] + public async Task NotFoundObjectResult_ExecuteSuccessful() + { + // Arrange + var httpContext = GetHttpContext(); + var result = new NotFoundObjectResult("Test Content"); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode); - } + // Assert + Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode); + } - private static HttpContext GetHttpContext() - { - var httpContext = new DefaultHttpContext(); - httpContext.Request.PathBase = new PathString(""); - httpContext.Response.Body = new MemoryStream(); - httpContext.RequestServices = CreateServices(); - return httpContext; - } + private static HttpContext GetHttpContext() + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.PathBase = new PathString(""); + httpContext.Response.Body = new MemoryStream(); + httpContext.RequestServices = CreateServices(); + return httpContext; + } - private static IServiceProvider CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(); - return services.BuildServiceProvider(); - } + private static IServiceProvider CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(); + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/ObjectResultTests.cs b/src/Http/Http.Results/test/ObjectResultTests.cs index 849708dc33..59160a9dcb 100644 --- a/src/Http/Http.Results/test/ObjectResultTests.cs +++ b/src/Http/Http.Results/test/ObjectResultTests.cs @@ -10,195 +10,194 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class ObjectResultTests { - public class ObjectResultTests + [Fact] + public async Task ObjectResult_ExecuteAsync_WithNullValue_Works() { - [Fact] - public async Task ObjectResult_ExecuteAsync_WithNullValue_Works() + // Arrange + var result = new ObjectResult(value: null, 411); + + var httpContext = new DefaultHttpContext() { - // Arrange - var result = new ObjectResult(value: null, 411); + RequestServices = CreateServices(), + }; - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - }; + // Act + await result.ExecuteAsync(httpContext); - // Act - await result.ExecuteAsync(httpContext); + // Assert + Assert.Equal(411, httpContext.Response.StatusCode); + } - // Assert - Assert.Equal(411, httpContext.Response.StatusCode); - } + [Fact] + public async Task ObjectResult_ExecuteAsync_SetsStatusCode() + { + // Arrange + var result = new ObjectResult("Hello", 407); - [Fact] - public async Task ObjectResult_ExecuteAsync_SetsStatusCode() + var httpContext = new DefaultHttpContext() { - // Arrange - var result = new ObjectResult("Hello", 407); + RequestServices = CreateServices(), + }; - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - }; + // Act + await result.ExecuteAsync(httpContext); - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(407, httpContext.Response.StatusCode); - } + // Assert + Assert.Equal(407, httpContext.Response.StatusCode); + } - [Fact] - public async Task ObjectResult_ExecuteAsync_JsonSerializesBody() + [Fact] + public async Task ObjectResult_ExecuteAsync_JsonSerializesBody() + { + // Arrange + var result = new ObjectResult("Hello", 407); + var stream = new MemoryStream(); + var httpContext = new DefaultHttpContext() { - // Arrange - var result = new ObjectResult("Hello", 407); - var stream = new MemoryStream(); - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - Response = + RequestServices = CreateServices(), + Response = { Body = stream, }, - }; + }; - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal("\"Hello\"", Encoding.UTF8.GetString(stream.ToArray())); - } + // Assert + Assert.Equal("\"Hello\"", Encoding.UTF8.GetString(stream.ToArray())); + } + + [Fact] + public async Task ExecuteAsync_UsesDefaults_ForProblemDetails() + { + // Arrange + var details = new ProblemDetails(); - [Fact] - public async Task ExecuteAsync_UsesDefaults_ForProblemDetails() + var result = new ObjectResult(details); + var stream = new MemoryStream(); + var httpContext = new DefaultHttpContext() { - // Arrange - var details = new ProblemDetails(); - - var result = new ObjectResult(details); - var stream = new MemoryStream(); - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - Response = + RequestServices = CreateServices(), + Response = { Body = stream, }, - }; - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(StatusCodes.Status500InternalServerError, httpContext.Response.StatusCode); - stream.Position = 0; - var responseDetails = JsonSerializer.Deserialize(stream); - Assert.Equal("https://tools.ietf.org/html/rfc7231#section-6.6.1", responseDetails.Type); - Assert.Equal("An error occurred while processing your request.", responseDetails.Title); - Assert.Equal(StatusCodes.Status500InternalServerError, responseDetails.Status); - } - - [Fact] - public async Task ExecuteAsync_UsesDefaults_ForValidationProblemDetails() + }; + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(StatusCodes.Status500InternalServerError, httpContext.Response.StatusCode); + stream.Position = 0; + var responseDetails = JsonSerializer.Deserialize(stream); + Assert.Equal("https://tools.ietf.org/html/rfc7231#section-6.6.1", responseDetails.Type); + Assert.Equal("An error occurred while processing your request.", responseDetails.Title); + Assert.Equal(StatusCodes.Status500InternalServerError, responseDetails.Status); + } + + [Fact] + public async Task ExecuteAsync_UsesDefaults_ForValidationProblemDetails() + { + // Arrange + var details = new HttpValidationProblemDetails(); + + var result = new ObjectResult(details); + var stream = new MemoryStream(); + var httpContext = new DefaultHttpContext() { - // Arrange - var details = new HttpValidationProblemDetails(); - - var result = new ObjectResult(details); - var stream = new MemoryStream(); - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - Response = + RequestServices = CreateServices(), + Response = { Body = stream, }, - }; - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); - stream.Position = 0; - var responseDetails = JsonSerializer.Deserialize(stream); - Assert.Equal("https://tools.ietf.org/html/rfc7231#section-6.5.1", responseDetails.Type); - Assert.Equal("One or more validation errors occurred.", responseDetails.Title); - Assert.Equal(StatusCodes.Status400BadRequest, responseDetails.Status); - } - - [Fact] - public async Task ExecuteAsync_SetsProblemDetailsStatus_ForValidationProblemDetails() - { - // Arrange - var details = new HttpValidationProblemDetails(); - - var result = new ObjectResult(details, StatusCodes.Status422UnprocessableEntity); - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - }; - - // Act - await result.ExecuteAsync(httpContext); + }; + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); + stream.Position = 0; + var responseDetails = JsonSerializer.Deserialize(stream); + Assert.Equal("https://tools.ietf.org/html/rfc7231#section-6.5.1", responseDetails.Type); + Assert.Equal("One or more validation errors occurred.", responseDetails.Title); + Assert.Equal(StatusCodes.Status400BadRequest, responseDetails.Status); + } - // Assert - Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value); - } + [Fact] + public async Task ExecuteAsync_SetsProblemDetailsStatus_ForValidationProblemDetails() + { + // Arrange + var details = new HttpValidationProblemDetails(); - [Fact] - public async Task ExecuteAsync_GetsStatusCodeFromProblemDetails() + var result = new ObjectResult(details, StatusCodes.Status422UnprocessableEntity); + var httpContext = new DefaultHttpContext() { - // Arrange - var details = new ProblemDetails { Status = StatusCodes.Status413RequestEntityTooLarge, }; + RequestServices = CreateServices(), + }; - var result = new ObjectResult(details); + // Act + await result.ExecuteAsync(httpContext); - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - }; + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value); + } - // Act - await result.ExecuteAsync(httpContext); + [Fact] + public async Task ExecuteAsync_GetsStatusCodeFromProblemDetails() + { + // Arrange + var details = new ProblemDetails { Status = StatusCodes.Status413RequestEntityTooLarge, }; - // Assert - Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, details.Status.Value); - Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, result.StatusCode.Value); - Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, httpContext.Response.StatusCode); - } + var result = new ObjectResult(details); - [Fact] - public async Task ExecuteAsync_UsesStatusCodeFromResultTypeForProblemDetails() + var httpContext = new DefaultHttpContext() { - // Arrange - var details = new ProblemDetails { Status = StatusCodes.Status422UnprocessableEntity, }; + RequestServices = CreateServices(), + }; - var result = new BadRequestObjectResult(details); + // Act + await result.ExecuteAsync(httpContext); - var httpContext = new DefaultHttpContext() - { - RequestServices = CreateServices(), - }; + // Assert + Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, details.Status.Value); + Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, result.StatusCode.Value); + Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, httpContext.Response.StatusCode); + } - // Act - await result.ExecuteAsync(httpContext); + [Fact] + public async Task ExecuteAsync_UsesStatusCodeFromResultTypeForProblemDetails() + { + // Arrange + var details = new ProblemDetails { Status = StatusCodes.Status422UnprocessableEntity, }; - // Assert - Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value); - Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode.Value); - Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); - } + var result = new BadRequestObjectResult(details); - private static IServiceProvider CreateServices() + var httpContext = new DefaultHttpContext() { - var services = new ServiceCollection(); - services.AddSingleton(NullLoggerFactory.Instance); + RequestServices = CreateServices(), + }; + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value); + Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode.Value); + Assert.Equal(StatusCodes.Status400BadRequest, httpContext.Response.StatusCode); + } + + private static IServiceProvider CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(NullLoggerFactory.Instance); - return services.BuildServiceProvider(); - } + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/OkObjectResultTest.cs b/src/Http/Http.Results/test/OkObjectResultTest.cs index 39b7f47db7..d154863360 100644 --- a/src/Http/Http.Results/test/OkObjectResultTest.cs +++ b/src/Http/Http.Results/test/OkObjectResultTest.cs @@ -9,38 +9,37 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class OkObjectResultTest { - public class OkObjectResultTest + [Fact] + public async Task OkObjectResult_SetsStatusCodeAndValue() { - [Fact] - public async Task OkObjectResult_SetsStatusCodeAndValue() - { - // Arrange - var result = new OkObjectResult("Hello world"); - var httpContext = GetHttpContext(); + // Arrange + var result = new OkObjectResult("Hello world"); + var httpContext = GetHttpContext(); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status200OK, httpContext.Response.StatusCode); - } + // Assert + Assert.Equal(StatusCodes.Status200OK, httpContext.Response.StatusCode); + } - private static HttpContext GetHttpContext() - { - var httpContext = new DefaultHttpContext(); - httpContext.Request.PathBase = new PathString(""); - httpContext.Response.Body = new MemoryStream(); - httpContext.RequestServices = CreateServices(); - return httpContext; - } + private static HttpContext GetHttpContext() + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.PathBase = new PathString(""); + httpContext.Response.Body = new MemoryStream(); + httpContext.RequestServices = CreateServices(); + return httpContext; + } - private static IServiceProvider CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(); - return services.BuildServiceProvider(); - } + private static IServiceProvider CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(); + return services.BuildServiceProvider(); } } diff --git a/src/Http/Http.Results/test/PhysicalFileResultTest.cs b/src/Http/Http.Results/test/PhysicalFileResultTest.cs index 1a99d1aa93..f64808ee54 100644 --- a/src/Http/Http.Results/test/PhysicalFileResultTest.cs +++ b/src/Http/Http.Results/test/PhysicalFileResultTest.cs @@ -6,36 +6,35 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; using Microsoft.Net.Http.Headers; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class PhysicalFileResultTest : PhysicalFileResultTestBase { - public class PhysicalFileResultTest : PhysicalFileResultTestBase + protected override Task ExecuteAsync( + HttpContext httpContext, + string path, + string contentType, + DateTimeOffset? lastModified = null, + EntityTagHeaderValue entityTag = null, + bool enableRangeProcessing = false) { - protected override Task ExecuteAsync( - HttpContext httpContext, - string path, - string contentType, - DateTimeOffset? lastModified = null, - EntityTagHeaderValue entityTag = null, - bool enableRangeProcessing = false) + var fileResult = new PhysicalFileResult(path, contentType) { - var fileResult = new PhysicalFileResult(path, contentType) + LastModified = lastModified, + EntityTag = entityTag, + EnableRangeProcessing = enableRangeProcessing, + GetFileInfoWrapper = (path) => { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - GetFileInfoWrapper = (path) => + var lastModified = DateTimeOffset.MinValue.AddDays(1); + return new() { - var lastModified = DateTimeOffset.MinValue.AddDays(1); - return new() - { - Exists = true, - Length = 34, - LastWriteTimeUtc = new DateTimeOffset(lastModified.Year, lastModified.Month, lastModified.Day, lastModified.Hour, lastModified.Minute, lastModified.Second, TimeSpan.FromSeconds(0)) - }; - } - }; + Exists = true, + Length = 34, + LastWriteTimeUtc = new DateTimeOffset(lastModified.Year, lastModified.Month, lastModified.Day, lastModified.Hour, lastModified.Minute, lastModified.Second, TimeSpan.FromSeconds(0)) + }; + } + }; - return fileResult.ExecuteAsync(httpContext); - } + return fileResult.ExecuteAsync(httpContext); } } diff --git a/src/Http/Http.Results/test/RedirectResultTest.cs b/src/Http/Http.Results/test/RedirectResultTest.cs index 2b0567e12a..a6fc4d31f8 100644 --- a/src/Http/Http.Results/test/RedirectResultTest.cs +++ b/src/Http/Http.Results/test/RedirectResultTest.cs @@ -4,29 +4,28 @@ using Microsoft.AspNetCore.Internal; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class RedirectResultTest : RedirectResultTestBase { - public class RedirectResultTest : RedirectResultTestBase + [Fact] + public void RedirectResult_Constructor_WithParameterUrlPermanentAndPreservesMethod_SetsResultUrlPermanentAndPreservesMethod() { - [Fact] - public void RedirectResult_Constructor_WithParameterUrlPermanentAndPreservesMethod_SetsResultUrlPermanentAndPreservesMethod() - { - // Arrange - var url = "/test/url"; + // Arrange + var url = "/test/url"; - // Act - var result = new RedirectResult(url, permanent: true, preserveMethod: true); + // Act + var result = new RedirectResult(url, permanent: true, preserveMethod: true); - // Assert - Assert.True(result.PreserveMethod); - Assert.True(result.Permanent); - Assert.Same(url, result.Url); - } + // Assert + Assert.True(result.PreserveMethod); + Assert.True(result.Permanent); + Assert.Same(url, result.Url); + } - protected override Task ExecuteAsync(HttpContext httpContext, string contentPath) - { - var redirectResult = new RedirectResult(contentPath, false, false); - return redirectResult.ExecuteAsync(httpContext); - } + protected override Task ExecuteAsync(HttpContext httpContext, string contentPath) + { + var redirectResult = new RedirectResult(contentPath, false, false); + return redirectResult.ExecuteAsync(httpContext); } } diff --git a/src/Http/Http.Results/test/RedirectToRouteResultTest.cs b/src/Http/Http.Results/test/RedirectToRouteResultTest.cs index b2e2e9c05a..2d5af54aae 100644 --- a/src/Http/Http.Results/test/RedirectToRouteResultTest.cs +++ b/src/Http/Http.Results/test/RedirectToRouteResultTest.cs @@ -12,100 +12,99 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class RedirectToRouteResultTest { - public class RedirectToRouteResultTest + [Fact] + public async Task RedirectToRoute_Execute_ThrowsOnNullUrl() + { + // Arrange + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices(null).BuildServiceProvider(); + + var result = new RedirectToRouteResult(null, new Dictionary()); + + // Act & Assert + await ExceptionAssert.ThrowsAsync( + async () => + { + await result.ExecuteAsync(httpContext); + }, + "No route matches the supplied values."); + } + + [Fact] + public async Task ExecuteResultAsync_UsesRouteName_ToGenerateLocationHeader() { - [Fact] - public async Task RedirectToRoute_Execute_ThrowsOnNullUrl() - { - // Arrange - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(null).BuildServiceProvider(); - - var result = new RedirectToRouteResult(null, new Dictionary()); - - // Act & Assert - await ExceptionAssert.ThrowsAsync( - async () => - { - await result.ExecuteAsync(httpContext); - }, - "No route matches the supplied values."); - } - - [Fact] - public async Task ExecuteResultAsync_UsesRouteName_ToGenerateLocationHeader() - { - // Arrange - var routeName = "orders_api"; - var locationUrl = "/api/orders/10"; - - var httpContext = GetHttpContext(locationUrl); - - var result = new RedirectToRouteResult(routeName, new { id = 10 }); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.True(httpContext.Response.Headers.ContainsKey("Location"), "Location header not found"); - Assert.Equal(locationUrl, httpContext.Response.Headers["Location"]); - } - - [Fact] - public async Task ExecuteResultAsync_WithFragment_PassesCorrectValuesToRedirect() - { - // Arrange - var expectedUrl = "/SampleAction#test"; - var expectedStatusCode = StatusCodes.Status301MovedPermanently; - var httpContext = GetHttpContext(expectedUrl); - - var result = new RedirectToRouteResult("Sample", null, true, "test"); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode); - Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); - } - - [Fact] - public async Task ExecuteResultAsync_WithFragment_PassesCorrectValuesToRedirect_WithPreserveMethod() - { - // Arrange - var expectedUrl = "/SampleAction#test"; - var expectedStatusCode = StatusCodes.Status308PermanentRedirect; - - var httpContext = GetHttpContext(expectedUrl); - var result = new RedirectToRouteResult("Sample", null, true, true, "test"); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode); - Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); - } - - private static HttpContext GetHttpContext(string path) - { - var services = CreateServices(path); - - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = services.BuildServiceProvider(); - - return httpContext; - } - - private static IServiceCollection CreateServices(string path) - { - var services = new ServiceCollection(); - services.AddSingleton(new TestLinkGenerator { Url = path }); - - services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); - return services; - } + // Arrange + var routeName = "orders_api"; + var locationUrl = "/api/orders/10"; + + var httpContext = GetHttpContext(locationUrl); + + var result = new RedirectToRouteResult(routeName, new { id = 10 }); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.True(httpContext.Response.Headers.ContainsKey("Location"), "Location header not found"); + Assert.Equal(locationUrl, httpContext.Response.Headers["Location"]); + } + + [Fact] + public async Task ExecuteResultAsync_WithFragment_PassesCorrectValuesToRedirect() + { + // Arrange + var expectedUrl = "/SampleAction#test"; + var expectedStatusCode = StatusCodes.Status301MovedPermanently; + var httpContext = GetHttpContext(expectedUrl); + + var result = new RedirectToRouteResult("Sample", null, true, "test"); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode); + Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); + } + + [Fact] + public async Task ExecuteResultAsync_WithFragment_PassesCorrectValuesToRedirect_WithPreserveMethod() + { + // Arrange + var expectedUrl = "/SampleAction#test"; + var expectedStatusCode = StatusCodes.Status308PermanentRedirect; + + var httpContext = GetHttpContext(expectedUrl); + var result = new RedirectToRouteResult("Sample", null, true, true, "test"); + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode); + Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]); + } + + private static HttpContext GetHttpContext(string path) + { + var services = CreateServices(path); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + + private static IServiceCollection CreateServices(string path) + { + var services = new ServiceCollection(); + services.AddSingleton(new TestLinkGenerator { Url = path }); + + services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); + return services; } } diff --git a/src/Http/Http.Results/test/SignInResultTest.cs b/src/Http/Http.Results/test/SignInResultTest.cs index 2de4d09df7..ba80cce51a 100644 --- a/src/Http/Http.Results/test/SignInResultTest.cs +++ b/src/Http/Http.Results/test/SignInResultTest.cs @@ -10,86 +10,85 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class SignInResultTest { - public class SignInResultTest + [Fact] + public async Task ExecuteAsync_InvokesSignInAsyncOnAuthenticationManager() { - [Fact] - public async Task ExecuteAsync_InvokesSignInAsyncOnAuthenticationManager() - { - // Arrange - var principal = new ClaimsPrincipal(); - var auth = new Mock(); - auth - .Setup(c => c.SignInAsync(It.IsAny(), "", principal, null)) - .Returns(Task.CompletedTask) - .Verifiable(); + // Arrange + var principal = new ClaimsPrincipal(); + var auth = new Mock(); + auth + .Setup(c => c.SignInAsync(It.IsAny(), "", principal, null)) + .Returns(Task.CompletedTask) + .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new SignInResult("", principal, null); + var httpContext = GetHttpContext(auth.Object); + var result = new SignInResult("", principal, null); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - auth.Verify(); - } + // Assert + auth.Verify(); + } - [Fact] - public async Task ExecuteAsync_InvokesSignInAsyncOnAuthenticationManagerWithDefaultScheme() - { - // Arrange - var principal = new ClaimsPrincipal(); - var auth = new Mock(); - auth - .Setup(c => c.SignInAsync(It.IsAny(), null, principal, null)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new SignInResult(principal); + [Fact] + public async Task ExecuteAsync_InvokesSignInAsyncOnAuthenticationManagerWithDefaultScheme() + { + // Arrange + var principal = new ClaimsPrincipal(); + var auth = new Mock(); + auth + .Setup(c => c.SignInAsync(It.IsAny(), null, principal, null)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new SignInResult(principal); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - auth.Verify(); - } + // Assert + auth.Verify(); + } - [Fact] - public async Task ExecuteAsync_InvokesSignInAsyncOnConfiguredScheme() - { - // Arrange - var principal = new ClaimsPrincipal(); - var authProperties = new AuthenticationProperties(); - var auth = new Mock(); - auth - .Setup(c => c.SignInAsync(It.IsAny(), "Scheme1", principal, authProperties)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new SignInResult("Scheme1", principal, authProperties); + [Fact] + public async Task ExecuteAsync_InvokesSignInAsyncOnConfiguredScheme() + { + // Arrange + var principal = new ClaimsPrincipal(); + var authProperties = new AuthenticationProperties(); + var auth = new Mock(); + auth + .Setup(c => c.SignInAsync(It.IsAny(), "Scheme1", principal, authProperties)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new SignInResult("Scheme1", principal, authProperties); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - auth.Verify(); - } + // Assert + auth.Verify(); + } - private static DefaultHttpContext GetHttpContext(IAuthenticationService auth) - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices() - .AddSingleton(auth) - .BuildServiceProvider(); - return httpContext; - } + private static DefaultHttpContext GetHttpContext(IAuthenticationService auth) + { + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices() + .AddSingleton(auth) + .BuildServiceProvider(); + return httpContext; + } - private static IServiceCollection CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); - return services; - } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); + return services; } } diff --git a/src/Http/Http.Results/test/SignOutResultTest.cs b/src/Http/Http.Results/test/SignOutResultTest.cs index 055ee04637..8f7368be11 100644 --- a/src/Http/Http.Results/test/SignOutResultTest.cs +++ b/src/Http/Http.Results/test/SignOutResultTest.cs @@ -10,86 +10,85 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class SignOutResultTest { - public class SignOutResultTest + [Fact] + public async Task ExecuteAsync_NoArgsInvokesDefaultSignOut() { - [Fact] - public async Task ExecuteAsync_NoArgsInvokesDefaultSignOut() - { - // Arrange - var auth = new Mock(); - auth - .Setup(c => c.SignOutAsync(It.IsAny(), null, null)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new SignOutResult(); + // Arrange + var auth = new Mock(); + auth + .Setup(c => c.SignOutAsync(It.IsAny(), null, null)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new SignOutResult(); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - auth.Verify(); - } + // Assert + auth.Verify(); + } - [Fact] - public async Task ExecuteAsync_InvokesSignOutAsyncOnAuthenticationManager() - { - // Arrange - var auth = new Mock(); - auth - .Setup(c => c.SignOutAsync(It.IsAny(), "", null)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new SignOutResult("", null); + [Fact] + public async Task ExecuteAsync_InvokesSignOutAsyncOnAuthenticationManager() + { + // Arrange + var auth = new Mock(); + auth + .Setup(c => c.SignOutAsync(It.IsAny(), "", null)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new SignOutResult("", null); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - auth.Verify(); - } + // Assert + auth.Verify(); + } - [Fact] - public async Task ExecuteAsync_InvokesSignOutAsyncOnAllConfiguredSchemes() - { - // Arrange - var authProperties = new AuthenticationProperties(); - var auth = new Mock(); - auth - .Setup(c => c.SignOutAsync(It.IsAny(), "Scheme1", authProperties)) - .Returns(Task.CompletedTask) - .Verifiable(); - auth - .Setup(c => c.SignOutAsync(It.IsAny(), "Scheme2", authProperties)) - .Returns(Task.CompletedTask) - .Verifiable(); - var httpContext = GetHttpContext(auth.Object); - var result = new SignOutResult(new[] { "Scheme1", "Scheme2" }, authProperties); + [Fact] + public async Task ExecuteAsync_InvokesSignOutAsyncOnAllConfiguredSchemes() + { + // Arrange + var authProperties = new AuthenticationProperties(); + var auth = new Mock(); + auth + .Setup(c => c.SignOutAsync(It.IsAny(), "Scheme1", authProperties)) + .Returns(Task.CompletedTask) + .Verifiable(); + auth + .Setup(c => c.SignOutAsync(It.IsAny(), "Scheme2", authProperties)) + .Returns(Task.CompletedTask) + .Verifiable(); + var httpContext = GetHttpContext(auth.Object); + var result = new SignOutResult(new[] { "Scheme1", "Scheme2" }, authProperties); - // Act - await result.ExecuteAsync(httpContext); + // Act + await result.ExecuteAsync(httpContext); - // Assert - auth.Verify(); - } + // Assert + auth.Verify(); + } - private static DefaultHttpContext GetHttpContext(IAuthenticationService auth) - { - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices() - .AddSingleton(auth) - .BuildServiceProvider(); - return httpContext; - } + private static DefaultHttpContext GetHttpContext(IAuthenticationService auth) + { + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices() + .AddSingleton(auth) + .BuildServiceProvider(); + return httpContext; + } - private static IServiceCollection CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); - return services; - } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); + return services; } } diff --git a/src/Http/Http.Results/test/StatusCodeResultTests.cs b/src/Http/Http.Results/test/StatusCodeResultTests.cs index bc32a64ae4..85dca965ce 100644 --- a/src/Http/Http.Results/test/StatusCodeResultTests.cs +++ b/src/Http/Http.Results/test/StatusCodeResultTests.cs @@ -6,40 +6,39 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class StatusCodeResultTests { - public class StatusCodeResultTests + [Fact] + public void StatusCodeResult_ExecuteResultSetsResponseStatusCode() { - [Fact] - public void StatusCodeResult_ExecuteResultSetsResponseStatusCode() - { - // Arrange - var result = new StatusCodeResult(StatusCodes.Status404NotFound); + // Arrange + var result = new StatusCodeResult(StatusCodes.Status404NotFound); - var httpContext = GetHttpContext(); + var httpContext = GetHttpContext(); - // Act - result.ExecuteAsync(httpContext); + // Act + result.ExecuteAsync(httpContext); - // Assert - Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode); - } + // Assert + Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode); + } - private static IServiceCollection CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(NullLoggerFactory.Instance); - return services; - } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddSingleton(NullLoggerFactory.Instance); + return services; + } - private static HttpContext GetHttpContext() - { - var services = CreateServices(); + private static HttpContext GetHttpContext() + { + var services = CreateServices(); - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = services.BuildServiceProvider(); + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); - return httpContext; - } + return httpContext; } } diff --git a/src/Http/Http.Results/test/TestLinkGenerator.cs b/src/Http/Http.Results/test/TestLinkGenerator.cs index ec026e13a7..8f8d9e0167 100644 --- a/src/Http/Http.Results/test/TestLinkGenerator.cs +++ b/src/Http/Http.Results/test/TestLinkGenerator.cs @@ -4,26 +4,25 @@ using System; using Microsoft.AspNetCore.Routing; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +internal sealed class TestLinkGenerator : LinkGenerator { - internal sealed class TestLinkGenerator : LinkGenerator - { - public string Url { get; set; } + public string Url { get; set; } - public override string GetPathByAddress(HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues = null, PathString? pathBase = null, FragmentString fragment = default, LinkOptions options = null) - { - throw new NotImplementedException(); - } + public override string GetPathByAddress(HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues = null, PathString? pathBase = null, FragmentString fragment = default, LinkOptions options = null) + { + throw new NotImplementedException(); + } - public override string GetPathByAddress(TAddress address, RouteValueDictionary values, PathString pathBase = default, FragmentString fragment = default, LinkOptions options = null) - { - throw new NotImplementedException(); - } + public override string GetPathByAddress(TAddress address, RouteValueDictionary values, PathString pathBase = default, FragmentString fragment = default, LinkOptions options = null) + { + throw new NotImplementedException(); + } - public override string GetUriByAddress(HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues = null, string scheme = null, HostString? host = null, PathString? pathBase = null, FragmentString fragment = default, LinkOptions options = null) - => Url; + public override string GetUriByAddress(HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues = null, string scheme = null, HostString? host = null, PathString? pathBase = null, FragmentString fragment = default, LinkOptions options = null) + => Url; - public override string GetUriByAddress(TAddress address, RouteValueDictionary values, string scheme, HostString host, PathString pathBase = default, FragmentString fragment = default, LinkOptions options = null) - => Url; - } + public override string GetUriByAddress(TAddress address, RouteValueDictionary values, string scheme, HostString host, PathString pathBase = default, FragmentString fragment = default, LinkOptions options = null) + => Url; } diff --git a/src/Http/Http.Results/test/UnauthorizedResultTests.cs b/src/Http/Http.Results/test/UnauthorizedResultTests.cs index f4050fe6e4..f6e2640fa7 100644 --- a/src/Http/Http.Results/test/UnauthorizedResultTests.cs +++ b/src/Http/Http.Results/test/UnauthorizedResultTests.cs @@ -3,18 +3,17 @@ using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class UnauthorizedResultTests { - public class UnauthorizedResultTests + [Fact] + public void UnauthorizedResult_InitializesStatusCode() { - [Fact] - public void UnauthorizedResult_InitializesStatusCode() - { - // Arrange & act - var result = new UnauthorizedResult(); + // Arrange & act + var result = new UnauthorizedResult(); - // Assert - Assert.Equal(StatusCodes.Status401Unauthorized, result.StatusCode); - } + // Assert + Assert.Equal(StatusCodes.Status401Unauthorized, result.StatusCode); } } diff --git a/src/Http/Http.Results/test/UnprocessableEntityObjectResultTests.cs b/src/Http/Http.Results/test/UnprocessableEntityObjectResultTests.cs index 1d5b68413a..7c26e98fb5 100644 --- a/src/Http/Http.Results/test/UnprocessableEntityObjectResultTests.cs +++ b/src/Http/Http.Results/test/UnprocessableEntityObjectResultTests.cs @@ -3,20 +3,19 @@ using Xunit; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class UnprocessableEntityObjectResultTests { - public class UnprocessableEntityObjectResultTests + [Fact] + public void UnprocessableEntityObjectResult_SetsStatusCodeAndValue() { - [Fact] - public void UnprocessableEntityObjectResult_SetsStatusCodeAndValue() - { - // Arrange & Act - var obj = new object(); - var result = new UnprocessableEntityObjectResult(obj); + // Arrange & Act + var obj = new object(); + var result = new UnprocessableEntityObjectResult(obj); - // Assert - Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); - Assert.Equal(obj, result.Value); - } + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); + Assert.Equal(obj, result.Value); } } diff --git a/src/Http/Http.Results/test/VirtualFileResultTest.cs b/src/Http/Http.Results/test/VirtualFileResultTest.cs index e38ed10778..76946cdb0a 100644 --- a/src/Http/Http.Results/test/VirtualFileResultTest.cs +++ b/src/Http/Http.Results/test/VirtualFileResultTest.cs @@ -6,20 +6,19 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; using Microsoft.Net.Http.Headers; -namespace Microsoft.AspNetCore.Http.Result +namespace Microsoft.AspNetCore.Http.Result; + +public class VirtualFileResultTest : VirtualFileResultTestBase { - public class VirtualFileResultTest : VirtualFileResultTestBase + protected override Task ExecuteAsync(HttpContext httpContext, string path, string contentType, DateTimeOffset? lastModified = null, EntityTagHeaderValue entityTag = null, bool enableRangeProcessing = false) { - protected override Task ExecuteAsync(HttpContext httpContext, string path, string contentType, DateTimeOffset? lastModified = null, EntityTagHeaderValue entityTag = null, bool enableRangeProcessing = false) + var result = new VirtualFileResult(path, contentType) { - var result = new VirtualFileResult(path, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; + LastModified = lastModified, + EntityTag = entityTag, + EnableRangeProcessing = enableRangeProcessing, + }; - return result.ExecuteAsync(httpContext); - } + return result.ExecuteAsync(httpContext); } } -- cgit v1.2.3