Skip to content

Commit 48dcb4a

Browse files
captainsafiapranavkm
authored andcommitted
Add support for Results extension point
1 parent aa04f8e commit 48dcb4a

6 files changed

+69
-0
lines changed

src/Http/Http.Extensions/test/Microsoft.AspNetCore.Http.Extensions.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
<ItemGroup>
1414
<Reference Include="Microsoft.AspNetCore.Http" />
15+
<Reference Include="Microsoft.AspNetCore.Http.Results" />
1516
<Reference Include="Microsoft.AspNetCore.Http.Extensions" />
1617
<Reference Include="Microsoft.Extensions.DependencyInjection" />
1718
</ItemGroup>

src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using Microsoft.AspNetCore.Http.Features;
2020
using Microsoft.AspNetCore.Http.Json;
2121
using Microsoft.AspNetCore.Http.Metadata;
22+
using Microsoft.AspNetCore.Http.Result;
2223
using Microsoft.AspNetCore.Testing;
2324
using Microsoft.Extensions.DependencyInjection;
2425
using Microsoft.Extensions.Logging;
@@ -2240,6 +2241,35 @@ public async Task TreatsUnknownNullabilityAsOptionalForReferenceType(bool provid
22402241

22412242
#nullable enable
22422243

2244+
[Fact]
2245+
public async Task CanExecuteRequestDelegateWithResultsExtension()
2246+
{
2247+
IResult actionWithExtensionsResult(string name) => Results.Extensions.TestResult(name);
2248+
2249+
var httpContext = new DefaultHttpContext();
2250+
var serviceCollection = new ServiceCollection();
2251+
serviceCollection.AddSingleton(LoggerFactory);
2252+
httpContext.RequestServices = serviceCollection.BuildServiceProvider();
2253+
var responseBodyStream = new MemoryStream();
2254+
httpContext.Response.Body = responseBodyStream;
2255+
2256+
httpContext.Request.Query = new QueryCollection(new Dictionary<string, StringValues>
2257+
{
2258+
["name"] = "Tester"
2259+
});
2260+
2261+
var factoryResult = RequestDelegateFactory.Create(actionWithExtensionsResult);
2262+
2263+
var requestDelegate = factoryResult.RequestDelegate;
2264+
await requestDelegate(httpContext);
2265+
2266+
Assert.Equal(200, httpContext.Response.StatusCode);
2267+
Assert.False(httpContext.RequestAborted.IsCancellationRequested);
2268+
var decodedResponseBody = Encoding.UTF8.GetString(responseBodyStream.ToArray());
2269+
Assert.Equal(@"""Hello Tester. This is from an extension method.""", decodedResponseBody);
2270+
2271+
}
2272+
22432273
private class Todo : ITodo
22442274
{
22452275
public int Id { get; set; }
@@ -2460,4 +2490,12 @@ public RequestBodyDetectionFeature(bool canHaveBody)
24602490
public bool CanHaveBody { get; }
24612491
}
24622492
}
2493+
2494+
internal static class TestExtensionResults
2495+
{
2496+
public static IResult TestResult(this IResultExtensions resultExtensions, string name)
2497+
{
2498+
return Results.Ok($"Hello {name}. This is from an extension method.");
2499+
}
2500+
}
24632501
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Microsoft.AspNetCore.Http.Result
5+
{
6+
/// <summary>
7+
/// Provides an interface for registering external methods that provide
8+
/// custom <see cref="IResult" /> instances.
9+
/// </summary>
10+
public interface IResultExtensions { }
11+
}

src/Http/Http.Results/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ static Microsoft.AspNetCore.Http.Results.Text(string! content, string? contentTy
3131
static Microsoft.AspNetCore.Http.Results.Unauthorized() -> Microsoft.AspNetCore.Http.IResult!
3232
static Microsoft.AspNetCore.Http.Results.UnprocessableEntity(object? error = null) -> Microsoft.AspNetCore.Http.IResult!
3333
static Microsoft.AspNetCore.Http.Results.ValidationProblem(System.Collections.Generic.IDictionary<string!, string![]!>! errors, string? detail = null, string? instance = null, int? statusCode = null, string? title = null, string? type = null) -> Microsoft.AspNetCore.Http.IResult!
34+
static Microsoft.AspNetCore.Http.Results.Extensions.get -> Microsoft.AspNetCore.Http.Result.IResultExtensions!
35+
Microsoft.AspNetCore.Http.Result.IResultExtensions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Microsoft.AspNetCore.Http.Result
5+
{
6+
/// <summary>
7+
/// Implements an interface for registering external methods that provide
8+
/// custom <see cref="IResult"/> instances.
9+
/// </summary>
10+
internal sealed class ResultExtensions : IResultExtensions { }
11+
}

src/Http/Http.Results/src/Results.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,5 +588,11 @@ public static IResult Accepted(string? uri = null, object? value = null)
588588
/// <returns>The created <see cref="IResult"/> for the response.</returns>
589589
public static IResult AcceptedAtRoute(string? routeName = null, object? routeValues = null, object? value = null)
590590
=> new AcceptedAtRouteResult(routeName, routeValues, value);
591+
592+
/// <summary>
593+
/// Provides a place for external libraries to extend the default <see cref="Results"/> set
594+
/// via extension methods returning custom <see cref="IResult" /> implementations.
595+
/// </summary>
596+
public static IResultExtensions Extensions { get; } = new ResultExtensions();
591597
}
592598
}

0 commit comments

Comments
 (0)