首页 > 解决方案 > WebApi:ID之间的不匹配

问题描述

鉴于以下路线

/api/Person/15

我们用 body 对这条路线做一个 PUT:

{
    id: 8,
    name: 'Joosh'
}

路线段值为 ,15[FromBody]id 为8

现在我们的控制器中有如下内容:

public Model Put(string id, [FromBody] Model model)
{
     if (id != model.Id)
         throw new Exception("Id mismatch!");

     // ... Do normal stuff
}

是否有“默认”或 DRY-ish 方法来执行此操作,而不假设它总是像参数 ID 和 Model.Id 属性一样简单?

标签: c#asp.net-core-webapi

解决方案


是否有“默认”或 DRY-ish 方法来执行此操作,而不假设它总是像参数 ID 和 Model.Id 属性一样简单?

自定义验证逻辑可以在 ActionFilter 中实现。因为 ActionFilter 是在动作执行中模型绑定之后处理的,所以模型和动作参数可以在 ActionFilter 中使用,而无需从请求正文或 URL 中读取。您可以参考以下工作演示:

  • 自定义验证过滤器

    public class ValidationFilter: ActionFilterAttribute
    {
     private readonly ILogger _logger;
    
    public ValidationFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger("ValidatePayloadTypeFilter");
    }
    
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var carDto = context.ActionArguments["car"] as Car;
    
        var id = context.ActionArguments["id"];
        if (Convert.ToInt32(id)!=carDto.Id)
        {
            context.HttpContext.Response.StatusCode = 400;
            context.Result = new ContentResult()
            {
                Content = "Id mismatch!"
            };
            return;
        }
    
        base.OnActionExecuting(context);
     }
    }
    
  • 在 ConfigureServices 方法中注册此操作过滤器

    services.AddScoped<ValidationFilter>();
    
  • 将此操作过滤器称为服务

    public class Car
    {
       public int Id { get; set; }
       public string CarName { get; set; }
    }
    
    [ServiceFilter(typeof(ValidationFilter))]
    [HttpPut("{id}")]
    public Car Put(int id, [FromBody] Car car)
    {
     // the stuff you want
    }
    

参考:

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2#action-filters

https://code-maze.com/action-filters-aspnetcore/#comments


推荐阅读