I was refactoring my endpoints in a Minimal WebApi project and faced this situation:
namespace DACRL.API.Endpoints;
public class ApiUserManagementEndpoints : IEndpoints
{
private const string ContentType = "application/json";
private const string Tag = "ApiAccounts";
private const string BaseRoute = "apiAccounts";
public static void DefineEndpoints(IEndpointRouteBuilder app)
{
app.MapPost($"{BaseRoute}/login", LoginAsync)
.WithName("LoginApiUser")
.Accepts<ApiUserModel>(ContentType)
.Produces<string>()
.Produces<ApiAuthResponse>()
.Produces((int)HttpStatusCode.NotFound)
.Produces((int)HttpStatusCode.BadRequest)
.WithTags(Tag);
}
#region Helpers
private static async Task<IResult> LoginAsync(ApiUserModel model, string ipAddress, IApiUserService userService, IOptions<Jwt> jwtConfigRaw, CancellationToken ct)
{
...
return Results.Ok(result);
}
private static string GenerateToken(Jwt jwtConfig, string username)
{
// Token stuff
}
#endregion
public static void AddServices(IServiceCollection services, IConfiguration configuration) =>
services.AddTransient<IApiUserService, ApiUserService>();
}
Now, LoginAsync needs a parameter value for ipAddress. How do I pass HttpContext.Connection.RemoteIpAddress.ToString() from my app.MapPost ?
>Solution :
You can inject HttpContext and use it:
private static async Task<IResult> LoginAsync(ApiUserModel model,
HttpContext ctx, // here
IApiUserService userService,
IOptions<Jwt> jwtConfigRaw,
CancellationToken ct)
{
var ip = ctx.Connection.RemoteIpAddress;
//...
}
See the special types subsection of Minimal APIs parameter minding docs:
Special types
The following types are bound without explicit attributes:
HttpContext: The context which holds all the information about the current HTTP request or response.HttpRequestandHttpResponse: The HTTP request and HTTP response.CancellationToken: The cancellation token associated with the current HTTP request.ClaimsPrincipal: The user associated with the request, bound fromHttpContext.User.