-
Notifications
You must be signed in to change notification settings - Fork 10.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate IResult based results from ActionResults (#33843)
* Separate IResult based results from ActionResults Fixes #33729
- Loading branch information
Showing
126 changed files
with
7,369 additions
and
3,144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// 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; | ||
|
||
namespace Microsoft.AspNetCore.Http.Result | ||
{ | ||
internal sealed class AcceptedAtRouteResult : ObjectResult | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AcceptedAtRouteResult"/> 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) | ||
: this(routeName: null, routeValues: routeValues, value: value) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AcceptedAtRouteResult"/> 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( | ||
string? routeName, | ||
object? routeValues, | ||
object? value) | ||
: base(value, StatusCodes.Status202Accepted) | ||
{ | ||
RouteName = routeName; | ||
RouteValues = new RouteValueDictionary(routeValues); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the name of the route to use for generating the URL. | ||
/// </summary> | ||
public string? RouteName { get; } | ||
|
||
/// <summary> | ||
/// Gets the route data to use for generating the URL. | ||
/// </summary> | ||
public RouteValueDictionary RouteValues { get; } | ||
|
||
/// <inheritdoc /> | ||
protected override void OnFormatting(HttpContext context) | ||
{ | ||
var linkGenerator = context.RequestServices.GetRequiredService<LinkGenerator>(); | ||
var url = linkGenerator.GetUriByAddress( | ||
context, | ||
RouteName, | ||
RouteValues, | ||
fragment: FragmentString.Empty); | ||
|
||
if (string.IsNullOrEmpty(url)) | ||
{ | ||
throw new InvalidOperationException("No route matches the supplied values."); | ||
} | ||
|
||
context.Response.Headers.Location = url; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// 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; | ||
|
||
namespace Microsoft.AspNetCore.Http.Result | ||
{ | ||
internal sealed class AcceptedResult : ObjectResult | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AcceptedResult"/> class with the values | ||
/// provided. | ||
/// </summary> | ||
public AcceptedResult() | ||
: base(value: null, StatusCodes.Status202Accepted) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AcceptedResult"/> 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> | ||
public AcceptedResult(string? location, object? value) | ||
: base(value, StatusCodes.Status202Accepted) | ||
{ | ||
Location = location; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AcceptedResult"/> 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> | ||
public AcceptedResult(Uri locationUri, object? value) | ||
: base(value, StatusCodes.Status202Accepted) | ||
{ | ||
if (locationUri == null) | ||
{ | ||
throw new ArgumentNullException(nameof(locationUri)); | ||
} | ||
|
||
if (locationUri.IsAbsoluteUri) | ||
{ | ||
Location = locationUri.AbsoluteUri; | ||
} | ||
else | ||
{ | ||
Location = locationUri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the location at which the status of the requested content can be monitored. | ||
/// </summary> | ||
public string? Location { get; set; } | ||
|
||
/// <inheritdoc /> | ||
protected override void OnFormatting(HttpContext context) | ||
{ | ||
if (context == null) | ||
{ | ||
throw new ArgumentNullException(nameof(context)); | ||
} | ||
|
||
if (!string.IsNullOrEmpty(Location)) | ||
{ | ||
context.Response.Headers.Location = Location; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// 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 BadRequestObjectResult : ObjectResult | ||
{ | ||
public BadRequestObjectResult(object? error) | ||
: base(error, StatusCodes.Status400BadRequest) | ||
{ | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +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. | ||
|
||
namespace Microsoft.AspNetCore.Http.Result | ||
{ | ||
internal sealed class BadRequestResult : StatusCodeResult | ||
{ | ||
public BadRequestResult() : base(StatusCodes.Status400BadRequest) | ||
{ | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// 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.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.AspNetCore.Http.Result | ||
{ | ||
/// <summary> | ||
/// An <see cref="IResult"/> that on execution invokes <see cref="M:HttpContext.ChallengeAsync"/>. | ||
/// </summary> | ||
internal sealed partial class ChallengeResult : IResult | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of <see cref="ChallengeResult"/>. | ||
/// </summary> | ||
public ChallengeResult() | ||
: this(Array.Empty<string>()) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of <see cref="ChallengeResult"/> with the | ||
/// specified authentication scheme. | ||
/// </summary> | ||
/// <param name="authenticationScheme">The authentication scheme to challenge.</param> | ||
public ChallengeResult(string authenticationScheme) | ||
: this(new[] { authenticationScheme }) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of <see cref="ChallengeResult"/> with the | ||
/// specified authentication schemes. | ||
/// </summary> | ||
/// <param name="authenticationSchemes">The authentication schemes to challenge.</param> | ||
public ChallengeResult(IList<string> authenticationSchemes) | ||
: this(authenticationSchemes, properties: null) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of <see cref="ChallengeResult"/> with the | ||
/// specified <paramref name="properties"/>. | ||
/// </summary> | ||
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication | ||
/// challenge.</param> | ||
public ChallengeResult(AuthenticationProperties? properties) | ||
: this(Array.Empty<string>(), properties) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of <see cref="ChallengeResult"/> with the | ||
/// specified authentication scheme and <paramref name="properties"/>. | ||
/// </summary> | ||
/// <param name="authenticationScheme">The authentication schemes to challenge.</param> | ||
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication | ||
/// challenge.</param> | ||
public ChallengeResult(string authenticationScheme, AuthenticationProperties? properties) | ||
: this(new[] { authenticationScheme }, properties) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of <see cref="ChallengeResult"/> with the | ||
/// specified authentication schemes and <paramref name="properties"/>. | ||
/// </summary> | ||
/// <param name="authenticationSchemes">The authentication scheme to challenge.</param> | ||
/// <param name="properties"><see cref="AuthenticationProperties"/> used to perform the authentication | ||
/// challenge.</param> | ||
public ChallengeResult(IList<string> authenticationSchemes, AuthenticationProperties? properties) | ||
{ | ||
AuthenticationSchemes = authenticationSchemes; | ||
Properties = properties; | ||
} | ||
|
||
public IList<string> AuthenticationSchemes { get; init; } = Array.Empty<string>(); | ||
|
||
public AuthenticationProperties? Properties { get; init; } | ||
|
||
public async Task ExecuteAsync(HttpContext httpContext) | ||
{ | ||
var logger = httpContext.RequestServices.GetRequiredService<ILogger<ChallengeResult>>(); | ||
|
||
Log.ChallengeResultExecuting(logger, AuthenticationSchemes); | ||
|
||
if (AuthenticationSchemes != null && AuthenticationSchemes.Count > 0) | ||
{ | ||
foreach (var scheme in AuthenticationSchemes) | ||
{ | ||
await httpContext.ChallengeAsync(scheme, Properties); | ||
} | ||
} | ||
else | ||
{ | ||
await httpContext.ChallengeAsync(Properties); | ||
} | ||
} | ||
|
||
private static partial class Log | ||
{ | ||
public static void ChallengeResultExecuting(ILogger logger, IList<string> authenticationSchemes) | ||
{ | ||
if (logger.IsEnabled(LogLevel.Information)) | ||
{ | ||
ChallengeResultExecuting(logger, authenticationSchemes.ToArray()); | ||
} | ||
} | ||
|
||
[LoggerMessage(1, LogLevel.Information, "Executing ChallengeResult with authentication schemes ({Schemes}).", EventName = "ChallengeResultExecuting", SkipEnabledCheck = true)] | ||
private static partial void ChallengeResultExecuting(ILogger logger, string[] schemes); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// 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 ConflictObjectResult : ObjectResult | ||
{ | ||
public ConflictObjectResult(object? error) : | ||
base(error, StatusCodes.Status409Conflict) | ||
{ | ||
} | ||
} | ||
} |
Oops, something went wrong.