Skip to content

Cleanup Results helper #34296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Http/Http.Extensions/src/ResponseHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public DateTimeOffset? Expires
}

/// <summary>
/// Gets or sets the <c>Last=Modified</c> header for an HTTP response.
/// Gets or sets the <c>Last-Modified</c> header for an HTTP response.
/// </summary>
public DateTimeOffset? LastModified
{
Expand Down
3 changes: 1 addition & 2 deletions src/Http/Http.Results/src/AcceptedAtRouteResult.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -48,7 +47,7 @@ public AcceptedAtRouteResult(
public RouteValueDictionary RouteValues { get; }

/// <inheritdoc />
protected override void OnFormatting(HttpContext context)
protected override void ConfigureResponseHeaders(HttpContext context)
{
var linkGenerator = context.RequestServices.GetRequiredService<LinkGenerator>();
var url = linkGenerator.GetUriByAddress(
Expand Down
7 changes: 1 addition & 6 deletions src/Http/Http.Results/src/AcceptedResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,8 @@ public AcceptedResult(Uri locationUri, object? value)
public string? Location { get; set; }

/// <inheritdoc />
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;
Expand Down
12 changes: 0 additions & 12 deletions src/Http/Http.Results/src/BadRequestResult.cs

This file was deleted.

12 changes: 0 additions & 12 deletions src/Http/Http.Results/src/ConflictResult.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Http/Http.Results/src/CreatedAtRouteResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public CreatedAtRouteResult(
public RouteValueDictionary? RouteValues { get; set; }

/// <inheritdoc />
protected override void OnFormatting(HttpContext context)
protected override void ConfigureResponseHeaders(HttpContext context)
{
var linkGenerator = context.RequestServices.GetRequiredService<LinkGenerator>();
var url = linkGenerator.GetUriByRouteValues(
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Http.Results/src/CreatedResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public CreatedResult(Uri location, object? value)
public string Location { get; init; }

/// <inheritdoc />
protected override void OnFormatting(HttpContext context)
protected override void ConfigureResponseHeaders(HttpContext context)
{
context.Response.Headers.Location = Location;
}
Expand Down
4 changes: 1 addition & 3 deletions src/Http/Http.Results/src/FileContentResult.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -18,7 +16,7 @@ internal sealed partial class FileContentResult : FileResult, IResult
/// </summary>
/// <param name="fileContents">The bytes that represent the file contents.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public FileContentResult(byte[] fileContents, string contentType)
public FileContentResult(byte[] fileContents, string? contentType)
: base(contentType)
{
FileContents = fileContents;
Expand Down
10 changes: 2 additions & 8 deletions src/Http/Http.Results/src/FileResult.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -17,14 +16,9 @@ internal abstract partial class FileResult
/// the provided <paramref name="contentType"/>.
/// </summary>
/// <param name="contentType">The Content-Type header of the response.</param>
protected FileResult(string contentType)
protected FileResult(string? contentType)
{
if (contentType == null)
{
throw new ArgumentNullException(nameof(contentType));
}

ContentType = contentType;
ContentType = contentType ?? "application/octet-stream";
}

/// <summary>
Expand Down
36 changes: 7 additions & 29 deletions src/Http/Http.Results/src/FileStreamResult.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -24,26 +20,8 @@ internal sealed class FileStreamResult : FileResult, IResult
/// </summary>
/// <param name="fileStream">The stream with the file.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public FileStreamResult(Stream fileStream, string contentType)
: this(fileStream, MediaTypeHeaderValue.Parse(contentType))
{
if (fileStream == null)
{
throw new ArgumentNullException(nameof(fileStream));
}

FileStream = fileStream;
}

/// <summary>
/// Creates a new <see cref="FileStreamResult"/> instance with
/// the provided <paramref name="fileStream"/> and the
/// provided <paramref name="contentType"/>.
/// </summary>
/// <param name="fileStream">The stream with the file.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public FileStreamResult(Stream fileStream, MediaTypeHeaderValue contentType)
: base(contentType.ToString())
public FileStreamResult(Stream fileStream, string? contentType)
: base(contentType)
{
if (fileStream == null)
{
Expand All @@ -58,10 +36,10 @@ public FileStreamResult(Stream fileStream, MediaTypeHeaderValue contentType)
/// </summary>
public Stream FileStream { get; }

public Task ExecuteAsync(HttpContext httpContext)
public async Task ExecuteAsync(HttpContext httpContext)
{
var logger = httpContext.RequestServices.GetRequiredService<ILogger<FileStreamResult>>();
using (FileStream)
await using (FileStream)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah hah! That was the bug!

{
Log.ExecutingFileResult(logger, this);

Expand Down Expand Up @@ -90,20 +68,20 @@ public Task ExecuteAsync(HttpContext httpContext)

if (!serveBody)
{
return Task.CompletedTask;
return;
}

if (range != null && rangeLength == 0)
{
return Task.CompletedTask;
return;
}

if (range != null)
{
FileResultHelper.Log.WritingRangeToBody(logger);
}

return FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength);
await FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength);
}
}
}
Expand Down
12 changes: 0 additions & 12 deletions src/Http/Http.Results/src/NotFoundResult.cs

This file was deleted.

42 changes: 31 additions & 11 deletions src/Http/Http.Results/src/ObjectResult.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -42,7 +41,7 @@ public Task ExecuteAsync(HttpContext httpContext)
{
var loggerFactory = httpContext.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger(GetType());
Log.ObjectResultExecuting(logger, Value);
Log.ObjectResultExecuting(logger, Value, StatusCode);

if (Value is ProblemDetails problemDetails)
{
Expand All @@ -54,10 +53,25 @@ public Task ExecuteAsync(HttpContext httpContext)
httpContext.Response.StatusCode = statusCode;
}

ConfigureResponseHeaders(httpContext);

if (Value is null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this go earlier?

{
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.
Expand Down Expand Up @@ -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);
}
}
}
12 changes: 0 additions & 12 deletions src/Http/Http.Results/src/OkResult.cs

This file was deleted.

5 changes: 1 addition & 4 deletions src/Http/Http.Results/src/PhysicalFileResult.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -22,7 +19,7 @@ internal sealed partial class PhysicalFileResult : FileResult, IResult
/// </summary>
/// <param name="fileName">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public PhysicalFileResult(string fileName, string contentType)
public PhysicalFileResult(string fileName, string? contentType)
: base(contentType)
{
FileName = fileName;
Expand Down
Loading