();
+ Assert.Equal("Hello Abc .", app.FindElement(By.Id("test-info")).Text);
+ Assert.Equal("0", app.FindElement(By.Id("value-QueryInt")).Text);
+ Assert.Equal(dateTime.ToString("hh:mm:ss on yyyy-MM-dd"), app.FindElement(By.Id("value-NullableDateTimeValue")).Text);
+ Assert.Equal(dateOnly.ToString("yyyy-MM-dd"), app.FindElement(By.Id("value-NullableDateOnlyValue")).Text);
+ Assert.Equal(timeOnly.ToString("hh:mm:ss"), app.FindElement(By.Id("value-NullableTimeOnlyValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-StringValue")).Text);
+ Assert.Equal("0 values ()", app.FindElement(By.Id("value-LongValues")).Text);
+
+ AssertHighlightedLinks("With query parameters (none)", "With query parameters (passing Date Time values)");
+ }
+
[Fact]
public void CanNavigateToQueryStringPageWithNoQuery()
{
@@ -809,6 +830,8 @@ public void CanNavigateToQueryStringPageWithNoQuery()
Assert.Equal("Hello Abc .", app.FindElement(By.Id("test-info")).Text);
Assert.Equal("0", app.FindElement(By.Id("value-QueryInt")).Text);
Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateTimeValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateOnlyValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableTimeOnlyValue")).Text);
Assert.Equal(string.Empty, app.FindElement(By.Id("value-StringValue")).Text);
Assert.Equal("0 values ()", app.FindElement(By.Id("value-LongValues")).Text);
@@ -827,6 +850,8 @@ public void CanNavigateBetweenPagesWithQueryStrings()
Browser.Equal("Hello Abc .", () => app.FindElement(By.Id("test-info")).Text);
Assert.Equal("0", app.FindElement(By.Id("value-QueryInt")).Text);
Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateTimeValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateOnlyValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableTimeOnlyValue")).Text);
Assert.Equal("Hello there", app.FindElement(By.Id("value-StringValue")).Text);
Assert.Equal("0 values ()", app.FindElement(By.Id("value-LongValues")).Text);
var instanceId = app.FindElement(By.Id("instance-id")).Text;
@@ -838,6 +863,8 @@ public void CanNavigateBetweenPagesWithQueryStrings()
app.FindElement(By.LinkText("With IntValue and LongValues")).Click();
Browser.Equal("123", () => app.FindElement(By.Id("value-QueryInt")).Text);
Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateTimeValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateOnlyValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableTimeOnlyValue")).Text);
Assert.Equal(string.Empty, app.FindElement(By.Id("value-StringValue")).Text);
Assert.Equal("3 values (50, 100, -20)", app.FindElement(By.Id("value-LongValues")).Text);
Assert.Equal(instanceId, app.FindElement(By.Id("instance-id")).Text);
@@ -847,6 +874,8 @@ public void CanNavigateBetweenPagesWithQueryStrings()
Browser.Navigate().Back();
Browser.Equal("0", () => app.FindElement(By.Id("value-QueryInt")).Text);
Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateTimeValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableDateOnlyValue")).Text);
+ Assert.Equal(string.Empty, app.FindElement(By.Id("value-NullableTimeOnlyValue")).Text);
Assert.Equal("Hello there", app.FindElement(By.Id("value-StringValue")).Text);
Assert.Equal("0 values ()", app.FindElement(By.Id("value-LongValues")).Text);
Assert.Equal(instanceId, app.FindElement(By.Id("instance-id")).Text);
diff --git a/src/Components/test/testassets/BasicTestApp/RouterTest/Links.razor b/src/Components/test/testassets/BasicTestApp/RouterTest/Links.razor
index ed381f72f8f2..67d6bb8a2474 100644
--- a/src/Components/test/testassets/BasicTestApp/RouterTest/Links.razor
+++ b/src/Components/test/testassets/BasicTestApp/RouterTest/Links.razor
@@ -20,6 +20,7 @@
With more parameters
With query parameters (none)
With query parameters (passing string value)
+ With query parameters (passing Date Time values)
Long page 1
Long page 2
With lazy assembly
diff --git a/src/Components/test/testassets/BasicTestApp/RouterTest/WithQueryParameters.razor b/src/Components/test/testassets/BasicTestApp/RouterTest/WithQueryParameters.razor
index 36e3fd058634..46a19b816bcc 100644
--- a/src/Components/test/testassets/BasicTestApp/RouterTest/WithQueryParameters.razor
+++ b/src/Components/test/testassets/BasicTestApp/RouterTest/WithQueryParameters.razor
@@ -2,6 +2,8 @@
Hello @FirstName @OptionalLastName.
IntValue: @IntValue
NullableDateTimeValue: @NullableDateTimeValue?.ToString("hh:mm:ss on yyyy-MM-dd")
+NullableDateOnlyValue: @NullableDateOnlyValue?.ToString("yyyy-MM-dd")
+NullableTimeOnlyValue: @NullableTimeOnlyValue?.ToString("hh:mm:ss")
StringValue: @StringValue
LongValues: @LongValues.Length values (@string.Join(", ", LongValues.Select(x => x.ToString()).ToArray()))
@@ -10,7 +12,6 @@
Links:
With IntValue |
- With NullableDateTimeValue |
With IntValue and LongValues |
@@ -26,6 +27,10 @@
[Parameter, SupplyParameterFromQuery] public DateTime? NullableDateTimeValue { get ; set; }
+ [Parameter, SupplyParameterFromQuery] public DateOnly? NullableDateOnlyValue { get ; set; }
+
+ [Parameter, SupplyParameterFromQuery] public TimeOnly? NullableTimeOnlyValue { get ; set; }
+
[Parameter, SupplyParameterFromQuery] public string StringValue { get ; set; }
[Parameter, SupplyParameterFromQuery(Name = "l")] public long[] LongValues { get ; set; }
diff --git a/src/Framework/Analyzer/src/MinimalActions/MinimalActionAnalyzer.cs b/src/Framework/Analyzer/src/DelegateEndpoints/DelegateEndpointAnalyzer.cs
similarity index 85%
rename from src/Framework/Analyzer/src/MinimalActions/MinimalActionAnalyzer.cs
rename to src/Framework/Analyzer/src/DelegateEndpoints/DelegateEndpointAnalyzer.cs
index c5640e170af6..ad712b22ef1f 100644
--- a/src/Framework/Analyzer/src/MinimalActions/MinimalActionAnalyzer.cs
+++ b/src/Framework/Analyzer/src/DelegateEndpoints/DelegateEndpointAnalyzer.cs
@@ -8,14 +8,14 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
-namespace Microsoft.AspNetCore.Analyzers.MinimalActions;
+namespace Microsoft.AspNetCore.Analyzers.DelegateEndpoints;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
-public partial class MinimalActionAnalyzer : DiagnosticAnalyzer
+public partial class DelegateEndpointAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(new[]
{
- DiagnosticDescriptors.DoNotUseModelBindingAttributesOnMinimalActionParameters,
+ DiagnosticDescriptors.DoNotUseModelBindingAttributesOnDelegateEndpointParameters,
});
public override void Initialize(AnalysisContext context)
@@ -35,7 +35,7 @@ public override void Initialize(AnalysisContext context)
{
var invocation = (IInvocationOperation)operationAnalysisContext.Operation;
var targetMethod = invocation.TargetMethod;
- if (IsMapActionInvocation(wellKnownTypes, invocation, targetMethod))
+ if (IsDelegateHandlerInvocation(wellKnownTypes, invocation, targetMethod))
{
return;
}
@@ -60,13 +60,13 @@ public override void Initialize(AnalysisContext context)
});
}
- private static bool IsMapActionInvocation(
+ private static bool IsDelegateHandlerInvocation(
WellKnownTypes wellKnownTypes,
IInvocationOperation invocation,
IMethodSymbol targetMethod)
{
return !targetMethod.Name.StartsWith("Map", StringComparison.Ordinal) ||
- !SymbolEqualityComparer.Default.Equals(wellKnownTypes.MinimalActionEndpointRouteBuilderExtensions, targetMethod.ContainingType) ||
+ !SymbolEqualityComparer.Default.Equals(wellKnownTypes.DelegateEndpointRouteBuilderExtensions, targetMethod.ContainingType) ||
invocation.Arguments.Length != 3;
}
}
diff --git a/src/Framework/Analyzer/src/MinimalActions/DiagnosticDescriptors.cs b/src/Framework/Analyzer/src/DelegateEndpoints/DiagnosticDescriptors.cs
similarity index 71%
rename from src/Framework/Analyzer/src/MinimalActions/DiagnosticDescriptors.cs
rename to src/Framework/Analyzer/src/DelegateEndpoints/DiagnosticDescriptors.cs
index c4b2fb99f06f..2a133e2c1627 100644
--- a/src/Framework/Analyzer/src/MinimalActions/DiagnosticDescriptors.cs
+++ b/src/Framework/Analyzer/src/DelegateEndpoints/DiagnosticDescriptors.cs
@@ -3,15 +3,15 @@
using Microsoft.CodeAnalysis;
-namespace Microsoft.AspNetCore.Analyzers.MinimalActions
+namespace Microsoft.AspNetCore.Analyzers.DelegateEndpoints
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking")]
internal static class DiagnosticDescriptors
{
- internal static readonly DiagnosticDescriptor DoNotUseModelBindingAttributesOnMinimalActionParameters = new(
+ internal static readonly DiagnosticDescriptor DoNotUseModelBindingAttributesOnDelegateEndpointParameters = new(
"ASP0003",
- "Do not use model binding attributes with Map actions",
- "{0} should not be specified for a {1} delegate parameter",
+ "Do not use model binding attributes with Map handlers",
+ "{0} should not be specified for a {1} Delegate parameter",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
diff --git a/src/Framework/Analyzer/src/MinimalActions/DisallowMvcBindArgumentsOnParameters.cs b/src/Framework/Analyzer/src/DelegateEndpoints/DisallowMvcBindArgumentsOnParameters.cs
similarity index 90%
rename from src/Framework/Analyzer/src/MinimalActions/DisallowMvcBindArgumentsOnParameters.cs
rename to src/Framework/Analyzer/src/DelegateEndpoints/DisallowMvcBindArgumentsOnParameters.cs
index 80fbd5534651..19636859c22b 100644
--- a/src/Framework/Analyzer/src/MinimalActions/DisallowMvcBindArgumentsOnParameters.cs
+++ b/src/Framework/Analyzer/src/DelegateEndpoints/DisallowMvcBindArgumentsOnParameters.cs
@@ -6,9 +6,9 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
-namespace Microsoft.AspNetCore.Analyzers.MinimalActions;
+namespace Microsoft.AspNetCore.Analyzers.DelegateEndpoints;
-public partial class MinimalActionAnalyzer : DiagnosticAnalyzer
+public partial class DelegateEndpointAnalyzer : DiagnosticAnalyzer
{
private static void DisallowMvcBindArgumentsOnParameters(
in OperationAnalysisContext context,
@@ -33,7 +33,7 @@ private static void DisallowMvcBindArgumentsOnParameters(
var methodName = invocation.TargetMethod.Name;
context.ReportDiagnostic(Diagnostic.Create(
- DiagnosticDescriptors.DoNotUseModelBindingAttributesOnMinimalActionParameters,
+ DiagnosticDescriptors.DoNotUseModelBindingAttributesOnDelegateEndpointParameters,
location,
modelBindingAttribute.AttributeClass.Name,
methodName));
diff --git a/src/Framework/Analyzer/src/MinimalActions/WellKnownTypes.cs b/src/Framework/Analyzer/src/DelegateEndpoints/WellKnownTypes.cs
similarity index 72%
rename from src/Framework/Analyzer/src/MinimalActions/WellKnownTypes.cs
rename to src/Framework/Analyzer/src/DelegateEndpoints/WellKnownTypes.cs
index 4ef66bb80bb3..2576e56b6a4c 100644
--- a/src/Framework/Analyzer/src/MinimalActions/WellKnownTypes.cs
+++ b/src/Framework/Analyzer/src/DelegateEndpoints/WellKnownTypes.cs
@@ -4,15 +4,15 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
-namespace Microsoft.AspNetCore.Analyzers.MinimalActions;
+namespace Microsoft.AspNetCore.Analyzers.DelegateEndpoints;
internal sealed class WellKnownTypes
{
public static bool TryCreate(Compilation compilation, [NotNullWhen(true)] out WellKnownTypes? wellKnownTypes)
{
wellKnownTypes = default;
- const string MinimalActionEndpointRouteBuilderExtensions = "Microsoft.AspNetCore.Builder.MinimalActionEndpointRouteBuilderExtensions";
- if (compilation.GetTypeByMetadataName(MinimalActionEndpointRouteBuilderExtensions) is not { } minimalActionEndpointRouteBuilderExtensions)
+ const string DelegateEndpointRouteBuilderExtensions = "Microsoft.AspNetCore.Builder.DelegateEndpointRouteBuilderExtensions";
+ if (compilation.GetTypeByMetadataName(DelegateEndpointRouteBuilderExtensions) is not { } delegateEndpointRouteBuilderExtensions)
{
return false;
}
@@ -33,7 +33,7 @@ public static bool TryCreate(Compilation compilation, [NotNullWhen(true)] out We
wellKnownTypes = new WellKnownTypes
{
- MinimalActionEndpointRouteBuilderExtensions = minimalActionEndpointRouteBuilderExtensions,
+ DelegateEndpointRouteBuilderExtensions = delegateEndpointRouteBuilderExtensions,
IBinderTypeProviderMetadata = ibinderTypeProviderMetadata,
BindAttribute = bindAttribute,
};
@@ -41,7 +41,7 @@ public static bool TryCreate(Compilation compilation, [NotNullWhen(true)] out We
return true;
}
- public ITypeSymbol MinimalActionEndpointRouteBuilderExtensions { get; private init; }
+ public ITypeSymbol DelegateEndpointRouteBuilderExtensions { get; private init; }
public INamedTypeSymbol IBinderTypeProviderMetadata { get; private init; }
public INamedTypeSymbol BindAttribute { get; private init; }
}
diff --git a/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt b/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt
index 65dc3997cc20..3e5511733340 100644
--- a/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Extensions/src/PublicAPI.Unshipped.txt
@@ -192,7 +192,7 @@ static Microsoft.AspNetCore.Http.HeaderDictionaryTypeExtensions.AppendList(th
static Microsoft.AspNetCore.Http.HeaderDictionaryTypeExtensions.GetTypedHeaders(this Microsoft.AspNetCore.Http.HttpRequest! request) -> Microsoft.AspNetCore.Http.Headers.RequestHeaders!
static Microsoft.AspNetCore.Http.HeaderDictionaryTypeExtensions.GetTypedHeaders(this Microsoft.AspNetCore.Http.HttpResponse! response) -> Microsoft.AspNetCore.Http.Headers.ResponseHeaders!
static Microsoft.AspNetCore.Http.HttpContextServerVariableExtensions.GetServerVariable(this Microsoft.AspNetCore.Http.HttpContext! context, string! variableName) -> string?
-static Microsoft.AspNetCore.Http.RequestDelegateFactory.Create(System.Delegate! action, Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions? options = null) -> Microsoft.AspNetCore.Http.RequestDelegateResult!
+static Microsoft.AspNetCore.Http.RequestDelegateFactory.Create(System.Delegate! handler, Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions? options = null) -> Microsoft.AspNetCore.Http.RequestDelegateResult!
static Microsoft.AspNetCore.Http.RequestDelegateFactory.Create(System.Reflection.MethodInfo! methodInfo, System.Func? targetFactory = null, Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions? options = null) -> Microsoft.AspNetCore.Http.RequestDelegateResult!
static Microsoft.AspNetCore.Http.ResponseExtensions.Clear(this Microsoft.AspNetCore.Http.HttpResponse! response) -> void
static Microsoft.AspNetCore.Http.ResponseExtensions.Redirect(this Microsoft.AspNetCore.Http.HttpResponse! response, string! location, bool permanent, bool preserveMethod) -> void
diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs
index eb6a6eebe06f..cb2bc5d44cc1 100644
--- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs
+++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs
@@ -67,23 +67,23 @@ public static partial class RequestDelegateFactory
private static readonly AcceptsMetadata DefaultAcceptsMetadata = new(new[] { "application/json" });
///
- /// Creates a implementation for .
+ /// Creates a implementation for .
///
- /// A request handler with any number of custom parameters that often produces a response with its return value.
+ /// A request handler with any number of custom parameters that often produces a response with its return value.
/// The used to configure the behavior of the handler.
/// The .
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
- public static RequestDelegateResult Create(Delegate action, RequestDelegateFactoryOptions? options = null)
+ public static RequestDelegateResult Create(Delegate handler, RequestDelegateFactoryOptions? options = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
{
- if (action is null)
+ if (handler is null)
{
- throw new ArgumentNullException(nameof(action));
+ throw new ArgumentNullException(nameof(handler));
}
- var targetExpression = action.Target switch
+ var targetExpression = handler.Target switch
{
- object => Expression.Convert(TargetExpr, action.Target.GetType()),
+ object => Expression.Convert(TargetExpr, handler.Target.GetType()),
null => null,
};
@@ -92,9 +92,9 @@ public static RequestDelegateResult Create(Delegate action, RequestDelegateFacto
ServiceProviderIsService = options?.ServiceProvider?.GetService()
};
- var targetableRequestDelegate = CreateTargetableRequestDelegate(action.Method, options, factoryContext, targetExpression);
+ var targetableRequestDelegate = CreateTargetableRequestDelegate(handler.Method, options, factoryContext, targetExpression);
- return new RequestDelegateResult(httpContext => targetableRequestDelegate(action.Target, httpContext), factoryContext.Metadata);
+ return new RequestDelegateResult(httpContext => targetableRequestDelegate(handler.Target, httpContext), factoryContext.Metadata);
}
@@ -149,14 +149,14 @@ public static RequestDelegateResult Create(MethodInfo methodInfo, Func(action(..), httpContext);
+ // ExecuteTask(handler(..), httpContext);
else if (typeArg == typeof(string))
{
return Expression.Call(
@@ -459,7 +459,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
methodCall,
HttpContextExpr);
}
- // ExecuteTask(action(..), httpContext);
+ // ExecuteTask(handler(..), httpContext);
else if (typeArg == typeof(string))
{
return Expression.Call(
diff --git a/src/Http/Http.Extensions/test/Microsoft.AspNetCore.Http.Extensions.Tests.csproj b/src/Http/Http.Extensions/test/Microsoft.AspNetCore.Http.Extensions.Tests.csproj
index 25444590f57a..546bc7f16fb5 100644
--- a/src/Http/Http.Extensions/test/Microsoft.AspNetCore.Http.Extensions.Tests.csproj
+++ b/src/Http/Http.Extensions/test/Microsoft.AspNetCore.Http.Extensions.Tests.csproj
@@ -12,6 +12,7 @@
+
diff --git a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
index 2326e6907b09..4fd470ba02ee 100644
--- a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
+++ b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
@@ -19,6 +19,7 @@
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.Http.Metadata;
+using Microsoft.AspNetCore.Http.Result;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -185,10 +186,10 @@ public void BuildRequestDelegateThrowsArgumentNullExceptions()
var serviceProvider = new EmptyServiceProvider();
- var exNullAction = Assert.Throws(() => RequestDelegateFactory.Create(action: null!));
+ var exNullAction = Assert.Throws(() => RequestDelegateFactory.Create(handler: null!));
var exNullMethodInfo1 = Assert.Throws(() => RequestDelegateFactory.Create(methodInfo: null!));
- Assert.Equal("action", exNullAction.ParamName);
+ Assert.Equal("handler", exNullAction.ParamName);
Assert.Equal("methodInfo", exNullMethodInfo1.ParamName);
}
@@ -2240,6 +2241,35 @@ public async Task TreatsUnknownNullabilityAsOptionalForReferenceType(bool provid
#nullable enable
+ [Fact]
+ public async Task CanExecuteRequestDelegateWithResultsExtension()
+ {
+ IResult actionWithExtensionsResult(string name) => Results.Extensions.TestResult(name);
+
+ var httpContext = new DefaultHttpContext();
+ var serviceCollection = new ServiceCollection();
+ serviceCollection.AddSingleton(LoggerFactory);
+ httpContext.RequestServices = serviceCollection.BuildServiceProvider();
+ var responseBodyStream = new MemoryStream();
+ httpContext.Response.Body = responseBodyStream;
+
+ httpContext.Request.Query = new QueryCollection(new Dictionary
+ {
+ ["name"] = "Tester"
+ });
+
+ var factoryResult = RequestDelegateFactory.Create(actionWithExtensionsResult);
+
+ var requestDelegate = factoryResult.RequestDelegate;
+ await requestDelegate(httpContext);
+
+ Assert.Equal(200, httpContext.Response.StatusCode);
+ Assert.False(httpContext.RequestAborted.IsCancellationRequested);
+ var decodedResponseBody = Encoding.UTF8.GetString(responseBodyStream.ToArray());
+ Assert.Equal(@"""Hello Tester. This is from an extension method.""", decodedResponseBody);
+
+ }
+
private class Todo : ITodo
{
public int Id { get; set; }
@@ -2460,4 +2490,12 @@ public RequestBodyDetectionFeature(bool canHaveBody)
public bool CanHaveBody { get; }
}
}
+
+ internal static class TestExtensionResults
+ {
+ public static IResult TestResult(this IResultExtensions resultExtensions, string name)
+ {
+ return Results.Ok($"Hello {name}. This is from an extension method.");
+ }
+ }
}
diff --git a/src/Http/Http.Results/src/IResultExtensions.cs b/src/Http/Http.Results/src/IResultExtensions.cs
new file mode 100644
index 000000000000..4238d0b83692
--- /dev/null
+++ b/src/Http/Http.Results/src/IResultExtensions.cs
@@ -0,0 +1,11 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.AspNetCore.Http.Result
+{
+ ///
+ /// Provides an interface for registering external methods that provide
+ /// custom instances.
+ ///
+ public interface IResultExtensions { }
+}
\ No newline at end of file
diff --git a/src/Http/Http.Results/src/PublicAPI.Unshipped.txt b/src/Http/Http.Results/src/PublicAPI.Unshipped.txt
index ce00f48fd907..85b2eab9441f 100644
--- a/src/Http/Http.Results/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Results/src/PublicAPI.Unshipped.txt
@@ -31,3 +31,5 @@ static Microsoft.AspNetCore.Http.Results.Text(string! content, string? contentTy
static Microsoft.AspNetCore.Http.Results.Unauthorized() -> 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!
+static Microsoft.AspNetCore.Http.Results.Extensions.get -> Microsoft.AspNetCore.Http.Result.IResultExtensions!
+Microsoft.AspNetCore.Http.Result.IResultExtensions
\ No newline at end of file
diff --git a/src/Http/Http.Results/src/ResultExtensions.cs b/src/Http/Http.Results/src/ResultExtensions.cs
new file mode 100644
index 000000000000..2666e72f3f37
--- /dev/null
+++ b/src/Http/Http.Results/src/ResultExtensions.cs
@@ -0,0 +1,11 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.AspNetCore.Http.Result
+{
+ ///
+ /// Implements an interface for registering external methods that provide
+ /// custom instances.
+ ///
+ internal sealed class ResultExtensions : IResultExtensions { }
+}
\ No newline at end of file
diff --git a/src/Http/Http.Results/src/Results.cs b/src/Http/Http.Results/src/Results.cs
index 4ba49f98e494..15d4937e3a24 100644
--- a/src/Http/Http.Results/src/Results.cs
+++ b/src/Http/Http.Results/src/Results.cs
@@ -588,5 +588,11 @@ public static IResult Accepted(string? uri = null, object? value = null)
/// The created for the response.
public static IResult AcceptedAtRoute(string? routeName = null, object? routeValues = null, object? value = null)
=> new AcceptedAtRouteResult(routeName, routeValues, value);
+
+ ///
+ /// Provides a place for external libraries to extend the default set
+ /// via extension methods returning custom implementations.
+ ///
+ public static IResultExtensions Extensions { get; } = new ResultExtensions();
}
}
diff --git a/src/Http/Routing/src/Builder/MinimalActionEndpointConventionBuilder.cs b/src/Http/Routing/src/Builder/DelegateEndpointConventionBuilder.cs
similarity index 79%
rename from src/Http/Routing/src/Builder/MinimalActionEndpointConventionBuilder.cs
rename to src/Http/Routing/src/Builder/DelegateEndpointConventionBuilder.cs
index cdcf7f6870a2..d5884ad8d915 100644
--- a/src/Http/Routing/src/Builder/MinimalActionEndpointConventionBuilder.cs
+++ b/src/Http/Routing/src/Builder/DelegateEndpointConventionBuilder.cs
@@ -9,16 +9,16 @@ namespace Microsoft.AspNetCore.Builder
///
/// Builds conventions that will be used for customization of MapAction instances.
///
- public sealed class MinimalActionEndpointConventionBuilder : IEndpointConventionBuilder
+ public sealed class DelegateEndpointConventionBuilder : IEndpointConventionBuilder
{
private readonly List _endpointConventionBuilders;
- internal MinimalActionEndpointConventionBuilder(IEndpointConventionBuilder endpointConventionBuilder)
+ internal DelegateEndpointConventionBuilder(IEndpointConventionBuilder endpointConventionBuilder)
{
_endpointConventionBuilders = new List() { endpointConventionBuilder };
}
- internal MinimalActionEndpointConventionBuilder(List endpointConventionBuilders)
+ internal DelegateEndpointConventionBuilder(List endpointConventionBuilders)
{
_endpointConventionBuilders = endpointConventionBuilders;
}
diff --git a/src/Http/Routing/src/Builder/MinimalActionEndpointRouteBuilderExtensions.cs b/src/Http/Routing/src/Builder/DelegateEndpointRouteBuilderExtensions.cs
similarity index 78%
rename from src/Http/Routing/src/Builder/MinimalActionEndpointRouteBuilderExtensions.cs
rename to src/Http/Routing/src/Builder/DelegateEndpointRouteBuilderExtensions.cs
index d209bd774a57..7158dc05f8a3 100644
--- a/src/Http/Routing/src/Builder/MinimalActionEndpointRouteBuilderExtensions.cs
+++ b/src/Http/Routing/src/Builder/DelegateEndpointRouteBuilderExtensions.cs
@@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Builder
///
/// Provides extension methods for to define HTTP API endpoints.
///
- public static class MinimalActionEndpointRouteBuilderExtensions
+ public static class DelegateEndpointRouteBuilderExtensions
{
// Avoid creating a new array every call
private static readonly string[] GetVerb = new[] { "GET" };
@@ -31,14 +31,14 @@ public static class MinimalActionEndpointRouteBuilderExtensions
///