0

I have a Durandal/Hot Towel test app I'm trying to wire up. I have the below ajax call but I'm getting a 404 error.

GET http/.../api/Pizza/GetPizzasByOrderId?%22a8926610-a713-494c-bb15-46f6487a01c7%22 404 (Not Found)

I can manually change the url to:

http/.../api/GetPizzasByOrderId?orderId=a8926610-a713-494c-bb15-46f6487a01c7

It works. But I would like to know why the other call isn't working or more so, why is the ajax messing the parameter up in the URL and not as data like it does with complex objects. I have a get and a save that is working just fine. The get has zero params and the save is passing a complex object in.

C# Web Api Controller:

public class PizzaController : ApiController
{
    [HttpGet]
    public IEnumerable<Pizza> GetPizzasByOrderId(Guid orderId)
    {
        return DATA.GetPizzasByOrderId(orderId);
    }
}

JAVASCRIPT:

var dataCall = $.ajax(config.getPizzasByOrderIdUrl, {
    data: ko.toJSON(orderId),
    type: "get",
    contentType: "application/json"
});

Should I just change my JavaScript code to the below and be done with it or is there a better way to talk to the Api?

var getPizzasByOrderId = function (orderId) {
    return Q.when($.getJSON(config.getPizzasByOrderIdUrl + "?orderId=" + orderId));
};

1 Answer 1

1

You could either use the code as you have it in that last code block, or you could pass in an object in place of your orderId as in the code block below. Either way, the difference is that the orderId parameter is being named.

var dataCall = $.ajax({
  url: config.getPizzasByOrderIdUrl,
  type: "GET",
  data: {orderId : orderId},
});

In regard to why $.ajax() works fine for your POST, you can check this out pretty easily by running these two bits of code and viewing the requests that go across the wire. I recommend using google chrome.

  1. Load a page that has jQuery loaded
  2. Open the developer tools and go to the console
  3. Enter the following code snippet

    $.ajax("", { data: {orderId: 123}, type: "get", contentType: "application/json" });

  4. Switch to the network tab and click on the one that ends in ?orderId=123

  5. Notice that it does have the data appended as query string parameters
  6. In the snippet above, replace the "get" with "post"
  7. After you hit enter, you should see another request on the network tab of the developer tools.
  8. Notice that when changing nothing but the request type, the data is moved from the query string to the body. As noted in the comments, WebApi will pull from the body of the request and use the model binder to populate the complex object.
Sign up to request clarification or add additional context in comments.

5 Comments

This is correct. ASP.NET WebApi selects the controller action based on the HTTP verb, the named parameters, and their data type. Get either of these wrong and it will return a 404.
Your code block does not work. It tries putting quotes around the orderId and throws a 400 error. There's no point in putting the toJson around a single parameter.
Here's what is confusing to me though. I know if I specify the paramaters like you have above (with out the toJson part) it works. But if you look at this answer. stackoverflow.com/questions/14507101/… ...Why don't I have to put the parameter in that one?? It looks like Web.Api behaves differently when it is just a single param instead of a complex object?
Yes, WebApi behaves differently based on the three things I said in my comment above. On a GET request, WebApi assumes, by default, that your parameters are located in the URI, especially if your parameters are value types (string, int, etc.). If your parameter is an object, WebApi expects it to be in the body of the request, unless you decorate the parameter with [FromUri] in your controller. The other parameter decorator is [FromBody] which tells WebApi to look for the parameter in the request body.
Yes, sorry, that shouldn't have a ko.toJSON(). I'll edit that out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.