Skip to content

Make IResults types public #40704

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 30 commits into from
Mar 20, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0ab4de9
StatuCodeResult as base class
brunolins16 Mar 9, 2022
813786e
StatuCodeResult as base class
brunolins16 Mar 9, 2022
811c604
Making types public and renaming to HTTPResult
brunolins16 Mar 10, 2022
5d66c24
Update comments
brunolins16 Mar 11, 2022
acf0a3b
Make setters internal
brunolins16 Mar 11, 2022
9ddf586
Updating public API file
brunolins16 Mar 11, 2022
9a79b02
Removing base classes
brunolins16 Mar 14, 2022
a1fef75
Changing method name to WriteResultAsStatusCode
brunolins16 Mar 14, 2022
1ee3138
Updating API
brunolins16 Mar 14, 2022
2c029a8
code cleanup
brunolins16 Mar 14, 2022
4103a0f
fixing public api
brunolins16 Mar 15, 2022
5fdebc4
Simplyfing interfaces
brunolins16 Mar 15, 2022
6146e4a
Removing interfaces + Adding ctors
brunolins16 Mar 18, 2022
7d89ce3
Fixing xml docs
brunolins16 Mar 18, 2022
6171f15
Making EmptyResult public
brunolins16 Mar 18, 2022
6a807cf
Updating JsonHttpResult
brunolins16 Mar 18, 2022
5fa233d
Adding missing ctor
brunolins16 Mar 18, 2022
dcf745b
Adding missing ctor
brunolins16 Mar 18, 2022
3d01bb6
Adding missing ctor
brunolins16 Mar 18, 2022
e05b04f
Adding misssed xml comment
brunolins16 Mar 18, 2022
9c628aa
Removing configureResponseHeader
brunolins16 Mar 18, 2022
eada9b4
PR Feedback
brunolins16 Mar 18, 2022
ff3cb76
Moving ctors to internal
brunolins16 Mar 18, 2022
00877b5
Create logger using string category
brunolins16 Mar 18, 2022
825f4c0
Adding more unittests
brunolins16 Mar 18, 2022
73800b9
Update src/Http/Http.Results/src/EmptyHttpResult.cs
brunolins16 Mar 18, 2022
8fb15dd
Update ContentHttpResult.cs
brunolins16 Mar 18, 2022
dac8711
avoid closure allocation
brunolins16 Mar 18, 2022
4a50104
Merge branch 'brunolins16/iresult-apisuggestion' of https://github.co…
brunolins16 Mar 18, 2022
1d76b6e
unit loggerfactory
brunolins16 Mar 19, 2022
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
16 changes: 16 additions & 0 deletions src/Http/Http.Abstractions/src/IAtLocationHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.Http;

/// <summary>
/// Defines a contract that represents the result of an HTTP result endpoint
/// that constains an <see cref="Location"/>.
/// </summary>
public interface IAtLocationHttpResult : IResult
{
/// <summary>
/// Gets the location at which the status of the requested content can be monitored.
/// </summary>
string? Location { get; }
}
23 changes: 23 additions & 0 deletions src/Http/Http.Abstractions/src/IAtRouteHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.AspNetCore.Routing;

namespace Microsoft.AspNetCore.Http;

/// <summary>
/// Defines a contract that represents the result of an HTTP result endpoint
/// that constains an object route.
/// </summary>
public interface IAtRouteHttpResult : IResult
{
/// <summary>
/// Gets the name of the route to use for generating the URL.
/// </summary>
string? RouteName { get; }

/// <summary>
/// Gets the route data to use for generating the URL.
/// </summary>
RouteValueDictionary? RouteValues { get; }
}
42 changes: 42 additions & 0 deletions src/Http/Http.Abstractions/src/IFileHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Http;

/// <summary>
/// Defines a contract that represents the file result of an HTTP result endpoint.
/// </summary>
public interface IFileHttpResult : IResult
{
/// <summary>
/// Gets the Content-Type header for the response.
/// </summary>
string ContentType { get; }

/// <summary>
/// Gets the file name that will be used in the Content-Disposition header of the response.
/// </summary>
string? FileDownloadName { get; }

/// <summary>
/// Gets or sets the last modified information associated with the <see cref="IFileHttpResult"/>.
/// </summary>
DateTimeOffset? LastModified { get; }

/// <summary>
/// Gets or sets the etag associated with the <see cref="IFileHttpResult"/>.
/// </summary>
EntityTagHeaderValue? EntityTag { get; }

/// <summary>
/// Gets or sets the value that enables range processing for the <see cref="IFileHttpResult"/>.
/// </summary>
bool EnableRangeProcessing { get; }

/// <summary>
/// Gets or sets the file length information associated with the <see cref="IFileHttpResult"/>.
/// </summary>
long? FileLength { get; }
}
16 changes: 16 additions & 0 deletions src/Http/Http.Abstractions/src/IObjectHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.Http;

/// <summary>
/// Defines a contract that represents the result of an HTTP endpoint
/// that contains an object <see cref="Value"/> and a given statu code.
/// </summary>
public interface IObjectHttpResult : IResult, IStatusCodeHttpResult
{
/// <summary>
/// Gets or sets the object result.
/// </summary>
object? Value { get; }
}
30 changes: 30 additions & 0 deletions src/Http/Http.Abstractions/src/IRedirectHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.Http;

/// <summary>
/// Defines a contract that represents the HTTP Redirect result of an HTTP result endpoint.
/// </summary>
public interface IRedirectHttpResult : IResult
{
/// <summary>
/// Gets the value that specifies that the redirect should be permanent if true or temporary if false.
/// </summary>
bool Permanent { get; }

/// <summary>
/// Gets an indication that the redirect preserves the initial request method.
/// </summary>
bool PreserveMethod { get; }

/// <summary>
/// Gets the URL to redirect to.
/// </summary>
string? Url { get; }

/// <summary>
/// Gets an indication that only local URLs are accepted.
/// </summary>
bool AcceptLocalUrlOnly { get; }
}
16 changes: 16 additions & 0 deletions src/Http/Http.Abstractions/src/IStatusCodeHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.Http;

/// <summary>
/// Defines a contract that represents the result of an HTTP endpoint
/// that contains a <see cref="StatusCode"/>.
/// </summary>
public interface IStatusCodeHttpResult : IResult
{
/// <summary>
/// Gets or sets the HTTP status code.
/// </summary>
int? StatusCode { get; }
}
21 changes: 21 additions & 0 deletions src/Http/Http.Abstractions/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
#nullable enable
*REMOVED*abstract Microsoft.AspNetCore.Http.HttpResponse.ContentType.get -> string!
Microsoft.AspNetCore.Http.EndpointMetadataCollection.GetRequiredMetadata<T>() -> T!
Microsoft.AspNetCore.Http.IAtLocationHttpResult
Microsoft.AspNetCore.Http.IAtLocationHttpResult.Location.get -> string?
Microsoft.AspNetCore.Http.IAtRouteHttpResult
Microsoft.AspNetCore.Http.IAtRouteHttpResult.RouteName.get -> string?
Microsoft.AspNetCore.Http.IAtRouteHttpResult.RouteValues.get -> Microsoft.AspNetCore.Routing.RouteValueDictionary?
Microsoft.AspNetCore.Http.IFileHttpResult
Microsoft.AspNetCore.Http.IFileHttpResult.ContentType.get -> string!
Microsoft.AspNetCore.Http.IFileHttpResult.EnableRangeProcessing.get -> bool
Microsoft.AspNetCore.Http.IFileHttpResult.EntityTag.get -> Microsoft.Net.Http.Headers.EntityTagHeaderValue?
Microsoft.AspNetCore.Http.IFileHttpResult.FileDownloadName.get -> string?
Microsoft.AspNetCore.Http.IFileHttpResult.FileLength.get -> long?
Microsoft.AspNetCore.Http.IFileHttpResult.LastModified.get -> System.DateTimeOffset?
Microsoft.AspNetCore.Http.IObjectHttpResult
Microsoft.AspNetCore.Http.IObjectHttpResult.Value.get -> object?
Microsoft.AspNetCore.Http.IRedirectHttpResult
Microsoft.AspNetCore.Http.IRedirectHttpResult.AcceptLocalUrlOnly.get -> bool
Microsoft.AspNetCore.Http.IRedirectHttpResult.Permanent.get -> bool
Microsoft.AspNetCore.Http.IRedirectHttpResult.PreserveMethod.get -> bool
Microsoft.AspNetCore.Http.IRedirectHttpResult.Url.get -> string?
Microsoft.AspNetCore.Http.IStatusCodeHttpResult
Microsoft.AspNetCore.Http.IStatusCodeHttpResult.StatusCode.get -> int?
Microsoft.AspNetCore.Http.RouteHandlerFilterContext.RouteHandlerFilterContext(Microsoft.AspNetCore.Http.HttpContext! httpContext, params object![]! parameters) -> void
Microsoft.AspNetCore.Http.IRouteHandlerFilter.InvokeAsync(Microsoft.AspNetCore.Http.RouteHandlerFilterContext! context, System.Func<Microsoft.AspNetCore.Http.RouteHandlerFilterContext!, System.Threading.Tasks.ValueTask<object?>>! next) -> System.Threading.Tasks.ValueTask<object?>
Microsoft.AspNetCore.Http.Metadata.IFromFormMetadata
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,67 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.Http;

using System.Threading.Tasks;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.AspNetCore.Http.Result;

internal sealed class AcceptedAtRouteResult : ObjectResult
/// <summary>
/// An <see cref="IResult"/> that on execution will write an object to the response
/// with status code Accepted (202) and Location header.
/// Targets a registered route.
/// </summary>
public sealed class AcceptedAtRouteHttpResult : IResult, IObjectHttpResult, IAtRouteHttpResult, IStatusCodeHttpResult
{
/// <summary>
/// Initializes a new instance of the <see cref="AcceptedAtRouteResult"/> class with the values
/// Initializes a new instance of the <see cref="AcceptedAtRouteHttpResult"/> class with the values
/// provided.
/// </summary>
/// <param name="routeValues">The route data to use for generating the URL.</param>
/// <param name="value">The value to format in the entity body.</param>
public AcceptedAtRouteResult(object? routeValues, object? value)
internal AcceptedAtRouteHttpResult(object? routeValues, object? value)
: this(routeName: null, routeValues: routeValues, value: value)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="AcceptedAtRouteResult"/> class with the values
/// Initializes a new instance of the <see cref="AcceptedAtRouteHttpResult"/> class with the values
/// provided.
/// </summary>
/// <param name="routeName">The name of the route to use for generating the URL.</param>
/// <param name="routeValues">The route data to use for generating the URL.</param>
/// <param name="value">The value to format in the entity body.</param>
public AcceptedAtRouteResult(
internal AcceptedAtRouteHttpResult(
string? routeName,
object? routeValues,
object? value)
: base(value, StatusCodes.Status202Accepted)
{
Value = value;
RouteName = routeName;
RouteValues = new RouteValueDictionary(routeValues);
}

/// <summary>
/// Gets the name of the route to use for generating the URL.
/// </summary>
/// <inheritdoc/>
public object? Value { get; }

/// <inheritdoc/>
public string? RouteName { get; }

/// <summary>
/// Gets the route data to use for generating the URL.
/// </summary>
public RouteValueDictionary RouteValues { get; }
/// <inheritdoc/>
public RouteValueDictionary? RouteValues { get; }

/// <inheritdoc/>
public int? StatusCode => StatusCodes.Status202Accepted;

/// <inheritdoc/>
public Task ExecuteAsync(HttpContext httpContext)
=> HttpResultsWriter.WriteResultAsJson(httpContext, objectHttpResult: this, configureResponseHeader: ConfigureResponseHeaders);

/// <inheritdoc />
protected override void ConfigureResponseHeaders(HttpContext context)
private void ConfigureResponseHeaders(HttpContext context)
{
var linkGenerator = context.RequestServices.GetRequiredService<LinkGenerator>();
var url = linkGenerator.GetUriByAddress(
var url = linkGenerator.GetUriByRouteValues(
context,
RouteName,
RouteValues,
Expand Down
80 changes: 80 additions & 0 deletions src/Http/Http.Results/src/AcceptedHttpResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.AspNetCore.Http;

using System.Threading.Tasks;

/// <summary>
/// An <see cref="IResult"/> that on execution will write an object to the response
/// with status code Accepted (202) and Location header.
/// Targets a registered route.
/// </summary>
public sealed class AcceptedHttpResult : IResult, IObjectHttpResult, IStatusCodeHttpResult, IAtLocationHttpResult
{
/// <summary>
/// Initializes a new instance of the <see cref="AcceptedHttpResult"/> class with the values
/// provided.
/// </summary>
internal AcceptedHttpResult()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="AcceptedHttpResult"/> class with the values
/// provided.
/// </summary>
/// <param name="location">The location at which the status of requested content can be monitored.</param>
/// <param name="value">The value to format in the entity body.</param>
internal AcceptedHttpResult(string? location, object? value)
{
Value = value;
Location = location;
}

/// <summary>
/// Initializes a new instance of the <see cref="AcceptedHttpResult"/> class with the values
/// provided.
/// </summary>
/// <param name="locationUri">The location at which the status of requested content can be monitored.</param>
/// <param name="value">The value to format in the entity body.</param>
internal AcceptedHttpResult(Uri locationUri, object? value)
{
Value = value;

if (locationUri == null)
{
throw new ArgumentNullException(nameof(locationUri));
}

if (locationUri.IsAbsoluteUri)
{
Location = locationUri.AbsoluteUri;
}
else
{
Location = locationUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
}
}

/// <inheritdoc/>
public object? Value { get; }

/// <inheritdoc/>
public int? StatusCode => StatusCodes.Status202Accepted;

/// <inheritdoc/>
public string? Location { get; }

/// <inheritdoc/>
public Task ExecuteAsync(HttpContext httpContext)
=> HttpResultsWriter.WriteResultAsJson(httpContext, objectHttpResult: this, configureResponseHeader: ConfigureResponseHeaders);

private void ConfigureResponseHeaders(HttpContext context)
{
if (!string.IsNullOrEmpty(Location))
{
context.Response.Headers.Location = Location;
}
}
}
Loading