Więcej
Jak przekazać dane json POST do metody Web API jako obiekt?
Aplikacja ASP.NET MVC4 Web API definiuje metodę post do zapisania klienta. Klient jest przekazywany w formacie json w treści żądania POST. Parametr Customer w metodzie post zawiera wartości null dla właściwości.
Jak to naprawić, aby dane były przekazywane jako obiekt klienta?
Jeśli to możliwe Content-Type: application/x-www-form-urlencoded powinien być użyty, ponieważ nie wiem jak to zmienić w metodzie javascript, która wysyła formularz.
Kontroler:
public class CustomersController : ApiController {
public object Post([FromBody] Customer customer)
{
return Request.CreateResponse(HttpStatusCode.OK,
new
{
customer = customer
});
}
}
}
public class Customer
{
public string company_name { get; set; }
public string contact_name { get; set; }
}
Żądanie:
POST http://localhost:52216/api/customers HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
{"contact_name":"sdfsd","company_name":"ssssd"}
292
3
EDIT : 31/10/2017
Ten sam kod / podejście będzie działać dla Asp.Net Core 2.0 również. Główną różnicą jest, W asp.net core, zarówno kontrolery web api, jak i kontrolery Mvc są łączone razem w pojedynczy model kontrolera. Więc twój typ zwrotu może być
IActionResult
lub jedną z jego'implementacji (Ex :OkObjectResult
).Użyj
Musisz użyć metody
JSON.stringify
, aby przekonwertować go na ciąg JSON, kiedy go wyślesz,A model binder powiąże dane json z obiektem twojej klasy.
Poniższy kod będzie działał dobrze (przetestowany)
Wynik
Właściwość
contentType
mówi serwerowi, że wysyłamy dane w formacie JSON. Ponieważ wysłaliśmy strukturę danych JSON, wiązanie modelu odbędzie się poprawnie.Jeśli sprawdzisz nagłówki żądania ajax's, możesz zobaczyć, że wartość
Content-Type
jest ustawiona jakoapplication/json
.Jeśli nie określisz contentType, zostanie użyty domyślny typ zawartości, który jest
application/x-www-form-urlencoded;
.Edyt z listopada 2015, aby rozwiązać inne możliwe problemy poruszone w komentarzach
Wysyłanie obiektu złożonego
Let's say you have a complex view model class as your web api action method parameter like this
a twój punkt końcowy web api jest jak
*W czasie pisania tego tekstu, ASP.NET MVC 6 jest najnowszą stabilną wersją i w MVC6, zarówno kontrolery Web api jak i kontrolery MVC dziedziczą z klasy bazowej
Microsoft.AspNet.Mvc.Controller
.Aby wysłać dane do metody od strony klienta, poniższy kod powinien działać dobrze
Wiązanie modelu działa dla niektórych właściwości, ale nie dla wszystkich ! Dlaczego ?
Jeśli nie udekorujesz parametru metody web api atrybutem
[FromBody]
.I wyślesz model (surowy obiekt javascript, nie w formacie JSON) bez określania wartości właściwości contentType
Wiązanie modelu będzie działać dla płaskich właściwości na modelu, a nie właściwości, gdzie typ jest złożony/innego typu. W naszym przypadku, właściwości
Id
iName
będą poprawnie powiązane z parametremm
, ale właściwośćTags
będzie pustą listą.Ten sam problem wystąpi jeśli używasz krótkiej wersji,
$.post
, która użyje domyślnego Content-Type podczas wysyłania żądania.Praca z POST w webapi może być trudna! Chciałbym dodać do już poprawnej odpowiedzi...
Skupię się szczególnie na POST, ponieważ radzenie sobie z GET jest banalne. Nie sądzę, aby wielu szukało rozwiązania problemu z GET za pomocą webapi. Tak czy inaczej...
Jeśli twoje pytanie brzmi - W MVC Web Api, jak - Użyj niestandardowych nazw metod działania innych niż ogólne czasowniki HTTP? - Wykonywać wiele postów? - Publikować wiele prostych typów? - Publikuj złożone typy za pomocą jQuery?
Następnie następujące rozwiązania mogą pomóc:
Po pierwsze, aby użyć Custom Action Methods w Web API, dodaj trasę web api jako:
A następnie możesz utworzyć metody akcji takie jak:
Teraz, z konsoli przeglądarki, odpal poniższe jQuery
Po drugie, aby wykonać wiele postów, Jest to proste, utwórz wiele metod akcji i udekoruj atrybutem [HttpPost]. Użyj [ActionName("MyAction")], aby przypisać niestandardowe nazwy itp. Przejdziemy do jQuery w czwartym punkcie poniżej
Po trzecie, Po pierwsze, delegowanie wielu SIMPLE typów w pojedynczej akcji nie jest możliwe. Co więcej, istnieje specjalny format, aby opublikować nawet pojedynczy prosty typ (poza przekazaniem parametru w łańcuchu zapytania lub w stylu REST). To był punkt, który kazał mi walić głową w Rest Clients (jak Fiddler i Chrome's Advanced REST client extension) i polować w sieci przez prawie 5 godzin, kiedy w końcu następujący adres URL okazał się pomocny. Zacytuje odpowiednią treść, ponieważ link może okazać się martwy!
PS: Zauważyłeś specyficzną składnię?
http://forums.asp.net/t/1883467.aspx?The+received+value+is+null+when+I+try+to+Post+to+my+Web+Api
Tak czy inaczej, skończmy z tą historią. Przechodząc dalej:
Po czwarte, postowanie typów złożonych za pomocą jQuery, oczywiście w roli tej szybko pojawi się $.ajax():
Powiedzmy, że metoda akcji przyjmuje obiekt Person, który ma id i nazwę. Tak więc, z javascript:
A akcja będzie wyglądała tak:
Wszystkie z powyższych, pracował dla mnie!!! Dzięki!
I've just been playing with this and discovered a rather strange result. Powiedzmy, że masz publiczne właściwości na swojej klasie w C#, takie jak to:
to musisz zrobić sztuczkę JSON.stringify, jak zasugerował Shyju i nazwać to w ten sposób:
Jednakże, jeśli zdefiniujesz gettery i setery na swojej klasie w ten sposób:
wtedy możesz nazwać to znacznie prościej:
Wykorzystuje to nagłówek HTTP:
Nie jestem do końca pewien, co się tutaj dzieje, ale wygląda to na błąd (cechę?) w frameworku. Przypuszczalnie różne metody wiązania wywołują różne "adaptery", i podczas gdy adapter dla application/json działa z publicznymi właściwościami, ten dla danych zakodowanych w formularzu nie.
Nie mam pojęcia, co byłoby uważane za najlepszą praktykę, chociaż.