Skip to content
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
7 changes: 7 additions & 0 deletions docs/guide/http/endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,4 +428,11 @@ There is no runtime filtering here because the `MiddlewareScoping` impacts the g
HTTP endpoint method, and Wolverine already generates code separately for the two use cases.
:::

As of Wolverine 5.7, you can also technically use `HttpContext` arguments in the message handler usage *if*
you are carefully accounting for that being null as shown in this sample:

snippet: sample_HybridHandler_with_null_HttpContext




14 changes: 14 additions & 0 deletions src/Http/Wolverine.Http.Tests/combo_handler_and_endpoint.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Alba;
using Microsoft.AspNetCore.Mvc;
using Shouldly;
using Wolverine.Tracking;
using WolverineWebApi;

namespace Wolverine.Http.Tests;
Expand Down Expand Up @@ -63,4 +64,17 @@ public async Task use_combo_as_handler_see_problem_details_catch()
NumberMessageHandler.CalledBeforeOnlyOnHttpEndpoints.ShouldBeFalse();
NumberMessageHandler.CalledBeforeOnlyOnMessageHandlers.ShouldBeTrue();
}

[Fact]
public async Task will_not_go_bonkers_with_nullable_http_context()
{
var response = await Host.Scenario(x =>
{
x.Post.Json(new DoHybrid("go, go gadget")).ToUrl("/hybrid");
});

response.ReadAsText().ShouldBe("go, go gadget");

await Host.InvokeMessageAndWaitAsync(new DoHybrid("now as a handler"));
}
}
18 changes: 18 additions & 0 deletions src/Http/Wolverine.Http/CodeGen/NullableHttpContextSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using JasperFx.CodeGeneration.Model;
using Microsoft.AspNetCore.Http;

namespace Wolverine.Http.CodeGen;

internal class NullableHttpContextSource : IVariableSource
{
public bool Matches(Type type)
{
return type == typeof(HttpContext);
}

public Variable Create(Type type)
{
return new Variable(typeof(HttpContext), "null");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ public static IServiceCollection AddWolverineHttp(this IServiceCollection servic
services.AddSingleton<WolverineHttpOptions>();
services.AddSingleton<NewtonsoftHttpSerialization>();
services.AddSingleton<HttpTransportExecutor>();

services.ConfigureWolverine(opts =>
{
opts.CodeGeneration.Sources.Add(new NullableHttpContextSource());
});

return services;
}

Expand Down
24 changes: 24 additions & 0 deletions src/Http/WolverineWebApi/HybridHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Wolverine.Http;

namespace WolverineWebApi;

#region sample_HybridHandler_with_null_HttpContext

public record DoHybrid(string Message);

public static class HybridHandler
{
[WolverinePost("/hybrid")]
public static async Task HandleAsync(DoHybrid command, HttpContext? context)
{
// What this, because it will be null if this is used within
// a message handler!
if (context != null)
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync(command.Message);
}
}
}

#endregion
Loading