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

时间:2017-11-16 01:27:01

标签: 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.IsValid) //From ApiController.ModelState
        {
            return BadRequest(ModelState);
        }
    }
}

我只想匹配以下3个网址:

  1. api/HomeidAnotherId都为空)
  2. api/Home?id=1(只有Anotherid为空)
  3. api/Home?AnotherId=1(只有Id为空)
  4. 其他网址应返回unregistered routeserror。目前,api/Home?asdfanyquery也会返回不符合我要求的匹配项。

    如何重写控制器以使路线只匹配上面的3个网址?

2 个答案:

答案 0 :(得分:0)

您说api/Home?asdfanyquery的条件将属于默认路由。这是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;
        }
    }
  1. api/Home?asdfanyqueryapi/Home - idAnotherId都为空)
  2. api/Home?id=1(只有Anotherid为空)
  3. api/Home?AnotherId=1(只有Id为空)

答案 1 :(得分:0)

我按照评论中的建议结束了creating an ActionFilterAttribute,并将其应用如下:

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);
         }
     }
}