我在一个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
的参数值。如何从app.MapPost
传递HttpContext.Connection.RemoteIpAddress.ToString()
?
您可以添加HttpContext
作为处理程序方法参数并使用它:
private static async Task<IResult> LoginAsync(ApiUserModel model,
HttpContext ctx, // here
IApiUserService userService,
IOptions<Jwt> jwtConfigRaw,
CancellationToken ct)
{
var ip = ctx.Connection.RemoteIpAddress;
//...
}
请参阅Minimal API参数提示文档的特殊类型小节:
特殊类型
以下类型绑定时没有显式属性:
HttpContext
:保存当前HTTP请求或响应的所有信息的上下文HttpRequest
和HttpResponse
:HTTP请求和HTTP响应CancellationToken
:与当前HTTP请求关联的取消令牌ClaimsPrincipal
:与请求关联的用户,从HttpContext.User
绑定而来
经过一番挠头之后,我意识到暴露ipAddress参数让swagger认为我必须自己提供。以下是我所做的:
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
为我解决了这个问题