FluentValidation 能否识别调用了哪些方法(PUT 或 POST)?

Ada*_*nar 3 c# fluentvalidation .net-core asp.net-core asp.net-core-webapi

在 中ASP.NET Core 3.0 Web API,我对和方法使用相同的DTO。在创建新名称时,我想防止已经存在的名称。像这样:PostPutItem

    public ItemValidator(IItemRepository itemRepository)
    {
        RuleFor(input => input.Name).NotEmpty();
        RuleFor(input => input.Name).Must(name => !itemRepository.ItemExists(name))
            .WithMessage(input => $"Item '{input.Name}' already exists");
    }
Run Code Online (Sandbox Code Playgroud)

这一切都非常适合更新和插入。您不能将名称更新为已存在的名称。但!当您尝试将“ItemA”更改为“ItemA”(新名称与旧名称相同)时,您会收到该错误,并且可能会有点误导(尽管在技术上是正确的)。

dto本身中,我没有唯一id的项目。因为我id在路上经过。

如果我可以访问已调用的控制器方法及其参数(包括id),我将能够判断是否有人试图将项目名称更改为相同名称。

Kus*_*ush 5

FluentValidation 可以识别调用的是哪个 HTTP 方法。为此,您需要在 StartUp 文件的 ConfigureServices 方法中添加 HttpContextAccessor。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddHttpContextAccessor();
        services.AddMvc(setup => { }).AddFluentValidation();
        services.AddTransient<IValidator<MyModel>, MyModelValidator>();
    }
Run Code Online (Sandbox Code Playgroud)

现在您可以在验证器类中使用 IHttpContextAccessor。这是我的验证器类

public class MyModelValidator : AbstractValidator<MyModel>
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public MyModelValidator(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;

        RuleFor(myModel => myModel.Id)
            .NotEmpty();

        RuleFor(myModel => myModel.Value)
            .Must(value => MyRule(value, _httpContextAccessor.HttpContext.Request.Method));
    }

    private bool MyRule(string value, string method)
    {
        if (method.ToUpper() == "POST")
        {
            return true;
        }
        else if (method.ToUpper() == "PUT")
        {
            // validatation logic for value
            return !string.IsNullOrWhiteSpace(value);
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以从 _httpContextAccessor 获取请求路径如下

var path = _httpContextAccessor.HttpContext.Request.Path.Value;
Run Code Online (Sandbox Code Playgroud)

编辑:

如果这解决了您的问题,请考虑将此答案标记为已接受。