diff --git a/src/Http/Http.Extensions/src/ResponseHeaders.cs b/src/Http/Http.Extensions/src/ResponseHeaders.cs index 98c8ad24da86..0150706d8cef 100644 --- a/src/Http/Http.Extensions/src/ResponseHeaders.cs +++ b/src/Http/Http.Extensions/src/ResponseHeaders.cs @@ -153,7 +153,7 @@ public DateTimeOffset? Expires } /// - /// Gets or sets the Last=Modified header for an HTTP response. + /// Gets or sets the Last-Modified header for an HTTP response. /// public DateTimeOffset? LastModified { diff --git a/src/Http/Http.Results/src/AcceptedAtRouteResult.cs b/src/Http/Http.Results/src/AcceptedAtRouteResult.cs index 8159803bccce..007a2e5f39c6 100644 --- a/src/Http/Http.Results/src/AcceptedAtRouteResult.cs +++ b/src/Http/Http.Results/src/AcceptedAtRouteResult.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; @@ -48,7 +47,7 @@ public AcceptedAtRouteResult( public RouteValueDictionary RouteValues { get; } /// - protected override void OnFormatting(HttpContext context) + protected override void ConfigureResponseHeaders(HttpContext context) { var linkGenerator = context.RequestServices.GetRequiredService(); var url = linkGenerator.GetUriByAddress( diff --git a/src/Http/Http.Results/src/AcceptedResult.cs b/src/Http/Http.Results/src/AcceptedResult.cs index d7e1da54e514..9725a0d4a90a 100644 --- a/src/Http/Http.Results/src/AcceptedResult.cs +++ b/src/Http/Http.Results/src/AcceptedResult.cs @@ -58,13 +58,8 @@ public AcceptedResult(Uri locationUri, object? value) public string? Location { get; set; } /// - protected override void OnFormatting(HttpContext context) + protected override void ConfigureResponseHeaders(HttpContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - if (!string.IsNullOrEmpty(Location)) { context.Response.Headers.Location = Location; diff --git a/src/Http/Http.Results/src/BadRequestResult.cs b/src/Http/Http.Results/src/BadRequestResult.cs deleted file mode 100644 index eff601caa1f0..000000000000 --- a/src/Http/Http.Results/src/BadRequestResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Http.Result -{ - internal sealed class BadRequestResult : StatusCodeResult - { - public BadRequestResult() : base(StatusCodes.Status400BadRequest) - { - } - } -} diff --git a/src/Http/Http.Results/src/ConflictResult.cs b/src/Http/Http.Results/src/ConflictResult.cs deleted file mode 100644 index 2baf7d079fb0..000000000000 --- a/src/Http/Http.Results/src/ConflictResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Http.Result -{ - internal class ConflictResult : StatusCodeResult - { - public ConflictResult() : base(StatusCodes.Status409Conflict) - { - } - } -} diff --git a/src/Http/Http.Results/src/CreatedAtRouteResult.cs b/src/Http/Http.Results/src/CreatedAtRouteResult.cs index 8fe982930663..e2c7ec5a5790 100644 --- a/src/Http/Http.Results/src/CreatedAtRouteResult.cs +++ b/src/Http/Http.Results/src/CreatedAtRouteResult.cs @@ -48,7 +48,7 @@ public CreatedAtRouteResult( public RouteValueDictionary? RouteValues { get; set; } /// - protected override void OnFormatting(HttpContext context) + protected override void ConfigureResponseHeaders(HttpContext context) { var linkGenerator = context.RequestServices.GetRequiredService(); var url = linkGenerator.GetUriByRouteValues( diff --git a/src/Http/Http.Results/src/CreatedResult.cs b/src/Http/Http.Results/src/CreatedResult.cs index 23be3d084722..71655a443946 100644 --- a/src/Http/Http.Results/src/CreatedResult.cs +++ b/src/Http/Http.Results/src/CreatedResult.cs @@ -49,7 +49,7 @@ public CreatedResult(Uri location, object? value) public string Location { get; init; } /// - protected override void OnFormatting(HttpContext context) + 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 cc51ed505112..d2867edd2b1e 100644 --- a/src/Http/Http.Results/src/FileContentResult.cs +++ b/src/Http/Http.Results/src/FileContentResult.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.IO; -using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -18,7 +16,7 @@ internal sealed partial class FileContentResult : FileResult, IResult /// /// The bytes that represent the file contents. /// The Content-Type header of the response. - public FileContentResult(byte[] fileContents, string contentType) + public FileContentResult(byte[] fileContents, string? contentType) : base(contentType) { FileContents = fileContents; diff --git a/src/Http/Http.Results/src/FileResult.cs b/src/Http/Http.Results/src/FileResult.cs index 1e0afe40a1f7..1b5cf7abdf33 100644 --- a/src/Http/Http.Results/src/FileResult.cs +++ b/src/Http/Http.Results/src/FileResult.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; @@ -17,14 +16,9 @@ internal abstract partial class FileResult /// the provided . /// /// The Content-Type header of the response. - protected FileResult(string contentType) + protected FileResult(string? contentType) { - if (contentType == null) - { - throw new ArgumentNullException(nameof(contentType)); - } - - ContentType = contentType; + ContentType = contentType ?? "application/octet-stream"; } /// diff --git a/src/Http/Http.Results/src/FileStreamResult.cs b/src/Http/Http.Results/src/FileStreamResult.cs index 7b7862047ed1..f40ee94bab85 100644 --- a/src/Http/Http.Results/src/FileStreamResult.cs +++ b/src/Http/Http.Results/src/FileStreamResult.cs @@ -1,13 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.IO; -using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Http.Result { @@ -24,26 +20,8 @@ internal sealed class FileStreamResult : FileResult, IResult /// /// The stream with the file. /// The Content-Type header of the response. - public FileStreamResult(Stream fileStream, string contentType) - : this(fileStream, MediaTypeHeaderValue.Parse(contentType)) - { - if (fileStream == null) - { - throw new ArgumentNullException(nameof(fileStream)); - } - - FileStream = fileStream; - } - - /// - /// 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, MediaTypeHeaderValue contentType) - : base(contentType.ToString()) + public FileStreamResult(Stream fileStream, string? contentType) + : base(contentType) { if (fileStream == null) { @@ -58,10 +36,10 @@ public FileStreamResult(Stream fileStream, MediaTypeHeaderValue contentType) /// public Stream FileStream { get; } - public Task ExecuteAsync(HttpContext httpContext) + public async Task ExecuteAsync(HttpContext httpContext) { var logger = httpContext.RequestServices.GetRequiredService>(); - using (FileStream) + await using (FileStream) { Log.ExecutingFileResult(logger, this); @@ -90,12 +68,12 @@ public Task ExecuteAsync(HttpContext httpContext) if (!serveBody) { - return Task.CompletedTask; + return; } if (range != null && rangeLength == 0) { - return Task.CompletedTask; + return; } if (range != null) @@ -103,7 +81,7 @@ public Task ExecuteAsync(HttpContext httpContext) FileResultHelper.Log.WritingRangeToBody(logger); } - return FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength); + await FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength); } } } diff --git a/src/Http/Http.Results/src/NotFoundResult.cs b/src/Http/Http.Results/src/NotFoundResult.cs deleted file mode 100644 index b0d7902eb8e4..000000000000 --- a/src/Http/Http.Results/src/NotFoundResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Http.Result -{ - internal sealed class NotFoundResult : StatusCodeResult - { - public NotFoundResult() : base(StatusCodes.Status404NotFound) - { - } - } -} diff --git a/src/Http/Http.Results/src/ObjectResult.cs b/src/Http/Http.Results/src/ObjectResult.cs index 0cdf80353c5d..fbac679943f3 100644 --- a/src/Http/Http.Results/src/ObjectResult.cs +++ b/src/Http/Http.Results/src/ObjectResult.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; @@ -42,7 +41,7 @@ public Task ExecuteAsync(HttpContext httpContext) { var loggerFactory = httpContext.RequestServices.GetRequiredService(); var logger = loggerFactory.CreateLogger(GetType()); - Log.ObjectResultExecuting(logger, Value); + Log.ObjectResultExecuting(logger, Value, StatusCode); if (Value is ProblemDetails problemDetails) { @@ -54,10 +53,25 @@ public Task ExecuteAsync(HttpContext httpContext) httpContext.Response.StatusCode = statusCode; } + ConfigureResponseHeaders(httpContext); + + if (Value is null) + { + return Task.CompletedTask; + } + OnFormatting(httpContext); return httpContext.Response.WriteAsJsonAsync(Value); } + protected virtual void OnFormatting(HttpContext httpContext) + { + } + + protected virtual void ConfigureResponseHeaders(HttpContext httpContext) + { + } + 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. @@ -89,23 +103,29 @@ private void ApplyProblemDetailsDefaults(ProblemDetails problemDetails) } } - protected virtual void OnFormatting(HttpContext httpContext) - { - } - private static partial class Log { - public static void ObjectResultExecuting(ILogger logger, object? value) + public static void ObjectResultExecuting(ILogger logger, object? value, int? statusCode) { if (logger.IsEnabled(LogLevel.Information)) { - var valueType = value is null ? "null" : value.GetType().FullName!; - ObjectResultExecuting(logger, valueType); + 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}'.", EventName = "ObjectResultExecuting", SkipEnabledCheck = true)] - public static partial void ObjectResultExecuting(ILogger logger, string type); + [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); } } } diff --git a/src/Http/Http.Results/src/OkResult.cs b/src/Http/Http.Results/src/OkResult.cs deleted file mode 100644 index 9cf0430fa990..000000000000 --- a/src/Http/Http.Results/src/OkResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Http.Result -{ - internal class OkResult : StatusCodeResult - { - public OkResult() : base(StatusCodes.Status200OK) - { - } - } -} diff --git a/src/Http/Http.Results/src/PhysicalFileResult.cs b/src/Http/Http.Results/src/PhysicalFileResult.cs index 9a53b91e9466..a891319546d2 100644 --- a/src/Http/Http.Results/src/PhysicalFileResult.cs +++ b/src/Http/Http.Results/src/PhysicalFileResult.cs @@ -1,9 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.IO; -using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -22,7 +19,7 @@ internal sealed partial class PhysicalFileResult : FileResult, IResult /// /// 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) + public PhysicalFileResult(string fileName, string? contentType) : base(contentType) { FileName = fileName; diff --git a/src/Http/Http.Results/src/PublicAPI.Unshipped.txt b/src/Http/Http.Results/src/PublicAPI.Unshipped.txt index 65f8f1d41689..ce00f48fd907 100644 --- a/src/Http/Http.Results/src/PublicAPI.Unshipped.txt +++ b/src/Http/Http.Results/src/PublicAPI.Unshipped.txt @@ -1,106 +1,33 @@ #nullable enable Microsoft.AspNetCore.Http.Results -static Microsoft.AspNetCore.Http.Results.Accepted() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Accepted(System.Uri! uri) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Accepted(System.Uri! uri, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Accepted(object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Accepted(string? uri) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Accepted(string? uri, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.AcceptedAtRoute(object? routeValues) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.AcceptedAtRoute(object? routeValues, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.AcceptedAtRoute(string? routeName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.AcceptedAtRoute(string? routeName, object? routeValues) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.AcceptedAtRoute(string? routeName, object? routeValues, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.BadRequest() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.BadRequest(object? error) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Challenge() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Challenge(Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Challenge(Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties, params string![]! authenticationSchemes) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Challenge(params string![]! authenticationSchemes) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Conflict() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Conflict(object? error) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Content(string! content) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Content(string! content, Microsoft.Net.Http.Headers.MediaTypeHeaderValue? contentType) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Content(string! content, string! contentType) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Content(string! content, string! contentType, System.Text.Encoding! contentEncoding) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Accepted(string? uri = null, object? value = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.AcceptedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.BadRequest(object? error = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Bytes(byte[]! contents, string? contentType = null, string? fileDownloadName = null, bool enableRangeProcessing = false, System.DateTimeOffset? lastModified = null, Microsoft.Net.Http.Headers.EntityTagHeaderValue? entityTag = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Challenge(Microsoft.AspNetCore.Authentication.AuthenticationProperties? properties = null, System.Collections.Generic.IList? authenticationSchemes = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Conflict(object? error = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Content(string! content, Microsoft.Net.Http.Headers.MediaTypeHeaderValue! contentType) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Content(string! content, string? contentType = null, System.Text.Encoding? contentEncoding = null) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.Created(System.Uri! uri, object? value) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.Created(string! uri, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.CreatedAtRoute(object? routeValues, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.CreatedAtRoute(string? routeName, object? routeValues, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.CreatedAtRoute(string? routeName, object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, string? fileDownloadName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string! contentType, string? fileDownloadName, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, string? fileDownloadName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string! contentType, string? fileDownloadName, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, string? fileDownloadName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.File(string! virtualPath, string! contentType, string? fileDownloadName, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Forbid() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Forbid(Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Forbid(Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties, params string![]! authenticationSchemes) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Forbid(params string![]! authenticationSchemes) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.CreatedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.File(System.IO.Stream! fileStream, string? contentType = null, string? fileDownloadName = null, System.DateTimeOffset? lastModified = null, Microsoft.Net.Http.Headers.EntityTagHeaderValue? entityTag = null, bool enableRangeProcessing = false) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.File(byte[]! fileContents, string? contentType = null, string? fileDownloadName = null, bool enableRangeProcessing = false, System.DateTimeOffset? lastModified = null, Microsoft.Net.Http.Headers.EntityTagHeaderValue? entityTag = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.File(string! path, string? contentType = null, string? fileDownloadName = null, System.DateTimeOffset? lastModified = null, Microsoft.Net.Http.Headers.EntityTagHeaderValue? entityTag = null, bool enableRangeProcessing = false) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Forbid(Microsoft.AspNetCore.Authentication.AuthenticationProperties? properties = null, System.Collections.Generic.IList? authenticationSchemes = null) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.Json(object? data, System.Text.Json.JsonSerializerOptions? options = null, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.LocalRedirect(string! localUrl) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.LocalRedirectPermanent(string! localUrl) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.LocalRedirectPermanentPreserveMethod(string! localUrl) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.LocalRedirectPreserveMethod(string! localUrl) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.LocalRedirect(string! localUrl, bool permanent = false, bool preserveMethod = false) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.NoContent() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.NotFound() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.NotFound(object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Ok() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Ok(object? value) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, string? fileDownloadName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, string? fileDownloadName, System.DateTimeOffset? lastModified, Microsoft.Net.Http.Headers.EntityTagHeaderValue! entityTag, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.PhysicalFile(string! physicalPath, string! contentType, string? fileDownloadName, bool enableRangeProcessing) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.NotFound(object? value = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Ok(object? value = null) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.Problem(string? detail = null, string? instance = null, int? statusCode = null, string? title = null, string? type = null) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.Redirect(string! url) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectPermanent(string! url) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectPermanentPreserveMethod(string! url) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectPreserveMethod(string! url) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoute(object? routeValues) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoute(string? routeName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoute(string? routeName, object? routeValues) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoute(string? routeName, object? routeValues, string? fragment) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoute(string? routeName, string? fragment) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePermanent(object? routeValues) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePermanent(string? routeName) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePermanent(string? routeName, object? routeValues) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePermanent(string? routeName, object? routeValues, string? fragment) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePermanent(string? routeName, string? fragment) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePermanentPreserveMethod(string? routeName = null, object? routeValues = null, string? fragment = null) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.RedirectToRoutePreserveMethod(string? routeName = null, object? routeValues = null, string? fragment = null) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignIn(System.Security.Claims.ClaimsPrincipal! principal) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignIn(System.Security.Claims.ClaimsPrincipal! principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignIn(System.Security.Claims.ClaimsPrincipal! principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties, string! authenticationScheme) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignIn(System.Security.Claims.ClaimsPrincipal! principal, string! authenticationScheme) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignOut() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignOut(Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignOut(Microsoft.AspNetCore.Authentication.AuthenticationProperties! properties, params string![]! authenticationSchemes) -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.SignOut(params string![]! authenticationSchemes) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Redirect(string! url, bool permanent = false, bool preserveMethod = false) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.RedirectToRoute(string? routeName = null, object? routeValues = null, bool permanent = false, bool preserveMethod = false, string? fragment = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.SignIn(System.Security.Claims.ClaimsPrincipal! principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties? properties = null, string? authenticationScheme = null) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.SignOut(Microsoft.AspNetCore.Authentication.AuthenticationProperties? properties = null, System.Collections.Generic.IList? authenticationSchemes = null) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.StatusCode(int statusCode) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Stream(System.IO.Stream! stream, string? contentType = null, string? fileDownloadName = null, System.DateTimeOffset? lastModified = null, Microsoft.Net.Http.Headers.EntityTagHeaderValue? entityTag = null, bool enableRangeProcessing = false) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.Text(string! content, string? contentType = null, System.Text.Encoding? contentEncoding = null) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.Unauthorized() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.UnprocessableEntity() -> Microsoft.AspNetCore.Http.IResult! -static Microsoft.AspNetCore.Http.Results.UnprocessableEntity(object? error) -> Microsoft.AspNetCore.Http.IResult! +static Microsoft.AspNetCore.Http.Results.UnprocessableEntity(object? error = null) -> Microsoft.AspNetCore.Http.IResult! static Microsoft.AspNetCore.Http.Results.ValidationProblem(System.Collections.Generic.IDictionary! errors, string? detail = null, string? instance = null, int? statusCode = null, string? title = null, string? type = null) -> Microsoft.AspNetCore.Http.IResult! diff --git a/src/Http/Http.Results/src/RedirectResult.cs b/src/Http/Http.Results/src/RedirectResult.cs index 8624683290b6..1ea822318ada 100644 --- a/src/Http/Http.Results/src/RedirectResult.cs +++ b/src/Http/Http.Results/src/RedirectResult.cs @@ -11,27 +11,6 @@ namespace Microsoft.AspNetCore.Http.Result { internal sealed partial class RedirectResult : IResult { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The local URL to redirect to. - public RedirectResult(string url) - : this(url, permanent: false) - { - } - - /// - /// 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). - public RedirectResult(string url, bool permanent) - : this(url, permanent, preserveMethod: false) - { - } - /// /// Initializes a new instance of the class with the values /// provided. diff --git a/src/Http/Http.Results/src/Results.cs b/src/Http/Http.Results/src/Results.cs index bf926f40edd6..7f3984723c47 100644 --- a/src/Http/Http.Results/src/Results.cs +++ b/src/Http/Http.Results/src/Results.cs @@ -1,13 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; -using System.IO; using System.Security.Claims; using System.Text; using System.Text.Json; using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Result; using Microsoft.AspNetCore.Mvc; @@ -20,35 +18,8 @@ namespace Microsoft.AspNetCore.Http /// public static class Results { - #region SignIn / SignOut / Challenge - - /// - /// Creates an that on execution invokes . - /// - /// The behavior of this method depends on the in use. - /// and - /// are among likely status results. - /// - /// - /// The created for the response. - public static IResult Challenge() - => new ChallengeResult(); - - /// - /// Creates an that on execution invokes . - /// - /// The behavior of this method depends on the in use. - /// and - /// are among likely status results. - /// - /// - /// The authentication schemes to challenge. - /// The created for the response. - public static IResult Challenge(params string[] authenticationSchemes) - => new ChallengeResult { AuthenticationSchemes = authenticationSchemes }; - /// - /// Creates an that on execution invokes . + /// Creates an that on execution invokes . /// /// The behavior of this method depends on the in use. /// and @@ -57,54 +28,30 @@ public static IResult Challenge(params string[] authenticationSchemes) /// /// used to perform the authentication /// challenge. + /// The authentication schemes to challenge. /// The created for the response. - public static IResult Challenge(AuthenticationProperties properties) - => new ChallengeResult { Properties = properties }; + public static IResult Challenge( + AuthenticationProperties? properties = null, + IList? authenticationSchemes = null) + => new ChallengeResult { AuthenticationSchemes = authenticationSchemes ?? Array.Empty(), Properties = properties }; /// - /// Creates an that on execution invokes . + /// Creates a that on execution invokes . /// - /// The behavior of this method depends on the in use. - /// and - /// are among likely status results. + /// 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. - public static IResult Challenge( - AuthenticationProperties properties, - params string[] authenticationSchemes) - => new ChallengeResult { AuthenticationSchemes = authenticationSchemes, Properties = properties }; - - /// - /// Creates an that on execution invokes . - /// - /// The containing the user claims. - /// The created for the response. - public static IResult SignIn(ClaimsPrincipal principal) - => new SignInResult(principal); - - /// - /// Creates an that on execution invokes . - /// - /// The containing the user claims. - /// The authentication scheme to use for the sign-in operation. - /// The created for the response. - public static IResult SignIn(ClaimsPrincipal principal, string authenticationScheme) - => new SignInResult(authenticationScheme, principal); - - /// - /// Creates an that on execution invokes . - /// - /// The containing the user claims. - /// used to perform the sign-in operation. - /// The created for the response. - public static IResult SignIn( - ClaimsPrincipal principal, - AuthenticationProperties properties) - => new SignInResult(principal, properties); + /// + /// 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 . @@ -115,63 +62,24 @@ public static IResult SignIn( /// The created for the response. public static IResult SignIn( ClaimsPrincipal principal, - AuthenticationProperties properties, - string authenticationScheme) + AuthenticationProperties? properties = null, + string? authenticationScheme = null) => new SignInResult(authenticationScheme, principal, properties); - /// - /// Creates an that on execution invokes . - /// - /// The created for the response. - public static IResult SignOut() - => new SignOutResult(); - - /// - /// Creates an that on execution invokes . - /// - /// used to perform the sign-out operation. - /// The created for the response. - public static IResult SignOut(AuthenticationProperties properties) - => new SignOutResult(properties); - - /// - /// Creates an that on execution invokes . - /// - /// The authentication schemes to use for the sign-out operation. - /// The created for the response. - public static IResult SignOut(params string[] authenticationSchemes) - => new SignOutResult(authenticationSchemes); - /// /// 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, params string[] authenticationSchemes) - => new SignOutResult(authenticationSchemes, properties); - #endregion - - #region ContentResult - /// - /// Writes the string to the HTTP response. - /// - /// The content to write to the response. - /// The created object for the response. - public static IResult Content(string content) - => Content(content, (MediaTypeHeaderValue?)null); - - /// - /// 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, string contentType) - => Content(content, MediaTypeHeaderValue.Parse(contentType)); + 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). @@ -181,1082 +89,317 @@ public static IResult Content(string content, string contentType) /// 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, Encoding contentEncoding) - { - var mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); - mediaTypeHeaderValue.Encoding = contentEncoding ?? mediaTypeHeaderValue.Encoding; - return Content(content, mediaTypeHeaderValue); - } + 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. - public static IResult Content(string content, MediaTypeHeaderValue? contentType) - { - return new ContentResult - { - Content = content, - ContentType = contentType?.ToString() - }; - } - #endregion - - #region ForbidResult - /// - /// 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. - /// - /// - /// The created for the response. - public static IResult Forbid() - => new ForbidResult(); - - /// - /// 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. - /// - /// - /// 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(params string[] authenticationSchemes) - => new ForbidResult { AuthenticationSchemes = authenticationSchemes }; - - /// - /// 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 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) - => new ForbidResult { 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. + /// If encoding is provided by both the 'charset' and the parameters, then + /// the parameter is chosen as the final encoding. /// - public static IResult Forbid(AuthenticationProperties properties, params string[] authenticationSchemes) - => new ForbidResult { Properties = properties, AuthenticationSchemes = authenticationSchemes, }; - #endregion - - /// - /// 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) - { - return new JsonResult - { - Value = data, - JsonSerializerOptions = options, - ContentType = contentType, - StatusCode = statusCode, - }; - } - - #region FileContentResult - /// - /// Returns a file with the specified as content (), - /// and the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// The created for the response. - public static IResult File(byte[] fileContents, string contentType) - => File(fileContents, contentType, fileDownloadName: null); - - /// - /// Returns a file with the specified as content (), - /// and the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// Set to true to enable range requests processing. - /// The created for the response. - public static IResult File(byte[] fileContents, string contentType, bool enableRangeProcessing) - => File(fileContents, contentType, fileDownloadName: null, enableRangeProcessing: enableRangeProcessing); - - /// - /// Returns a file with the specified as content (), the - /// specified as the Content-Type and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// The suggested file name. - /// The created for the response. - public static IResult File(byte[] fileContents, string contentType, string? fileDownloadName) - => new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName }; - - /// - /// Returns a file with the specified as content (), the - /// specified as the Content-Type and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// The suggested file name. - /// Set to true to enable range requests processing. - /// The created for the response. - public static IResult File(byte[] fileContents, string contentType, string? fileDownloadName, bool enableRangeProcessing) - => new FileContentResult(fileContents, contentType) - { - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - - /// - /// Returns a file with the specified as content (), - /// and the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult File(byte[] fileContents, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new FileContentResult(fileContents, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - }; - } - - /// - /// Returns a file with the specified as content (), - /// and the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// 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. - public static IResult File(byte[] fileContents, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new FileContentResult(fileContents, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; - } - - /// - /// Returns a file with the specified as content (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// The Content-Type of the file. - /// The suggested file name. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult File(byte[] fileContents, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new FileContentResult(fileContents, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - }; - } - - /// - /// Returns a file with the specified as content (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The file contents. - /// 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. - public static IResult File(byte[] fileContents, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new FileContentResult(fileContents, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - } - #endregion - - #region FileStreamResult - /// - /// Returns a file in the specified (), with the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// The created for the response. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult File(Stream fileStream, string contentType) - => File(fileStream, contentType, fileDownloadName: null); - - /// - /// Returns a file in the specified (), with the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// 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 File(Stream fileStream, string contentType, bool enableRangeProcessing) - => File(fileStream, contentType, fileDownloadName: null, enableRangeProcessing: enableRangeProcessing); - - /// - /// Returns a file in the specified () with the - /// specified as the Content-Type and the - /// specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// The suggested file name. - /// The created for the response. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult File(Stream fileStream, string contentType, string? fileDownloadName) - => new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName }; - - /// - /// Returns a file in the specified () with the - /// specified as the Content-Type and the - /// specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// The suggested file name. - /// 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 File(Stream fileStream, string contentType, string? fileDownloadName, bool enableRangeProcessing) - => new FileStreamResult(fileStream, contentType) - { - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - - /// - /// Returns a file in the specified (), - /// and the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult File(Stream fileStream, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new FileStreamResult(fileStream, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - }; - } - - /// - /// Returns a file in the specified (), - /// and the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// 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. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult File(Stream fileStream, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new FileStreamResult(fileStream, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; - } - - /// - /// Returns a file in the specified (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// The Content-Type of the file. - /// The suggested file name. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult File(Stream fileStream, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new FileStreamResult(fileStream, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - }; - } - - /// - /// Returns a file in the specified (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The with the contents of the file. - /// 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. - /// - /// The parameter is disposed after the response is sent. - /// - public static IResult File(Stream fileStream, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new FileStreamResult(fileStream, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - } - #endregion - - #region PhysicalFileResult - /// - /// Returns the file specified by () with the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// The created for the response. - public static IResult PhysicalFile(string physicalPath, string contentType) - => PhysicalFile(physicalPath, contentType, fileDownloadName: null); - - /// - /// Returns the file specified by () with the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// Set to true to enable range requests processing. - /// The created for the response. - public static IResult PhysicalFile(string physicalPath, string contentType, bool enableRangeProcessing) - => PhysicalFile(physicalPath, contentType, fileDownloadName: null, enableRangeProcessing: enableRangeProcessing); - - /// - /// Returns the file specified by () with the - /// specified as the Content-Type and the - /// specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// The suggested file name. - /// The created for the response. - public static IResult PhysicalFile( - string physicalPath, - string contentType, - string? fileDownloadName) - => new PhysicalFileResult(physicalPath, contentType) { FileDownloadName = fileDownloadName }; - - /// - /// Returns the file specified by () with the - /// specified as the Content-Type and the - /// specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// The suggested file name. - /// Set to true to enable range requests processing. - /// The created for the response. - public static IResult PhysicalFile( - string physicalPath, - string contentType, - string? fileDownloadName, - bool enableRangeProcessing) - => new PhysicalFileResult(physicalPath, contentType) - { - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - - /// - /// Returns the file specified by (), and - /// the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult PhysicalFile(string physicalPath, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new PhysicalFileResult(physicalPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - }; - } - - /// - /// Returns the file specified by (), and - /// the specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// 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. - public static IResult PhysicalFile(string physicalPath, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new PhysicalFileResult(physicalPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; - } - - /// - /// Returns the file specified by (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// The Content-Type of the file. - /// The suggested file name. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult PhysicalFile(string physicalPath, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new PhysicalFileResult(physicalPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - }; - } - - /// - /// Returns the file specified by (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The path to the file. The path must be an absolute path. - /// 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. - public static IResult PhysicalFile(string physicalPath, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new PhysicalFileResult(physicalPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - } - #endregion - - #region VirtualFileResult - /// - /// Returns the file specified by () with the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// The created for the response. - public static IResult File(string virtualPath, string contentType) - => File(virtualPath, contentType, fileDownloadName: null); - - /// - /// Returns the file specified by () with the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// Set to true to enable range requests processing. - /// The created for the response. - public static IResult File(string virtualPath, string contentType, bool enableRangeProcessing) - => File(virtualPath, contentType, fileDownloadName: null, enableRangeProcessing: enableRangeProcessing); - - /// - /// Returns the file specified by () with the - /// specified as the Content-Type and the - /// specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// The suggested file name. - /// The created for the response. - public static IResult File(string virtualPath, string contentType, string? fileDownloadName) - => new VirtualFileResult(virtualPath, contentType) { FileDownloadName = fileDownloadName }; - - /// - /// Returns the file specified by () with the - /// specified as the Content-Type and the - /// specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// The suggested file name. - /// Set to true to enable range requests processing. - /// The created for the response. - public static IResult File(string virtualPath, string contentType, string? fileDownloadName, bool enableRangeProcessing) - => new VirtualFileResult(virtualPath, contentType) - { - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - - /// - /// Returns the file specified by (), and the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult File(string virtualPath, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new VirtualFileResult(virtualPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - }; - } - - /// - /// Returns the file specified by (), and the - /// specified as the Content-Type. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// 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. - public static IResult File(string virtualPath, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new VirtualFileResult(virtualPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - EnableRangeProcessing = enableRangeProcessing, - }; - } - - /// - /// Returns the file specified by (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// The Content-Type of the file. - /// The suggested file name. - /// The of when the file was last modified. - /// The associated with the file. - /// The created for the response. - public static IResult File(string virtualPath, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) - { - return new VirtualFileResult(virtualPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - }; - } - - /// - /// Returns the file specified by (), the - /// specified as the Content-Type, and the specified as the suggested file name. - /// - /// This supports range requests ( or - /// if the range is not satisfiable). - /// - /// - /// The virtual path of the file to be returned. - /// 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. - public static IResult File(string virtualPath, string contentType, string? fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) - { - return new VirtualFileResult(virtualPath, contentType) - { - LastModified = lastModified, - EntityTag = entityTag, - FileDownloadName = fileDownloadName, - EnableRangeProcessing = enableRangeProcessing, - }; - } - #endregion - - #region RedirectResult variants - /// - /// Redirects () - /// to the specified . - /// - /// The URL to redirect to. - /// The created for the response. - public static IResult Redirect(string url) - { - if (string.IsNullOrEmpty(url)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(url)); - } - - return new RedirectResult(url); - } - - /// - /// Redirects () - /// to the specified . - /// - /// The URL to redirect to. - /// The created for the response. - public static IResult RedirectPermanent(string url) - { - if (string.IsNullOrEmpty(url)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(url)); - } - - return new RedirectResult(url, permanent: true); - } - - /// - /// Redirects () - /// to the specified preserving the HTTP method. - /// - /// The URL to redirect to. - /// The created for the response. - public static IResult RedirectPreserveMethod(string url) - { - if (string.IsNullOrEmpty(url)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(url)); - } - - return new RedirectResult(url: url, permanent: false, preserveMethod: true); - } - - /// - /// Redirects () - /// to the specified preserving the HTTP method. - /// - /// The URL to redirect to. - /// The created for the response. - public static IResult RedirectPermanentPreserveMethod(string url) - { - if (string.IsNullOrEmpty(url)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(url)); - } - - return new RedirectResult(url: url, permanent: true, preserveMethod: true); - } - - /// - /// Redirects () - /// to the specified . - /// - /// The local URL to redirect to. - /// The created for the response. - public static IResult LocalRedirect(string localUrl) - { - if (string.IsNullOrEmpty(localUrl)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(localUrl)); - } - - return new LocalRedirectResult(localUrl); - } - - /// - /// Redirects () - /// to the specified . - /// - /// The local URL to redirect to. - /// The created for the response. - public static IResult LocalRedirectPermanent(string localUrl) - { - if (string.IsNullOrEmpty(localUrl)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(localUrl)); - } - - return new LocalRedirectResult(localUrl, permanent: true); - } - - /// - /// Redirects () - /// to the specified preserving the HTTP method. - /// - /// The local URL to redirect to. - /// The created for the response. - public static IResult LocalRedirectPreserveMethod(string localUrl) - { - if (string.IsNullOrEmpty(localUrl)) - { - throw new ArgumentException("Argument cannot be null or empty.", nameof(localUrl)); - } - - return new LocalRedirectResult(localUrl: localUrl, permanent: false, preserveMethod: true); - } - - /// - /// Redirects () - /// to the specified preserving the HTTP method. - /// - /// The local URL to redirect to. - /// The created for the response. - public static IResult LocalRedirectPermanentPreserveMethod(string localUrl) + public static IResult Text(string content, string? contentType = null, Encoding? contentEncoding = null) { - if (string.IsNullOrEmpty(localUrl)) + MediaTypeHeaderValue? mediaTypeHeaderValue = null; + if (contentType is not null) { - throw new ArgumentException("Argument cannot be null or empty.", nameof(localUrl)); + mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); + mediaTypeHeaderValue.Encoding = contentEncoding ?? mediaTypeHeaderValue.Encoding; } - return new LocalRedirectResult(localUrl: localUrl, permanent: true, preserveMethod: true); + return new ContentResult + { + Content = content, + ContentType = mediaTypeHeaderValue?.ToString() + }; } /// - /// Redirects () to the specified route using the specified . + /// Writes the string to the HTTP response. /// - /// The name of the route. - /// The created for the response. - public static IResult RedirectToRoute(string? routeName) - => RedirectToRoute(routeName, routeValues: null); + /// 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() + }; /// - /// Redirects () to the specified route using the specified . + /// Creates a that serializes the specified object to JSON. /// - /// The parameters for a route. - /// The created for the response. - public static IResult RedirectToRoute(object? routeValues) - => RedirectToRoute(routeName: null, routeValues: routeValues); + /// 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, + }; /// - /// Redirects () to the specified route using the specified - /// and . + /// 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 name of the route. - /// The parameters for a route. + /// 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 RedirectToRoute(string? routeName, object? routeValues) - => RedirectToRoute(routeName, routeValues, fragment: null); +#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 + 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, + }; /// - /// Redirects () to the specified route using the specified - /// and . + /// 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 name of the route. - /// The fragment to add to the URL. + /// 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 RedirectToRoute(string? routeName, string? fragment) - => RedirectToRoute(routeName, routeValues: null, fragment: fragment); + 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, + }; + /// - /// Redirects () to the specified route using the specified - /// , , and . + /// Writes the specified to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// This API is an alias for . + /// /// - /// The name of the route. - /// The parameters for a route. - /// The fragment to add to the URL. + /// 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. - public static IResult RedirectToRoute( - string? routeName, - object? routeValues, - string? fragment) + /// + /// 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( +#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) { - return new RedirectToRouteResult(routeName, routeValues, fragment); + return new FileStreamResult(fileStream, contentType) + { + LastModified = lastModified, + EntityTag = entityTag, + FileDownloadName = fileDownloadName, + EnableRangeProcessing = enableRangeProcessing, + }; } /// - /// Redirects () to the specified route with - /// set to false and - /// set to true, using the specified , , and . + /// Writes the specified to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// + /// + /// This API is an alias for . + /// /// - /// The name of the route. - /// The route data to use for generating the URL. - /// The fragment to add to the URL. - /// The created for the response. - public static IResult RedirectToRoutePreserveMethod( - string? routeName = null, - object? routeValues = null, - string? fragment = null) + /// 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 RedirectToRouteResult( - routeName: routeName, - routeValues: routeValues, - permanent: false, - preserveMethod: true, - fragment: fragment); + return new FileStreamResult(stream, contentType) + { + LastModified = lastModified, + EntityTag = entityTag, + FileDownloadName = fileDownloadName, + EnableRangeProcessing = enableRangeProcessing, + }; } /// - /// Redirects () to the specified route with - /// set to true using the specified . - /// - /// The name of the route. - /// The created for the response. - public static IResult RedirectToRoutePermanent(string? routeName) - => RedirectToRoutePermanent(routeName, routeValues: null); - - /// - /// Redirects () to the specified route with - /// set to true using the specified . + /// Writes the file at the specified to the response. + /// + /// This supports range requests ( or + /// if the range is not satisfiable). + /// /// - /// The parameters for a route. + /// 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. - public static IResult RedirectToRoutePermanent(object? routeValues) - => RedirectToRoutePermanent(routeName: null, routeValues: routeValues); +#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, + EnableRangeProcessing = enableRangeProcessing, + }; + } + else + { + return new VirtualFileResult(path, contentType) + { + FileDownloadName = fileDownloadName, + LastModified = lastModified, + EntityTag = entityTag, + EnableRangeProcessing = enableRangeProcessing, + }; + } + } /// - /// Redirects () to the specified route with - /// set to true using the specified - /// and . + /// 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 name of the route. - /// The parameters for a route. + /// 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 RedirectToRoutePermanent(string? routeName, object? routeValues) - => RedirectToRoutePermanent(routeName, routeValues, fragment: null); + public static IResult Redirect(string url, bool permanent = false, bool preserveMethod = false) + => new RedirectResult(url, permanent, preserveMethod); /// - /// Redirects () to the specified route with - /// set to true using the specified - /// and . + /// 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 name of the route. - /// The fragment to add to the URL. + /// 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 RedirectToRoutePermanent(string? routeName, string? fragment) - => RedirectToRoutePermanent(routeName, routeValues: null, fragment: fragment); - + public static IResult LocalRedirect(string localUrl, bool permanent = false, bool preserveMethod = false) + => new LocalRedirectResult(localUrl, permanent, preserveMethod); + /// - /// Redirects () to the specified route with - /// set to true using the specified , - /// , and . + /// 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 RedirectToRoutePermanent( - string? routeName, - object? routeValues, - string? fragment) - { - return new RedirectToRouteResult(routeName, routeValues, permanent: true, fragment: fragment); - } - - /// - /// Redirects () to the specified route with - /// set to true and - /// set to true, using the specified , , and . - /// - /// The name of the route. - /// The route data to use for generating the URL. - /// The fragment to add to the URL. - /// The created for the response. - public static IResult RedirectToRoutePermanentPreserveMethod( - string? routeName = null, - object? routeValues = null, - string? fragment = null) - { - return new RedirectToRouteResult( + 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: true, - preserveMethod: true, + permanent: permanent, + preserveMethod: preserveMethod, fragment: fragment); - } - #endregion /// /// Creates a object by specifying a . @@ -1266,19 +409,12 @@ public static IResult RedirectToRoutePermanentPreserveMethod( public static IResult StatusCode(int statusCode) => new StatusCodeResult(statusCode); - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult NotFound() - => new NotFoundResult(); - /// /// Produces a response. /// /// The value to be included in the HTTP response body. /// The created for the response. - public static IResult NotFound(object? value) + public static IResult NotFound(object? value = null) => new NotFoundObjectResult(value); /// @@ -1288,34 +424,20 @@ public static IResult NotFound(object? value) public static IResult Unauthorized() => new UnauthorizedResult(); - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult BadRequest() - => new BadRequestResult(); - /// /// 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) + public static IResult BadRequest(object? error = null) => new BadRequestObjectResult(error); - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult Conflict() - => new ConflictResult(); - /// /// 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) + public static IResult Conflict(object? error = null) => new ConflictObjectResult(error); /// @@ -1325,34 +447,20 @@ public static IResult Conflict(object? error) public static IResult NoContent() => new NoContentResult(); - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult Ok() - => new OkResult(); - /// /// Produces a response. /// /// The value to be included in the HTTP response body. /// The created for the response. - public static IResult Ok(object? value) + public static IResult Ok(object? value = null) => new OkObjectResult(value); - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult UnprocessableEntity() - => new UnprocessableEntityResult(); - /// /// 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) + public static IResult UnprocessableEntity(object? error = null) => new UnprocessableEntityObjectResult(error); /// @@ -1412,7 +520,6 @@ public static IResult ValidationProblem( return new ObjectResult(problemDetails); } - #region CreatedResult /// /// Produces a response. /// @@ -1445,24 +552,6 @@ public static IResult Created(Uri uri, object? value) return new CreatedResult(uri, value); } - /// - /// Produces a response. - /// - /// The name of the route 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, object? value) - => CreatedAtRoute(routeName, routeValues: null, value: value); - - /// - /// Produces a response. - /// - /// 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(object? routeValues, object? value) - => CreatedAtRoute(routeName: null, routeValues: routeValues, value: value); - /// /// Produces a response. /// @@ -1470,109 +559,18 @@ public static IResult CreatedAtRoute(object? routeValues, object? value) /// 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, object? routeValues, object? value) + public static IResult CreatedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) => new CreatedAtRouteResult(routeName, routeValues, value); - #endregion - - #region AcceptedResult - /// - /// Produces a response. - /// - /// The created for the response. - public static IResult Accepted() - => new AcceptedResult(); - - /// - /// Produces a response. - /// - /// The optional content value to format in the response body. - /// The created for the response. - public static IResult Accepted(object? value) - => new AcceptedResult(location: null, value: value); - - /// - /// Produces a response. - /// - /// The optional URI with the location at which the status of requested content can be monitored. - /// The created for the response. - public static IResult Accepted(Uri uri) - { - if (uri == null) - { - throw new ArgumentNullException(nameof(uri)); - } - - return new AcceptedResult(locationUri: uri, value: null); - } - - /// - /// Produces a response. - /// - /// The optional URI with the location at which the status of requested content can be monitored. - /// The created for the response. - public static IResult Accepted(string? uri) - => new AcceptedResult(location: uri, value: null); - /// /// 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, object? value) + public static IResult Accepted(string? uri = null, object? value = null) => new AcceptedResult(uri, 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(Uri uri, object? value) - { - if (uri == null) - { - throw new ArgumentNullException(nameof(uri)); - } - - return new AcceptedResult(locationUri: uri, value: value); - } - - /// - /// Produces a response. - /// - /// The route data to use for generating the URL. - /// The created for the response. - public static IResult AcceptedAtRoute(object? routeValues) - => AcceptedAtRoute(routeName: null, routeValues: routeValues, value: null); - - /// - /// Produces a response. - /// - /// The name of the route to use for generating the URL. - /// The created for the response. - public static IResult AcceptedAtRoute(string? routeName) - => AcceptedAtRoute(routeName, routeValues: null, value: null); - - /// - /// Produces a response. - /// - /// The name of the route to use for generating the URL. - ///The route data to use for generating the URL. - /// The created for the response. - public static IResult AcceptedAtRoute(string? routeName, object? routeValues) - => AcceptedAtRoute(routeName, routeValues, value: null); - - /// - /// Produces a response. - /// - /// 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(object? routeValues, object? value) - => AcceptedAtRoute(routeName: null, routeValues: routeValues, value: value); - /// /// Produces a response. /// @@ -1580,8 +578,7 @@ public static IResult AcceptedAtRoute(object? routeValues, object? value) /// 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, object? routeValues, object? value) + public static IResult AcceptedAtRoute(string? routeName = null, object? routeValues = null, object? value = null) => new AcceptedAtRouteResult(routeName, routeValues, value); - #endregion } } diff --git a/src/Http/Http.Results/src/UnprocessableEntityResult.cs b/src/Http/Http.Results/src/UnprocessableEntityResult.cs deleted file mode 100644 index f58c43059e94..000000000000 --- a/src/Http/Http.Results/src/UnprocessableEntityResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Http.Result -{ - internal sealed class UnprocessableEntityResult : StatusCodeResult - { - public UnprocessableEntityResult() : base(StatusCodes.Status422UnprocessableEntity) - { - } - } -} diff --git a/src/Http/Http.Results/src/VirtualFileResult.cs b/src/Http/Http.Results/src/VirtualFileResult.cs index 975026f35298..242454ca8f10 100644 --- a/src/Http/Http.Results/src/VirtualFileResult.cs +++ b/src/Http/Http.Results/src/VirtualFileResult.cs @@ -1,16 +1,12 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; -using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Http.Result { @@ -28,20 +24,8 @@ 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) - : this(fileName, MediaTypeHeaderValue.Parse(contentType)) - { - } - - /// - /// 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, MediaTypeHeaderValue contentType) - : base(contentType.ToString()) + public VirtualFileResult(string fileName, string? contentType) + : base(contentType) { FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); } diff --git a/src/Http/Http.Results/test/BadRequestResultTests.cs b/src/Http/Http.Results/test/BadRequestResultTests.cs deleted file mode 100644 index 9e5dd8f6aead..000000000000 --- a/src/Http/Http.Results/test/BadRequestResultTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.AspNetCore.Http.Result -{ - public class BadRequestResultTests - { - [Fact] - public void BadRequestResult_InitializesStatusCode() - { - // Arrange & act - var badRequest = new BadRequestResult(); - - // Assert - Assert.Equal(StatusCodes.Status400BadRequest, badRequest.StatusCode); - } - } -} diff --git a/src/Http/Http.Results/test/ConflictResultTest.cs b/src/Http/Http.Results/test/ConflictResultTest.cs deleted file mode 100644 index d21eb6fc2dc8..000000000000 --- a/src/Http/Http.Results/test/ConflictResultTest.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.AspNetCore.Http.Result -{ - public class ConflictResultTest - { - [Fact] - public void ConflictResult_InitializesStatusCode() - { - // Arrange & act - var conflictResult = new ConflictResult(); - - // Assert - Assert.Equal(StatusCodes.Status409Conflict, conflictResult.StatusCode); - } - } -} diff --git a/src/Http/Http.Results/test/NotFoundResultTests.cs b/src/Http/Http.Results/test/NotFoundResultTests.cs deleted file mode 100644 index ffa21c67a33b..000000000000 --- a/src/Http/Http.Results/test/NotFoundResultTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.AspNetCore.Http.Result -{ - public class NotFoundResultTests - { - [Fact] - public void NotFoundResult_InitializesStatusCode() - { - // Arrange & act - var notFound = new NotFoundResult(); - - // Assert - Assert.Equal(StatusCodes.Status404NotFound, notFound.StatusCode); - } - } -} diff --git a/src/Http/Http.Results/test/ObjectResultTests.cs b/src/Http/Http.Results/test/ObjectResultTests.cs index a78a47356d82..c82b5780cccf 100644 --- a/src/Http/Http.Results/test/ObjectResultTests.cs +++ b/src/Http/Http.Results/test/ObjectResultTests.cs @@ -1,11 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.IO; using System.Text; using System.Text.Json; -using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; @@ -17,6 +14,24 @@ namespace Microsoft.AspNetCore.Http.Result { public class ObjectResultTests { + [Fact] + public async Task ObjectResult_ExecuteAsync_WithNullValue_Works() + { + // Arrange + var result = new ObjectResult(value: null, 411); + + var httpContext = new DefaultHttpContext() + { + RequestServices = CreateServices(), + }; + + // Act + await result.ExecuteAsync(httpContext); + + // Assert + Assert.Equal(411, httpContext.Response.StatusCode); + } + [Fact] public async Task ObjectResult_ExecuteAsync_SetsStatusCode() { diff --git a/src/Http/Http.Results/test/OkResultTest.cs b/src/Http/Http.Results/test/OkResultTest.cs deleted file mode 100644 index a32ca95201e0..000000000000 --- a/src/Http/Http.Results/test/OkResultTest.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using Xunit; - -namespace Microsoft.AspNetCore.Http.Result -{ - public class OkResultTest - { - [Fact] - public async Task HttpOkResult_SetsStatusCode() - { - // Arrange - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices().BuildServiceProvider(); - - var result = new OkResult(); - - // Act - await result.ExecuteAsync(httpContext); - - // Assert - Assert.Equal(StatusCodes.Status200OK, httpContext.Response.StatusCode); - } - - private static IServiceCollection CreateServices() - { - var services = new ServiceCollection(); - services.AddSingleton(NullLoggerFactory.Instance); - return services; - } - } -} diff --git a/src/Http/Http.Results/test/RedirectResultTest.cs b/src/Http/Http.Results/test/RedirectResultTest.cs index 005407107c5c..907d32e53d0c 100644 --- a/src/Http/Http.Results/test/RedirectResultTest.cs +++ b/src/Http/Http.Results/test/RedirectResultTest.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Threading.Tasks; using Microsoft.AspNetCore.Internal; using Xunit; @@ -9,36 +8,6 @@ namespace Microsoft.AspNetCore.Http.Result { public class RedirectResultTest : RedirectResultTestBase { - [Fact] - public void RedirectResult_Constructor_WithParameterUrl_SetsResultUrlAndNotPermanentOrPreserveMethod() - { - // Arrange - var url = "/test/url"; - - // Act - var result = new RedirectResult(url); - - // Assert - Assert.False(result.PreserveMethod); - Assert.False(result.Permanent); - Assert.Same(url, result.Url); - } - - [Fact] - public void RedirectResult_Constructor_WithParameterUrlAndPermanent_SetsResultUrlAndPermanentNotPreserveMethod() - { - // Arrange - var url = "/test/url"; - - // Act - var result = new RedirectResult(url, permanent: true); - - // Assert - Assert.False(result.PreserveMethod); - Assert.True(result.Permanent); - Assert.Same(url, result.Url); - } - [Fact] public void RedirectResult_Constructor_WithParameterUrlPermanentAndPreservesMethod_SetsResultUrlPermanentAndPreservesMethod() { @@ -56,7 +25,7 @@ public void RedirectResult_Constructor_WithParameterUrlPermanentAndPreservesMeth protected override Task ExecuteAsync(HttpContext httpContext, string contentPath) { - var redirectResult = new RedirectResult(contentPath); + var redirectResult = new RedirectResult(contentPath, false, false); return redirectResult.ExecuteAsync(httpContext); } } diff --git a/src/Http/Http.Results/test/UnprocessableEntityResultTests.cs b/src/Http/Http.Results/test/UnprocessableEntityResultTests.cs deleted file mode 100644 index 07ec867abea2..000000000000 --- a/src/Http/Http.Results/test/UnprocessableEntityResultTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.AspNetCore.Http.Result -{ - public class UnprocessableEntityResultTests - { - [Fact] - public void UnprocessableEntityResult_InitializesStatusCode() - { - // Arrange & act - var result = new UnprocessableEntityResult(); - - // Assert - Assert.Equal(StatusCodes.Status422UnprocessableEntity, result.StatusCode); - } - } -} diff --git a/src/Mvc/test/WebSites/SimpleWebSiteWithWebApplicationBuilder/Program.cs b/src/Mvc/test/WebSites/SimpleWebSiteWithWebApplicationBuilder/Program.cs index e185a78c7db9..1faeb5b91e90 100644 --- a/src/Mvc/test/WebSites/SimpleWebSiteWithWebApplicationBuilder/Program.cs +++ b/src/Mvc/test/WebSites/SimpleWebSiteWithWebApplicationBuilder/Program.cs @@ -21,7 +21,7 @@ return NotFound(); } - return RedirectPermanent("/json"); + return Redirect("/json", permanent: true); }); app.Run(); diff --git a/src/Shared/ResultsHelpers/FileResultHelper.cs b/src/Shared/ResultsHelpers/FileResultHelper.cs index fb44351d4359..c0c2296c6507 100644 --- a/src/Shared/ResultsHelpers/FileResultHelper.cs +++ b/src/Shared/ResultsHelpers/FileResultHelper.cs @@ -88,7 +88,6 @@ internal static (RangeItemHeaderValue? range, long rangeLength, bool serveBody) return (range: null, rangeLength: 0, serveBody: false); } - response.ContentType = result.ContentType; SetContentDispositionHeader(httpContext, in result); diff --git a/src/Shared/ResultsTests/FileStreamResultTestBase.cs b/src/Shared/ResultsTests/FileStreamResultTestBase.cs index f69c5d217346..551782b12a5c 100644 --- a/src/Shared/ResultsTests/FileStreamResultTestBase.cs +++ b/src/Shared/ResultsTests/FileStreamResultTestBase.cs @@ -1,11 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.IO; -using System.Linq; using System.Text; -using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -389,7 +385,7 @@ public async Task WriteFileAsync_CopiesProvidedStream_ToOutputStream() httpContext.Response.Body = outStream; // Act - await ExecuteAsync(httpContext, originalStream, "text/plian"); + await ExecuteAsync(httpContext, originalStream, "text/plain"); // Assert var outBytes = outStream.ToArray();