Asp.net web api ASP.NET Web API避免查询字符串中的无效参数

Asp.net web api ASP.NET Web API避免查询字符串中的无效参数,asp.net-web-api,filter,query-string,Asp.net Web Api,Filter,Query String,给定以下Web API控制器操作: // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } 有没有办法确保查询字符串中的所有参数都是所调用操作的有效参数?您可以编写一个操作筛选器,验证所有查询参数是否都在操作参数中,如果没有,则抛出 使用系统; 使用System.Linq; Net系统; 使用S

给定以下Web API控制器操作:

    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

有没有办法确保查询字符串中的所有参数都是所调用操作的有效参数?

您可以编写一个操作筛选器,验证所有查询参数是否都在操作参数中,如果没有,则抛出

使用系统;
使用System.Linq;
Net系统;
使用System.Net.Http;
使用System.Web.Http.Controller;
使用System.Web.Http.Filters;
名称空间My.namespace.Filters
{
/// 
///检查在查询字符串中传递的参数的操作筛选器
///仅是我们在方法签名中指定的那些。
///否则返回404错误请求。
/// 
公共类ValidateQueryParametersAttribute:ActionFilterAttribute
{
/// 
///此方法在每次WS调用之前运行
/// 
/// 
公共重写无效OnActionExecuting(HttpActionContext actionContext)
{
//检查客户端是否未使用任何无效参数
//但这些只是WS方法所需要的
var parameters=actionContext.ActionDescriptor.GetParameters();
var queryParameters=actionContext.Request.GetQueryNameValuePairs();
if(queryParameters.Select(kvp=>kvp.Key).Any(queryParameter=>!parameters.Any(p=>p.ParameterName==queryParameter)))
{
actionContext.Response=actionContext.Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
}
}

为了更好地使用开箱即用的验证支持,我创建了自己的操作选择器,它可以将URI参数绑定到复杂类型对象,而无需重复

因此,您可以使用此操作选择器执行以下操作:

public class CarsByCategoryRequestCommand {

    public int CategoryId { get; set; }
    public int Page { get; set; }

    [Range(1, 50)]
    public int Take { get; set; }
}

public class CarsByColorRequestCommand {

    public int ColorId { get; set; }
    public int Page { get; set; }

    [Range(1, 50)]
    public int Take { get; set; }
}

[InvalidModelStateFilter]
public class CarsController : ApiController {

    public string[] GetCarsByCategoryId(
        [FromUri]CarsByCategoryRequestCommand cmd) {

        return new[] { 
            "Car 1",
            "Car 2",
            "Car 3"
        };
    }

    public string[] GetCarsByColorId(
        [FromUri]CarsByColorRequestCommand cmd) {

        return new[] { 
            "Car 1",
            "Car 2"
        };
    }
}
然后,您可以注册一个操作过滤器来验证用户输入,以终止请求并返回“400错误请求”响应以及验证错误消息:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class InvalidModelStateFilterAttribute : ActionFilterAttribute {

    public override void OnActionExecuting(HttpActionContext actionContext) {

        if (!actionContext.ModelState.IsValid) {

            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}
有关此操作选择器以及如何获取它的更多信息,请查看以下帖子:


您不需要它,因为如果没有必要的简单类型参数,默认操作选择器将不会选择该操作,并且基本上返回404。如果所有参数都是可选的,即Get(int?p1=null,int?p2=null),则即使查询字符串包含无效参数,也会执行该操作,因此,我认为这种方法应该有效。我来试一试,谢谢!啊,对。默认操作选择器不考虑可选参数。看起来不错,我将首先尝试RaghuRam建议的更简单的方法,无论如何,这非常有趣,感谢分享:)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class InvalidModelStateFilterAttribute : ActionFilterAttribute {

    public override void OnActionExecuting(HttpActionContext actionContext) {

        if (!actionContext.ModelState.IsValid) {

            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}