Boone
Boone

Reputation: 1056

Web Api call is returning a 404 error with GUID passed as param

I am having troubles with my ajax call making it to my web.api method. If I remove the Guid orderId from both the api and the js, the call makes it to the controller, but the pizza object is empty. If I pass the Guid in the URL, it also makes it to the controller but no pizza. Please explain why this doesn't work or help me make it work.

JS:

var savePizza = function (orderId, pizza) {
    var dataCall = $.ajax(config.savePizzaUrl, {
        data: ko.toJSON({ orderId: orderId, pizza: pizza }),
        type: "post",
        contentType: "application/json"
    });

    return Q.when(dataCall);
};

Web Api:

    [HttpPost]
    public RequestReturn<Guid> SavePizza(Guid orderId, Pizza pizza)
    {
        return PizzaRequests.SavePizza(orderId, pizza);
    }

JS Objects:

var pizza = function (data) {
    this.Id = data.Id;
    this.Size = new size(data.Size);
    this.SizeId = data.SizeId;
    this.Toppings = $.map(data.Toppings, function(item) {return new topping(item);});
};
var topping = function (data) {
    this.Id = data.Id;
    this.Name = data.Name;
    this.Price = data.Price;
};
var size = function (data) {
    this.Id = data.Id;
    this.Name = data.Name;
    this.Price = data.Price;
};

C# Objects:

public class Pizza
{
    public Guid Id { get; set; }
    public Guid SizeId { get; set; }
    public Size Size { get; set; }
    public IEnumerable<Topping> Toppings { get; set; }
}
public class Size
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
}
public class Topping
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
}

JSON Fiddler Post Capture:

enter image description here enter image description here

Upvotes: 5

Views: 5498

Answers (2)

subsci
subsci

Reputation: 1740

In my experience the WEB API 2 HttpPost does not work if I try to put a Guid in the parameter collection. I have to put the Guid into the URI, e.g.

  var url = window.applicationBaseUrl + "aiapps/"  
             + GuidOrderId + "/DeleteByGroupId";

And then the ApiController like this

    [HttpPost]
    [Route("~/aiapps/{guid:Guid}/deletebygroupid")]
    public AiAppsOpResult DeleteByGroupId(Guid guid)
    {         

Some have suggested that it will work to use a JSON object for the Guid that has an empty key, e.g. {'':OrderId} but not for me. And it does no good to declare the Guid parameter optional or nullable in the controller. I have not tested @Badri's solution, but I think it will work. I do know the WEB API will work if I make a C# DTO that contains both the Pizza and the OrderIdGuid and POST that, e.g.

    public class MetaPizza 
    {
         public Pizza pizza {get;set;} 
         public Guid OrderId{get;set;}
    }

and

    [Route("~/api/postorder")]
    [HttpPost]
    public AiAppsOpResult CalcRisk(MetaPizza metaPizza)



$.ajax({
        type: "POST",
        dataType: "json",
        contentType: "application/json",
        url: window.applicationBaseUrl + "api/postorder" ,
        data: _JSON_MetaPizza
    })

Upvotes: 1

ASP.NET Web API, by default, binds request body to a complex type (Pizza, in your case). Web API binds the body in its entirety to one parameter. Simple types such as GUID are bound from the URI path and query string. So, by passing GUID in the URI and posting only the JSON corresponding to pizza object (only the pizza and not anything else such as order ID), you can get this working.

Upvotes: 9

Related Questions