Najbardziej podstawowa wersja odpowiadająca za pomocą JsonResult
to:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
Jednak to nie pomoże w rozwiązaniu problemu, ponieważ nie możesz jawnie zająć się własnym kodem odpowiedzi.
Aby uzyskać kontrolę nad wynikami statusu, musisz zwrócić a, w ActionResult
którym możesz następnie skorzystać z tego StatusCodeResult
typu.
na przykład:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
Zauważ, że oba powyższe przykłady pochodzą ze świetnego przewodnika dostępnego w Microsoft Documentation: Formatting Response Data
Dodatkowe rzeczy
Problem, z którym często się spotykam, polega na tym, że chciałem mieć bardziej szczegółową kontrolę nad moim interfejsem WebAPI, a nie tylko korzystać z domyślnej konfiguracji z szablonu „Nowy projekt” w VS.
Upewnijmy się, że znasz podstawy ...
Krok 1: Skonfiguruj usługę
Aby Twoje ASP.NET Core WebAPI odpowiadało za pomocą obiektu serializowanego JSON wraz z pełną kontrolą nad kodem stanu, należy zacząć od upewnienia się, że AddMvc()
usługa została uwzględniona w ConfigureServices
metodzie zwykle znajdującej się w Startup.cs
.
Ważne jest, aby pamiętać, że AddMvc()
automatycznie uwzględni on formatowanie danych wejściowych / wyjściowych dla formatu JSON wraz z odpowiadaniem na inne typy żądań.
Jeśli Twój projekt wymaga pełnej kontroli i chcesz ściśle zdefiniować swoje usługi, na przykład sposób, w jaki Twoje WebAPI będzie zachowywać się w przypadku różnych typów żądań, w tym application/json
i nie odpowiadać na inne typy żądań (takie jak standardowe żądania przeglądarki), możesz zdefiniować je ręcznie za pomocą następujący kod:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
Zauważysz, że zamieściłem również sposób dodawania własnych niestandardowych elementów formatujących wejścia / wyjścia, na wypadek, gdybyś chciał odpowiedzieć na inny format serializacji (protobuf, oszczędność itp.).
Fragment powyższego kodu jest w większości duplikatem AddMvc()
metody. Jednak każdą usługę „domyślną” wdrażamy samodzielnie, definiując każdą usługę, zamiast korzystać z usługi wstępnie dostarczonej z szablonem. Dodałem link do repozytorium w bloku kodu lub możesz wyewidencjonować AddMvc()
z repozytorium GitHub. .
Zwróć uwagę, że istnieje kilka poradników, które spróbują rozwiązać ten problem przez „cofanie” wartości domyślnych, zamiast po prostu ich nie implementować w pierwszej kolejności… Jeśli weźmiesz pod uwagę fakt, że pracujemy teraz z Open Source, jest to praca zbędna , zły kod i szczerze mówiąc stary nawyk, który wkrótce zniknie.
Krok 2: Utwórz kontroler
Pokażę ci naprawdę proste, żeby uporządkować twoje pytanie.
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
Krok 3: Sprawdź Content-Type
iAccept
Musisz upewnić się, że Twoje Content-Type
i Accept
nagłówki w żądaniu są ustawione poprawnie. W twoim przypadku (JSON), będziesz chciał ustawić to na application/json
.
Jeśli chcesz, aby Twoje WebAPI odpowiadało domyślnie jako JSON, niezależnie od tego, co określa nagłówek żądania, możesz to zrobić na kilka sposobów .
Sposób 1
Jak pokazano w artykule, który zaleciłem wcześniej ( Formatowanie danych odpowiedzi ), możesz wymusić określony format na poziomie kontrolera / akcji. Osobiście nie podoba mi się to podejście ... ale tutaj chodzi o kompletność:
Wymuszanie określonego formatu Jeśli chcesz ograniczyć formaty odpowiedzi dla określonej akcji, możesz zastosować filtr [Produces]. Filtr [Produces] określa formaty odpowiedzi dla określonej akcji (lub kontrolera). Podobnie jak większość filtrów, można to zastosować w działaniu, kontrolerze lub zasięgu globalnym.
[Produces("application/json")]
public class AuthorsController
[Produces]
Filtr zmusi wszystkich działań w ramach
AuthorsController
powrócić JSON-sformatowanych odpowiedzi, nawet jeśli inne formatujących zostały skonfigurowane dla aplikacji, a klient dostarczył Accept
nagłówek żąda innego, dostępnego formatu.
Sposób 2
Moją preferowaną metodą jest odpowiadanie przez WebAPI na wszystkie żądania w żądanym formacie. Jednak w przypadku, gdy nie akceptuje żądanego formatu, wróć do domyślnego (tj. JSON)
Najpierw musisz to zarejestrować w opcjach (musimy przerobić domyślne zachowanie, jak wspomniano wcześniej)
options.RespectBrowserAcceptHeader = true; // false by default
Wreszcie, po prostu zmieniając kolejność na liście elementów formatujących, które zostały zdefiniowane w narzędziu do tworzenia usług, host sieciowy domyślnie ustawi program formatujący, który umieścisz na górze listy (tj. Pozycja 0).
Więcej informacji można znaleźć w tym wpisie blogu .NET Web Development and Tools
CreatedAtRoute
metody itp.