Передача параметра из MapPost в локальную функцию
Я рефакторил свои конечные точки в проекте Minimal WebApi и столкнулся с такой ситуацией:
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>();
}
Сейчас,LoginAsync
нужно значение параметра дляipAddress
. Как мне пройтиHttpContext.Connection.RemoteIpAddress.ToString()
от моегоapp.MapPost
?
2 ответа
Вы можете добавить параметр метода as handler и использовать его:
private static async Task<IResult> LoginAsync(ApiUserModel model,
HttpContext ctx, // here
IApiUserService userService,
IOptions<Jwt> jwtConfigRaw,
CancellationToken ct)
{
var ip = ctx.Connection.RemoteIpAddress;
//...
}
См. подраздел специальных типов в документах, посвященных параметрам минимального API:
Специальные типы
Следующие типы связаны без явных атрибутов:
HttpContext
: контекст, который содержит всю информацию о текущем HTTP-запросе или ответе.HttpRequest
иHttpResponse
: HTTP-запрос и HTTP-ответ.CancellationToken
: токен отмены, связанный с текущим HTTP-запросом.ClaimsPrincipal
: Пользователь, связанный с запросом, связанный сHttpContext.User
.
Немного поразмыслив, я понял, что раскрытие параметра ipAddress заставило чванство думать, что я должен предоставить его сам. Вот что я сделал:
private static async Task<IResult> LoginAsync(ApiUserModel model, IHttpContextAccessor httpContextAccessor, IApiUserService userService, IOptions<Jwt> jwtConfigRaw, CancellationToken ct)
{
...
var ipAddress = httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString();
...
}
Таким образом, вводяIHttpContextAccessor
решил это для меня.