Jeg leter etter den riktige måten å returnere JSON med en HTTP-statuskode i .NET Core Web API-kontrolleren min. Jeg bruker å bruke det slik:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
Dette var i en 4.6 MVC-applikasjon, men nå med .NET Core ser jeg ikke ut til å ha dette IHttpActionResult
Jeg har ActionResult
og bruker slik:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
Men svaret fra serveren er rart, som i bildet nedenfor:
![skriv inn bildebeskrivelse her]]1
Jeg vil bare at Web API-kontrolleren skal returnere JSON med en HTTP-statuskode som jeg gjorde i Web API 2.
Den mest grunnleggende versjonen som svarer med et JsonResult
er:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
Dette kommer imidlertid ikke til å hjelpe med problemet ditt fordi du ikke eksplisitt kan håndtere din egen responskode.
Måten å få kontroll over statusresultatene, er at du må returnere en
ActionResult
som er der du kan dra nytte avStatusCodeResult
-typen.
for eksempel:
// 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);
}
Merk at begge eksemplene ovenfor er hentet fra en flott veiledning som er tilgjengelig fra Microsoft Documentation: Formatering av svardata
Problemet jeg støter på ganske ofte er at jeg ønsket mer detaljert kontroll over WebAPI-en min i stedet for bare å gå med standardkonfigurasjonen fra "Nytt prosjekt" -malen i VS.
La' s sørge for at du har noen av de grunnleggende ned ...
For å få ASP.NET Core WebAPI til å svare med et JSON Serialized Object sammen med full kontroll over statuskoden, bør du starte med å sørge for at du har inkludert AddMvc()
-tjenesten i ConfigureServices
-metoden som vanligvis finnes i Startup.cs
.
Det er viktig å merke seg at AddMvc()
automatisk vil inkludere Input/Output Formatter for JSON sammen med å svare på andre typer forespørsler.
Hvis prosjektet ditt krever full kontroll og du ønsker å definere tjenestene dine strengt, for eksempel hvordan WebAPI-en din skal oppføre seg på forskjellige typer forespørsler, inkludert application/json
og ikke svare på andre typer forespørsler (for eksempel en standard nettleserforespørsel), kan du definere det manuelt med følgende kode:
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)
}
Du vil legge merke til at jeg også har inkludert en måte for deg å legge til dine egne tilpassede input / output-formater, i tilfelle du kanskje vil svare på et annet serialiseringsformat (protobuf, sparsommelighet osv.).
Kodebiten ovenfor er for det meste en kopi av AddMvc()
-metoden. Imidlertid implementerer vi hver "standard" -tjeneste på egen hånd ved å definere hver eneste tjeneste i stedet for å gå med den forhåndsleverte med malen. Jeg har lagt til depotlenken i kodeblokken, eller du kan sjekke ut AddMvc()
fra GitHub-depotet..
*Merk at det er noen guider som vil prøve å løse dette ved å "angre" standardinnstillingene, i stedet for bare å ikke implementere det i utgangspunktet ... Hvis du tar i betraktning at vi nå jobber med åpen kildekode, er dette overflødig arbeid, dårlig kode og ærlig talt en gammel vane som snart vil forsvinne.
Jeg skal vise deg en veldig grei en bare for å få sortert spørsmålet ditt.
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();
}
}
Du må sørge for at overskriftene Content-Type
og Accept
i forespørselen er riktig angitt. I ditt tilfelle (JSON) må du sette den opp til å være application/json
.
Hvis du vil at WebAPI-en din skal svare som JSON som standard, uavhengig av hva forespørselshodet spesifiserer, kan du gjøre det på et par måter.
Måte 1 Som vist i artikkelen jeg anbefalte tidligere (Formatering av svardata) kan du tvinge et bestemt format på Controller / Action-nivå. Personlig liker jeg ikke denne tilnærmingen ... men her er den for fullstendighetens skyld:
Tvinge et bestemt format Hvis du ønsker å begrense svarformatene for en bestemt handling, kan du bruke filtreringen filteret [Produserer]. Filteret [Produserer] spesifiserer svarformatene for en bestemt handling. formater for en bestemt handling (eller kontrollør). Som de fleste filtre kan dette brukes på handlingen, kontrolleren eller det globale omfanget.
[Produserer("applikasjon/json")] offentlig klasse AuthorsController
[Produces]
-filteret vil tvinge alle handlinger innenforAuthorsController
til å returnere JSON-formaterte svar, selv om andre formattere ble konfigurert for applikasjonen og klienten har gitt enAccept
header som ber om et annet, tilgjengelig format.
Måte 2 Min foretrukne metode er at WebAPI svarer på alle forespørsler med det forespurte formatet. Men i tilfelle det ikke godtar det forespurte formatet, så fall-back til en standard (dvs. JSON).
Først må du registrere det i alternativene dine (vi må omarbeide standardoppførselen, som nevnt tidligere).
options.RespectBrowserAcceptHeader = true; // false by default
Til slutt, ved ganske enkelt å omorganisere listen over formaterere som ble definert i tjenestebyggeren, vil webverten som standard bruke formatereren du plasserer øverst på listen (dvs. posisjon 0).
Mer informasjon finner du i denne .NET Web Development and Tools Blog entry.
Du har forhåndsdefinerte metoder for de vanligste statuskodene.
Ok(result)
returnerer 200
med svar.CreatedAtRoute
returnerer 201
+ ny URL til ressursen.NotFound
returnerer 404
.BadRequest
returnerer 400
osv.Se BaseController.cs
og Controller.cs
for en liste over alle metodene.
Men hvis du virkelig insisterer, kan du bruke StatusCode
for å angi en egendefinert kode, men du bør egentlig ikke gjøre det da det gjør koden mindre lesbar og du må gjenta koden for å angi overskrifter (som for CreatedAtRoute
).
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
Se koden nedenfor, du kan administrere flere statuskoder med forskjellige typer JSON.
public async Task<HttpResponseMessage> GetAsync()
{
try
{
using (var entities = new DbEntities())
{
var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList();
if (resourceModelList.Count == 0)
{
return this.Request.CreateResponse<string>(HttpStatusCode.NotFound, "No resources found.");
}
return this.Request.CreateResponse<List<ResourceModel>>(HttpStatusCode.OK, resourceModelList, "application/json");
}
}
catch (Exception ex)
{
return this.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong.");
}
}