WebApi 2.0路由与查询参数不匹配?

时间:2013-11-13 14:56:57

标签: c# asp.net-web-api asp.net-web-api-routing

我刚从AttributeRouting切换到WebApi 2.0 AttributeRouting,并且有一个控制器和动作定义如下:

public class InvitesController : ApiController
{
    [Route("~/api/invites/{email}")]
    [HttpGet]
    [ResponseType(typeof(string))]
    public IHttpActionResult InviteByEmail(string email)
    {
        return this.Ok(string.Empty);
    }
}

示例查询:

GET: http://localhost/api/invites/test@foo.com

我收到的回复是200,内容为空(由于string.Empty)。


一切正常 - 但我想将email属性更改为查询参数。所以我将控制器更新为:

public class InvitesController : ApiController
{
    [Route("~/api/invites")]
    [HttpGet]
    [ResponseType(typeof(string))]
    public IHttpActionResult InviteByEmail(string email)
    {
        return this.Ok(string.Empty);
    }
}

但是现在用以下方式查询端点时:

GET: http://localhost/api/invites?email=test@foo.com

我收到的回复是404:

{
"message": "No HTTP resource was found that matches the request URI 'http://localhost/api/invites?email=test@foo.com'.",
"messageDetail": "No route providing a controller name was found to match request URI 'http://localhost/api/invites?email=test@foo.com'"
}

有人知道为什么它与参数交换到查询参数时的路线不匹配,而不是内联网址?


根据要求,WebApiConfig的定义如下:

public static void Register(HttpConfiguration config)
{
    var jsonFormatter = config.Formatters.JsonFormatter;
    jsonFormatter.Indent = true;
    jsonFormatter.SerializerSettings.ContractResolver = new RemoveExternalContractResolver();

    config.MapHttpAttributeRoutes();
}

谢谢!

3 个答案:

答案 0 :(得分:6)

我认为您需要在Route中包含查询参数(及其类型),如下所示:

[Route("api/invites/{email:string}")]

使用它将

POST: http://localhost/api/invites/test@foo.com

或者,如果要命名查询参数:

[Route("api/invites")]

使用它(只要你的方法中有一个电子邮件参数)

POST: http://localhost/api/invites?email=test@foo.com

当你在edhedges中评论时回答:路线模板不能以'/'或'〜'开头,所以你可以按照上面的路线删除

答案 1 :(得分:3)

问题是路由定义的冲突,由于是跨控制器(以及一些路由是'绝对'(~/))而未被注意到。下面是一个重现结果的例子。

public class ValuesController : ApiController
{
    [Route("~/api/values")]
    [HttpGet]
    public IHttpActionResult First(string email)
    {
        return this.Ok("first");
    }
}

[RoutePrefix("api/values")]
public class ValuesTwoController : ApiController
{
    [Route("")]
    [HttpGet]
    public IHttpActionResult Second(string email)
    {
        return this.Ok("second");
    }
}

发出请求:

GET: http://localhost/api/values?email=foo

将返回404,回复为:

{
    "message": "No HTTP resource was found that matches the request URI 'http://localhost/api/values?email=foo'.",
    "messageDetail": "No route providing a controller name was found to match request URI 'http://localhost/api/values?email=foo'"
}

什么是误导性的响应消息。

答案 2 :(得分:2)

我认为您需要将路线声明更改为:[Route("~/api/invites?{email}")]

以下是相关链接:http://attributerouting.net/#route-constraints