0

I have a controller where I am trying to post the following with a query string

http://localhost:53546/api/v1/projects?id=ABA28A61-8898-4739-8464-386C7890E435

but that doesn't hit the controller POST method

This however does

http://localhost:53546/api/v1/projects/ABA28A61-8898-4739-8464-386C7890E435

How can I accept a query string in a post? I keep getting a 504 error : Method not supported. Is there some special syntax to accept query strings in asp.net web api?

Here is my controller

[RoutePrefix("api/v1/projects")]
public class ProjectController : ApiController
{
    private RestClient client;

    public ProjectController() {
        client = new RestClient("http://localhost:53546");
    }

    [HttpPost]
    [Route("{id:guid}")]
    public string Post(Guid id)
    {
        return "Here is your Post id - " + id.ToString();
    }
}

Here is my DoPost method

public JToken DoRequest(string path, string method, params string[] parameters)
{
    if (!path.StartsWith("/"))
    {
        path = "/" + path;
    }
    var fullUrl = url + path + ToQueryString(parameters);

    if (DebugUrls) Console.WriteLine("Requesting: {0}", fullUrl);

    var request = WebRequest.Create(new Uri(fullUrl));
    request.Method = method;
    request.ContentType = "application/json";
    request.ContentLength = 0;
    var response = request.GetResponseAsync().Result;
    using (var responseStream = response.GetResponseStream())
    {
        return ReadResponse(responseStream);
    }
}

This is my route config if it matters

    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
Train
  • 3,420
  • 2
  • 29
  • 59
  • 2
    Your URL doesn't match any route. Why would you expect it to work? – SLaks Oct 31 '17 at 21:33
  • @SLaks How can I match a route to the query string above? – Train Oct 31 '17 at 21:39
  • 2
    `routeTemplate: "api/{controller}/{id}",` already defines that `id` is the default parameter in the route, hence that's why it works when **id=** query string argument is omitted from the URL. – Jeremy Thompson Oct 31 '17 at 21:39

2 Answers2

1

Query strings are not part of the route.

Therefore, you need to add [Route("")] to add an additional route that adds nothing to the controller's prefix.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • according to https://stackoverflow.com/questions/22642874/query-string-not-working-while-using-attribute-routing this doesn't work if it's marked on multiple methods – Train Oct 31 '17 at 21:57
1

As previously mentioned you have defined id as part of your default route. This means that when an API controller has a method accepting id as an argument, the routing engine is going to expect to find it in the uri and not from a query string.

In your POST example above, if you changed the argument name from id to postId and changed id to postId in your DoRequest code then it should work.

Another option would be to remove the {id} from your routeTemplate and remove the default value for id as well.

Chris Sainty
  • 7,861
  • 2
  • 37
  • 59