-1

I have the following URL:

http://localhost/api/values/100/some+string+here

In the WebAPI app ValuesController, I have this:

[HttpGet]
[Route("api/values/{p1}/{p2}")]
public HttpResponseMessage Get (string p1, string p2) {
...
}

For the caller, it never hits the web api. Instead, it comes back with a 404.

Any idea what is wrong?

4thSpace
  • 43,672
  • 97
  • 296
  • 475
  • It might have something to do with `values`. Try replacing this with the proper cased controller name like `Home` (if your ApiController was named `HomeController`). – Igor Jun 16 '16 at 17:06
  • might be worth checking this out http://stackoverflow.com/questions/12835074/mvc4-web-api-rest-interface-with-multiple-parameters – terbubbs Jun 16 '16 at 17:10
  • 1
    I can't duplicate your problem. I have tried using latest version of Web-API 2.2. I used various Web API controller names and your exact same URI and method that you posted, it gets hit with the values every time. Things to check. Make sure the class that you have defined is inheriting from `ApiController` (and not Controller). Post the default routing config in the webapiconfig.cs. Make sure your WebApiConfig.cs is being initialized at startup. – Igor Jun 16 '16 at 17:15
  • 1
    @Igor URL routes aren't case-sensitive, so I doubt that's the issue. – Spivonious Jun 16 '16 at 17:16
  • @Spivonious - I came to that conclusion as well after testing it but forgot to mention that in my last comment. – Igor Jun 16 '16 at 17:16
  • @Igor - no problem! – Spivonious Jun 16 '16 at 17:17
  • @4thSpace - could it be that the binding engine is sucking up the entire "100/some-string-here" for the first parameter? Try adding a method that just takes one string and see if it gets hit. – Spivonious Jun 16 '16 at 17:19
  • 1
    That may be a stupid question but you're returning HttpResponseMessage. Are you sure that the api is never hit? Have you checked that you method is not doing something like this: return new HttpResponseMessage(HttpStatusCode.NotFound); – derloopkat Jun 16 '16 at 17:26
  • Sorry - I had the URL wrong. It is "+" instead of "-". That is due to url encoding. – 4thSpace Jun 16 '16 at 17:31
  • Possible duplicate of [MVC WEB API routing fails when url contains encoded ampersand](http://stackoverflow.com/questions/14359305/mvc-web-api-routing-fails-when-url-contains-encoded-ampersand) – Igor Jun 16 '16 at 17:43

1 Answers1

1

You are using Attribute Routing in ASP.NET Web API 2. Make sure you configure your web api to use Attribute routing with MapHttpAttributeRoutes.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

        // Convention-based routing.
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Next make sure you defined your controller properly

public class ValuesController : ApiController {
    //GET api/values/100/some-string-here
    [HttpGet]
    [Route("api/values/{p1}/{p2}")]
    public HttpResponseMessage Get (string p1, string p2) {
    ...
    }
}

You could even use RoutePrefix

[RoutePrefix("api/values")]
public class ValuesController : ApiController {
    //GET api/values/100/some-string-here
    [HttpGet]
    [Route("{p1}/{p2}")]
    public HttpResponseMessage Get (string p1, string p2) {
    ...
    }
}

Also if like in your example you want the first parameter to be an integer. then you can use a route constraint and update method.

[RoutePrefix("api/values")]
public class ValuesController : ApiController {
    //GET api/values/100/some-string-here
    [HttpGet]
    [Route("{p1:int}/{p2}")]
    public HttpResponseMessage Get (int p1, string p2) {
    ...
    }
}

UPDATE:

Created an integration test for the Values Controller and was able to confirm that the action was called

[TestMethod]
public async Task HttpClient_Should_Get_OKStatus_From_Action_With_Multiple_Parameters() {
    var config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();

    using (var server = new HttpServer(config)) {

        var client = new HttpClient(server);

        string url = "http://localhost/api/values/100/some+string+here";

        using (var response = await client.GetAsync(url)) {
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
        }
    }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472