Asp.net 如何防止随机查询与用[Route(';';)]注释的操作匹配?

Asp.net 如何防止随机查询与用[Route(';';)]注释的操作匹配?,asp.net,asp.net-web-api2,asp.net-web-api-routing,Asp.net,Asp.net Web Api2,Asp.net Web Api Routing,我现在有这个控制器 [RoutePrefix("api/Home")] public class HomeController : ApiController { [HttpGet] [Route("")] public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null){ if (!ModelState.IsVal

我现在有这个控制器

[RoutePrefix("api/Home")]
public class HomeController : ApiController
{

    [HttpGet]
    [Route("")]
    public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null){

        if (!ModelState.IsValid) //From ApiController.ModelState
        {
            return BadRequest(ModelState);
        }
    }
}
我只希望匹配以下3个URL:

  • api/Home
    id
    AnotherId
    均为空)
  • api/Home?id=1
    (仅
    另一个id
    为空)
  • api/Home?AnotherId=1
    (仅
    Id
    为空)
  • 其他URL应返回
    未注册的路由
    错误
    。目前,
    api/Home?asdfanyquery
    还返回了一个我不希望的匹配


    如何重写控制器,使路由仅与上述3个URL匹配?

    您所说的
    api/Home?asdfanyquery
    条件将属于默认路由。即id,另一个id为null。 试试下面这个

    [RoutePrefix("api/Home")]
        public class HomeController : ApiController
        {
            [HttpGet]
            [Route("{id=id}/{AnotherId=AnotherId}")]
            public bool GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null)
            {
    
                return true;
            }
        }
    
  • api/Home?asdfanyquery
    api/Home
    -id和
    另一个id
    均为空)
  • api/Home?id=1
    (仅
    另一个id
    为空)
  • api/Home?AnotherId=1
    (仅
    Id
    为空)

  • 您所说的
    api/Home?asdfanyquery
    条件将属于默认路径。即id,另一个id为null。 试试下面这个

    [RoutePrefix("api/Home")]
        public class HomeController : ApiController
        {
            [HttpGet]
            [Route("{id=id}/{AnotherId=AnotherId}")]
            public bool GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null)
            {
    
                return true;
            }
        }
    
  • api/Home?asdfanyquery
    api/Home
    -id和
    另一个id
    均为空)
  • api/Home?id=1
    (仅
    另一个id
    为空)
  • api/Home?AnotherId=1
    (仅
    Id
    为空)
  • 我最终按照评论中的建议进行了应用:

    public class InvalidQueryStringRejector : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var arguments = actionContext.ActionArguments.Keys;
    
            var queryString = actionContext.Request.GetQueryNameValuePairs()
                .Select(q => q.Key);
    
            var invalidParams = queryString.Where(k => !arguments.Contains(k));
    
            if (invalidParams.Any())
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    message = "Invalid query string parameters",
                    parameters = invalidParams
                });
            }
        }
    }
    
    
    [RoutePrefix("api/Home")]
    public class HomeController : ApiController
    {
         [InvalidQueryStringRejector] //The custom created ActionFilterAttribute
         [HttpGet]
         [Route("")]
         public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null)
         {
             if (!ModelState.IsValid) //From ApiController.ModelState
             {
                  return BadRequest(ModelState);
             }
         }
    } 
    
    我最终按照评论中的建议进行了应用:

    public class InvalidQueryStringRejector : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var arguments = actionContext.ActionArguments.Keys;
    
            var queryString = actionContext.Request.GetQueryNameValuePairs()
                .Select(q => q.Key);
    
            var invalidParams = queryString.Where(k => !arguments.Contains(k));
    
            if (invalidParams.Any())
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, new
                {
                    message = "Invalid query string parameters",
                    parameters = invalidParams
                });
            }
        }
    }
    
    
    [RoutePrefix("api/Home")]
    public class HomeController : ApiController
    {
         [InvalidQueryStringRejector] //The custom created ActionFilterAttribute
         [HttpGet]
         [Route("")]
         public IHttpActionResult GetByIdAndAnotherID([FromUri]int? id = null, [FromUri]int? AnotherId = null)
         {
             if (!ModelState.IsValid) //From ApiController.ModelState
             {
                  return BadRequest(ModelState);
             }
         }
    } 
    

    我认为您需要使用自定义的
    IActionFilter
    iasyncationfilter
    来执行类似操作。在
    OnActionExecuting
    中,检查是否存在其他查询字符串值,如果发现任何查询字符串值,则拒绝请求。我认为您需要使用自定义
    IActionFilter
    iasyncationfilter
    来执行类似操作。在
    OnActionExecuting
    中,检查是否存在其他查询字符串值,如果发现任何查询字符串值,则拒绝请求。我理解
    api/Home?asdfanyquery
    表示
    id
    AnotherId
    均为空。然而,我想要的是访问
    api/Home?asdfanyquery
    将返回
    错误
    无法识别的死记硬背
    或类似内容。我理解
    api/Home?asdfanyquery
    意味着
    id
    另一个id
    都为空。但是,我想要的是访问
    api/Home?asdfanyquery
    将返回
    错误
    无法识别的死记硬背
    或类似的内容。为了完整起见,是否可以包含
    InvalidQueryStringRejectorAttribute
    的代码?另外,仅供参考,当您使用该属性时,您可以只使用
    InvalidQueryStringRejector
    ,属性的
    后缀将自动推断。为了完整性,您是否可以包含
    InvalidQueryStringRejectorAttribute
    的代码?另外,仅供参考,当您使用该属性时,您只需使用
    InvalidQueryStringRejector
    ,即可自动推断
    属性的后缀。