2013-08-27 6 views
5

Mam problem z wywołaniem ajax wywołując go w mojej metodzie web.api. Jeśli usunę Guid orderId zarówno z api, jak i js, wywołanie spowoduje przejście do kontrolera, ale obiekt pizzy jest pusty. Jeśli przekażę Guid w adresie URL, przejdzie on również do kontrolera, ale bez pizzy. Wyjaśnij, dlaczego to nie działa lub pomóż mi to zrobić.Web Api wywołuje błąd 404 z identyfikatorem GUID przekazanym jako parametr

JS: API

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:

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

JS Przedmioty:

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# obiektów:

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 Skrzypek post Przechwytywanie:

enter image description here enter image description here

Odpowiedz

9

ASP.NET Web API, domyślnie wiąże żądania ciało typu złożonego (pizzeria, w Twoim przypadku). Interfejs API sieci Web łączy parametr w całości: do jeden parametr:. Typy proste, takie jak GUID, są powiązane ze ścieżką URI i ciągiem zapytania. Tak więc, przekazując identyfikator GUID w URI i publikując tylko JSON odpowiadający obiektowi pizzy (tylko pizza, a nie cokolwiek innego, jak np. Identyfikator zamówienia), można uzyskać to działa.

+0

Więc zasadniczo web.api nie jest dla mnie. Mam metody, w których muszę przekazać wiele obiektów. Na przykład obiekty Pizza, zamówienie i rozmiar. I próbowałem przekazać Guidowi w ścieżce URI i Pizza w Danych, i udało mi się dostać do kontrolera, ale obiekt Pizza był pusty. – Boone

+0

Nie, web API jest dla każdego. Jestem pewien, że twoje potrzeby mogą zostać zaspokojone. Musisz tylko zrozumieć zasady i grać przez nich! Czy publikujesz 'dane: ko.toJSON ({pizza: pizza})'? Jeśli tak, powinieneś wypróbować 'data: ko.toJSON (pizza)'. – Badri

+0

Robię dane: ko.toJSON (pizza). Spędziłem 3 sekundy i użyłem zwykłego kontrolera z tym samym kodem i zadziałało idealnie. Po prostu zawsze czuję, że muszę robić obejścia tylko po to, żeby to działało. – Boone

1

Z mojego doświadczenia WEB API 2 HttpPost robi nie praca jeśli próbuję umieścić Guid w zbiorze parametrów. Muszę umieścić Guid w URI, np.

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

A potem ApiController jak ten

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

Niektórzy sugerują, że to będzie działać, aby użyć obiektu JSON dla Guid który ma pusty klucz, na przykład {'':OrderId} ale nie dla mnie. I nie ma sensu deklarować parametru Guid jako opcjonalnego lub zerowego w kontrolerze. Nie testowałem rozwiązania @ Badri, ale myślę, że to zadziała. Wiem, że WEB API będzie działać, jeśli zrobię C# DTO, który zawiera zarówno Pizza i OrderIdGuid i POST, np.

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

i

[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 
    })