Web Api必需参数

Jas*_*oyd 36 c# asp.net asp.net-web-api

使用ASP.NET Web API.如果参数为空,有没有办法自动返回状态代码400?我发现了这个问题,但这是一个应用于所有方法的全局解决方案,我想在每个参数的每个方法的基础上执行此操作.

所以,例如,这就是我目前正在做的事情:

public HttpResponseMessage SomeMethod(SomeNullableParameter parameter)
{
    if (parameter == null)
        throw new HttpResponseException(HttpStatusCode.BadRequest);

    // Otherwise do more stuff.
}
Run Code Online (Sandbox Code Playgroud)

我真的只想做这样的事情(注意所需的属性):

public HttpResponseMessage SomeMethod([Required] SomeNullableParameter parameter)
{
    // Do stuff.
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*oyd 20

我最终使用的方法是创建一个我在全球注册的自定义过滤器.过滤器检查所有请求参数RequiredAttribute.如果找到该属性,则它检查参数是否随请求一起传递(非null),如果为null则返回状态代码400.我还在过滤器中添加了一个缓存,以存储每个请求所需的参数,以避免在将来的调用中出现反射.我很高兴地发现这适用于值类型,因为操作上下文将参数存储为对象.

编辑 - 基于tecfield评论的更新解决方案

public class RequiredParametersFilter : ActionFilterAttribute
{
    // Cache used to store the required parameters for each request based on the
    // request's http method and local path.
    private readonly ConcurrentDictionary<Tuple<HttpMethod, string>, List<string>> _Cache =
        new ConcurrentDictionary<Tuple<HttpMethod, string>, List<string>>();

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // Get the request's required parameters.
        List<string> requiredParameters = this.GetRequiredParameters(actionContext);     

        // If the required parameters are valid then continue with the request.
        // Otherwise, return status code 400.
        if(this.ValidateParameters(actionContext, requiredParameters))
        {
            base.OnActionExecuting(actionContext);
        }
        else
        {
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    }

    private bool ValidateParameters(HttpActionContext actionContext, List<string> requiredParameters)
    {
        // If the list of required parameters is null or containst no parameters 
        // then there is nothing to validate.  
        // Return true.
        if (requiredParameters == null || requiredParameters.Count == 0)
        {
            return true;
        }

        // Attempt to find at least one required parameter that is null.
        bool hasNullParameter = 
            actionContext
            .ActionArguments
            .Any(a => requiredParameters.Contains(a.Key) && a.Value == null);

        // If a null required paramter was found then return false.  
        // Otherwise, return true.
        return !hasNullParameter;
    }

    private List<string> GetRequiredParameters(HttpActionContext actionContext)
    {
        // Instantiate a list of strings to store the required parameters.
        List<string> result = null;

        // Instantiate a tuple using the request's http method and the local path.
        // This will be used to add/lookup the required parameters in the cache.
        Tuple<HttpMethod, string> request =
            new Tuple<HttpMethod, string>(
                actionContext.Request.Method,
                actionContext.Request.RequestUri.LocalPath);

        // Attempt to find the required parameters in the cache.
        if (!this._Cache.TryGetValue(request, out result))
        {
            // If the required parameters were not found in the cache then get all
            // parameters decorated with the 'RequiredAttribute' from the action context.
            result = 
                actionContext
                .ActionDescriptor
                .GetParameters()
                .Where(p => p.GetCustomAttributes<RequiredAttribute>().Any())
                .Select(p => p.ParameterName)
                .ToList();

            // Add the required parameters to the cache.
            this._Cache.TryAdd(request, result);
        }

        // Return the required parameters.
        return result;
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 你的缓存要小心.你可能想使用一个线程安全的`ConcurrentDictionary`而不是一个非线程安全的普通`Dictionary`! (6认同)

Tim*_*ell 5

设置[Required]模型中的属性,然后检查ModelState它是否存在IsValid

这将允许同时测试所有必需的属性。

请参阅“Under-Posting”部分@WebAPI 中的模型验证

  • 从 Asp.Net Core 2.1 开始,有一个内置验证。请参阅我的回复 stackoverflow.com/a/54533218/245460 (3认同)
  • 我对这种方法感到担忧,因为我可能想要处理与空参数不同的无效模型。我确实尝试了一下,看看它是否有效,但没有。因为该对象为空,所以它从未被添加到模型中,所以从未发生过验证。 (2认同)