c# - 是否可以在 ASP.NET Core 中组合 [FromRoute] 和 [FromBody]?

标签 c# asp.net-core fluentvalidation asp.net-core-routing

我对 API Controller 有这样的操作:

[HttpPost]
public async Task<IActionResult> StartDeployment(
    [FromQuery]Guid deploymentId,
    [FromRoute]RequestInfo requestInfo,
    [FromBody]DeploymenRequest deploymentRequest)
{
}

可通过复杂的 url (requestInfo) 获取并接收 HTTP POST 请求负载 (deploymentRequest)。

是否可以结合使用 [FromRoute][FromBody] 这样我就有了单一请求模型:

public class UberDeploymentRequestInfo
{
    [FromQuery]public Guid DeploymentId { get; set; }

    [FromRoute]public RequestInfo RequestInfo { get; set; }

    [FromBody]public DeploymenRequest DeploymentRequest { get; set; }
}

所以我可以使用 Fluent Validation 拥有单个验证器:

internal class UberDeploymentRequestInfoValidator : AbstractValidator<UberDeploymentRequestInfo>
{
    public UberDeploymentRequestInfoValidator()
    {
        // validation rules can access both url and payload
    }
}

最佳答案

如评论中所述,它可以通过自定义模型 Binder 来实现。下面是一些代码片段,用于连接所有内容,例如,您可以将带有以下 JSON 正文的 http 请求发送到 API /api/cats?From=james&Days=20

{
    "Name":"",
    "EyeColor":"Red"
}

几个类,你也可以在这里找到它们:https://github.com/atwayne/so-51316269

// We read Cat from request body
public class Cat
{
    public string Name { get; set; }
    public string EyeColor { get; set; }
}

// AdoptionRequest from Query String or Route
public class AdoptionRequest
{
    public string From { get; set; }
    public string Days { get; set; }
}

// One class to merge them together
[ModelBinder(BinderType = typeof(CatAdoptionEntityBinder))]
public class CatAdoptionRequest
{
    public Cat Cat { get; set; }
    public AdoptionRequest AdoptionRequest { get; set; }
}


public class CatAdoptionEntityBinder : IModelBinder
{
    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        // Read Cat from Body
        var memoryStream = new MemoryStream();
        var body = bindingContext.HttpContext.Request.Body;
        var reader = new StreamReader(body, Encoding.UTF8);
        var text = reader.ReadToEnd();
        var cat = JsonConvert.DeserializeObject<Cat>(text);

        // Read Adoption Request from query or route
        var adoptionRequest = new AdoptionRequest();
        var properties = typeof(AdoptionRequest).GetProperties();
        foreach (var property in properties)
        {
            var valueProvider = bindingContext.ValueProvider.GetValue(property.Name);
            if (valueProvider != null)
            {
                property.SetValue(adoptionRequest, valueProvider.FirstValue);
            }
        }

        // Merge
        var model = new CatAdoptionRequest()
        {
            Cat = cat,
            AdoptionRequest = adoptionRequest
        };

        bindingContext.Result = ModelBindingResult.Success(model);
        return;
    }
}


// Controller
[HttpPost()]
public bool Post([CustomizeValidator]CatAdoptionRequest adoptionRequest)
{
    return ModelState.IsValid;
}

public class CatAdoptionRequestValidator : AbstractValidator<CatAdoptionRequest>
{
    public CatAdoptionRequestValidator()
    {
        RuleFor(profile => profile.Cat).NotNull();
        RuleFor(profile => profile.AdoptionRequest).NotNull();
        RuleFor(profile => profile.Cat.Name).NotEmpty();
    }
}

// and in our Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddFluentValidation();
    services.AddTransient<IValidator<CatAdoptionRequest>, CatAdoptionRequestValidator>();
}

关于c# - 是否可以在 ASP.NET Core 中组合 [FromRoute] 和 [FromBody]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51316269/

相关文章:

c# - 如何在 asp.net 中的按钮单击事件调用之前和之后调用 javascript 函数

c# - 如何使用 IEnumerable<> 类型创建 CodeFunction2?

c# - Azure ASP .net WebApp - 500 错误 - 请求超时

c# - 无法解析类型 'System.Net.Http.HttpClient' 的服务

c# - 数字格式在 ASP.NET Core 中不起作用

c# - 数据注释属性在 asp net core 中不起作用

asp.net-core - 了解 ASP.NET Core 依赖关系和功能

asp.net-mvc-3 - ASP.NET MVC3 Fluent Validation Constructor 每个请求命中多次

c# - 空对象的 FluentValidation 规则

c# - FluentValidation 中依赖规则的顺序