Es meklēju pareizo veidu, kā atgriezt JSON ar HTTP statusa kodu savā .NET Core Web API kontrolierī. Es to izmantoju šādi:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
Tas bija 4.6 MVC lietojumprogrammā, bet tagad ar .NET Core man nav šī IHttpActionResult
, man ir ActionResult
un izmantoju šādi:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
Bet atbilde no servera ir dīvaina, kā attēlā zemāk:
Es tikai gribu, lai Web API kontrolieris atgrieztu JSON ar HTTP statusa kodu, kā es to darīju Web API 2.
Vienkāršākā versija, kas reaģē ar JsonResult
, ir:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
Tomēr tas nepalīdzēs atrisināt jūsu problēmu, jo jūs nevarat tieši rīkoties ar savu atbildes kodu.
Lai iegūtu kontroli pār statusa rezultātiem, jums ir jāatgriež
ActionResult
, kur jūs varat izmantotStatusCodeResult
tipa priekšrocības.
piemēram:
// 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);
}
Ņemiet vērā, ka abi šie piemēri ir ņemti no lieliskas rokasgrāmatas, kas pieejama Microsoft dokumentācijā: Atbildes datu formatēšana
Problēma, ar ko es bieži sastopos, ir tāda, ka es gribēju detalizētāk kontrolēt savu WebAPI, nevis vienkārši izmantot noklusējuma konfigurāciju no "New Project" šablona VS.
Pārliecināsimies, ka esat apguvis dažus pamatus...
Lai panāktu, ka jūsu ASP.NET Core WebAPI atbild ar JSON serializētu objektu un pilnībā kontrolētu statusa kodu, vispirms pārliecinieties, ka ConfigureServices
metodē, kas parasti atrodama Startup.cs
, ir iekļauts AddMvc()
pakalpojums.
Svarīgi atzīmēt, ka
AddMvc()
automātiski iekļaus JSON ieejas/izvades formatētāju, kā arī atbildēs uz citiem pieprasījumu tipiem.
Ja jūsu projektam nepieciešama pilnīga kontrole un vēlaties stingri definēt savus pakalpojumus, piemēram, kā jūsu WebAPI rīkosies ar dažādiem pieprasījumu tipiem, tostarp application/json
, un neatbildēs uz citiem pieprasījumu tipiem (piemēram, standarta pārlūkprogrammas pieprasījumu), varat to definēt manuāli, izmantojot šādu kodu:
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)
}
Jūs pamanīsiet, ka es esmu iekļāvis arī iespēju pievienot savus ieejas/izejas formatētājus gadījumam, ja vēlaties atbildēt uz citu serializācijas formātu (protobuf, thrift utt.).
Iepriekš minētā koda daļa lielākoties ir AddMvc()
metodes dublēšana. Tomēr mēs katru "noklusējuma" servisu ieviešam paši, definējot katru servisu, nevis izmantojam iepriekš piegādāto kopā ar šablonu. Es esmu pievienojis kodu blokā saiti uz repozitoriju, vai arī jūs varat apskatīt AddMvc()
no GitHub repozitorija.
Es parādīšu jums patiešām vienkāršu, lai atrisinātu jūsu jautājumu.
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();
}
}
Content-Type
un Accept
Jums jāpārliecinās, ka Content-Type
un Accept
galvenes jūsu pieprasījumā ir iestatītas pareizi. Jūsu gadījumā (JSON), jūs vēlaties, lai tas būtu application/json
.
Ja vēlaties, lai jūsu WebAPI pēc noklusējuma atbildētu kā JSON, neatkarīgi no tā, kas norādīts pieprasījuma galvenē, to var izdarīt** vairākos veidos.
1. veids Kā norādīts iepriekš ieteiktajā rakstā (Atbildes datu formatēšana), jūs varat uzspiest noteiktu formātu kontroliera/pasākuma līmenī. Man personīgi šī pieeja nepatīk... bet, lai būtu pilnība, šeit tas ir:
Ja vēlaties ierobežot atbildes formātus konkrētai darbībai, varat izmantot šo funkciju: > Noteikt konkrētu formātu.
[Ražo] filtru. Filtrs [Produces] norāda atbildes formātu. formātus konkrētai darbībai (vai kontrolierim). Tāpat kā lielākā daļa filtru, arī šis var piemērot darbības, kontroliera vai globālā mērogā.
[Produces("application/json")] public class AuthorsController
Filtrs
[Produces]
piespiedīs visas darbības, kas atrodas kontrollerīAuthorsController
atgriezt JSON formāta atbildes, pat ja citi formatētāji bija konfigurēti lietojumprogrammai un klients sniedzaAccept
galveni, pieprasot citu pieejamo formātu.
2. veids Man vēlamā metode ir tāda, ka WebAPI atbild uz visiem pieprasījumiem ar pieprasīto formātu. Tomēr gadījumā, ja pieprasītais formāts netiek pieņemts, tad atgriezties pie noklusējuma (t. i., JSON).
Vispirms jums tas būs jāreģistrē savās opcijās (mums jāpārstrādā noklusējuma uzvedība, kā minēts iepriekš).
options.RespectBrowserAcceptHeader = true; // false by default
Visbeidzot, vienkārši pārkārtojot pakalpojumu konstruktorā definēto formatētāju sarakstu, tīmekļa resursdators pēc noklusējuma izmantos to formatētāju, kuru jūs novietojat saraksta augšpusē (t. i., 0. pozīcijā).
Vairāk informācijas var atrast šajā .NET Web Development and Tools Blog ierakstā.
Jums ir iepriekš definētas metodes visbiežāk sastopamajiem statusa kodiem.
Ok(result)
atgriež 200
ar atbildiCreatedAtRoute
atgriež 201
+ jauna resursa URLNeradīts
atgriež 404
.BadRequest
atgriež 400
utt.Visu metožu sarakstu skatīt BaseController.cs
un Controller.cs
.
Bet, ja ļoti uzstājat, varat izmantot StatusCode
, lai iestatītu pielāgotu kodu, bet to nevajadzētu darīt, jo tas padara kodu mazāk salasāmu un jums būs jāatkārto kods, lai iestatītu galvenes (piemēram, CreatedAtRoute
).
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
Lūdzu, skatiet zemāk kodu, Jūs varat pārvaldīt vairākus statusa kodu ar dažāda tipa 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.");
}
}