问题
I've just switched from AttributeRouting to WebApi 2.0 AttributeRouting, and have got a controller and action defined like so:
public class InvitesController : ApiController
{
[Route("~/api/invites/{email}")]
[HttpGet]
[ResponseType(typeof(string))]
public IHttpActionResult InviteByEmail(string email)
{
return this.Ok(string.Empty);
}
}
Example query:
GET: http://localhost/api/invites/test@foo.com
The response I receive is a 200, with empty content (due to string.Empty).
This all works fine -- but I want to change the email property to be a query parameter instead . So I update the controller to:
public class InvitesController : ApiController
{
[Route("~/api/invites")]
[HttpGet]
[ResponseType(typeof(string))]
public IHttpActionResult InviteByEmail(string email)
{
return this.Ok(string.Empty);
}
}
But now when querying the endpoint with:
GET: http://localhost/api/invites?email=test@foo.com
The response I receive is a 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'"
}
Does anyone know why it doesn't match the route when the parameter is swapped to a query parameter, rather than inline of the url ?
As requested, WebApiConfig is defined like so:
public static void Register(HttpConfiguration config)
{
var jsonFormatter = config.Formatters.JsonFormatter;
jsonFormatter.Indent = true;
jsonFormatter.SerializerSettings.ContractResolver = new RemoveExternalContractResolver();
config.MapHttpAttributeRoutes();
}
Thanks !
回答1:
I think you need to include the query parameter (along with its type) in the Route as follows:
[Route("api/invites/{email:string}")]
using it will be
POST: http://localhost/api/invites/test@foo.com
Alternatively if you want to name the query parameter:
[Route("api/invites")]
using it will be (as long as you have an email parameter in your method)
POST: http://localhost/api/invites?email=test@foo.com
As you comment in edhedges answer: the route template cannot start with a '/' or a '~', so you can remove that from the route as above
回答2:
Issue is a clash of route definitions, which went unnoticed due to being cross-controller (and also some of the routes being 'absolute' (~/
)). Below is an example that reproduces the result.
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");
}
}
Issuing a request:
GET: http://localhost/api/values?email=foo
Will return a 404 with a response of:
{
"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'"
}
What is misleading is the response message.
回答3:
I think you need to change your Route declaration to this: [Route("~/api/invites?{email}")]
Here is a relevant link: http://attributerouting.net/#route-constraints
来源:https://stackoverflow.com/questions/19956974/webapi-2-0-routes-not-matching-with-query-parameters