Próbuję opublikować wiele parametrów na kontrolerze WebAPI. Jeden parametr pochodzi z adresu URL, a drugi z treści. Oto adres URL:
/offers/40D5E19D-0CD5-4FBD-92F8-43FDBB475333/prices/
Oto mój kod kontrolera:
public HttpResponseMessage Put(Guid offerId, OfferPriceParameters offerPriceParameters)
{
//What!?
var ser = new DataContractJsonSerializer(typeof(OfferPriceParameters));
HttpContext.Current.Request.InputStream.Position = 0;
var what = ser.ReadObject(HttpContext.Current.Request.InputStream);
return new HttpResponseMessage(HttpStatusCode.Created);
}
Treść treści jest w formacie JSON:
{
"Associations":
{
"list": [
{
"FromEntityId":"276774bb-9bd9-4bbd-a7e7-6ed3d69f196f",
"ToEntityId":"ed0d2616-f707-446b-9e40-b77b94fb7d2b",
"Types":
{
"list":[
{
"BillingCommitment":5,
"BillingCycle":5,
"Prices":
{
"list":[
{
"CurrencyId":"274d24c9-7d0b-40ea-a936-e800d74ead53",
"RecurringFee":4,
"SetupFee":5
}]
}
}]
}
}]
}
}
Masz jakiś pomysł, dlaczego domyślne powiązanie nie może połączyć się z offerPriceParameters
argumentem mojego kontrolera? Zawsze ma wartość null. Ale jestem w stanie odzyskać dane z ciała za pomocą DataContractJsonSerializer
.
Próbuję też użyć FromBody
atrybutu argumentu, ale to też nie działa.
.net
asp.net-web-api
Normand Bedard
źródło
źródło
Natywnie WebAPI nie obsługuje wiązania wielu parametrów POST. Jak podkreśla Colin, istnieje szereg ograniczeń, które zostały opisane w moim wpisie na blogu, do którego się odwołuje.
Istnieje obejście problemu, tworząc spinacz parametrów niestandardowych. Kod, który to robi, jest brzydki i zawiły, ale opublikowałem kod wraz ze szczegółowym wyjaśnieniem na moim blogu, gotowy do podłączenia do projektu tutaj:
Przekazywanie wielu prostych wartości POST do interfejsu API sieci Web ASP.NET
źródło
Jeśli używany jest routing atrybutów, możesz użyć atrybutów [FromUri] i [FromBody].
Przykład:
źródło
[FromRoute]
zamiast[FromUri]
Przekazaliśmy obiekt Json metodą HttpPost i przeanalizowaliśmy go w obiekcie dynamicznym. to działa dobrze. to jest przykładowy kod:
webapi:
Złożonym typem obiektu może być obiekt, tablica i słownik.
źródło
Do przekazania wielu parametrów w poście można użyć prostej klasy parametrów:
źródło
Możesz zezwolić na wiele parametrów POST przy użyciu klasy MultiPostParameterBinding z https://github.com/keith5000/MultiPostParameterBinding
Aby z niego skorzystać:
1) Pobierz kod w formacie folderze źródłowym i dodaj go do projektu interfejsu API sieci Web lub dowolnego innego projektu w rozwiązaniu.
2) Użyj atrybutu [MultiPostParameters] w metodach akcji, które muszą obsługiwać wiele parametrów POST.
3) Dodaj ten wiersz w Global.asax.cs do metody Application_Start w dowolnym miejscu przed wywołaniem GlobalConfiguration.Configure (WebApiConfig.Register) :
4) Poproś klientów o przekazanie parametrów jako właściwości obiektu. Przykładowy obiekt JSON dla
DoSomething(param1, param2, param3)
metody to:Przykład JQuery:
Odwiedzić łącze, aby uzyskać więcej informacji.
Zastrzeżenie: jestem bezpośrednio powiązany z połączonym zasobem.
źródło
Ładne pytanie i komentarze - wiele się nauczyłem z odpowiedzi tutaj :)
Jako dodatkowy przykład zwróć uwagę, że możesz również mieszać treść i trasy, np
Dzwonię w ten sposób:
źródło
Jak wygląda Twój szablon trasy w tym przypadku?
Opublikowałeś ten adres URL:
Aby to zadziałało, spodziewałbym się takiego routingu w Twoim
WebApiConfig
:Inne założenia to: - wywoływany jest kontroler
OffersController
. - obiekt JSON, który przekazujesz w treści żądania, jest typuOfferPriceParameters
(nie jest to żaden typ pochodny) - nie masz żadnych innych metod na kontrolerze, które mogłyby kolidować z tym (jeśli to zrobisz, spróbuj je skomentować i zobacz, co dzieje się)I jak wspomniał Filip, pomogłoby to, gdybyś zaczął akceptować niektóre odpowiedzi, ponieważ „wskaźnik akceptacji 0%” może sprawić, że ludzie pomyślą, że marnują czas
źródło
Jeśli nie chcesz iść drogą ModelBinding, możesz użyć DTO, aby zrobić to za Ciebie. Na przykład utwórz akcję POST w DataLayer, która akceptuje typ złożony i wysyła dane z BusinessLayer. Możesz to zrobić w przypadku wywołania UI-> API.
Oto przykładowe DTO. Przypisz nauczyciela do ucznia i przypisz wiele prac / przedmiotów do ucznia.
Następnie akcję w DataLayer można utworzyć jako:
Aby zadzwonić z BusinessLayer:
Teraz to nadal będzie działać, jeśli chcę wysłać dane wielu Studentów jednocześnie. Zmodyfikuj
MyAction
jak poniżej. Nie ma potrzeby pisania [FromBody], WebAPI2 przyjmuje domyślnie złożony typ [FromBody].a następnie podczas wywoływania go przekaż
List<StudentCurriculumDTO>
dane.źródło
Parametry żądania, takie jak
Kod interfejsu API sieci Web jest podobny
źródło
Możesz pobrać dane formularza jako ciąg:
https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2
źródło