W niektórych przypadkach mam NewtonSoft JSON.NET iw moim kontrolerze po prostu zwracam Jobject z mojego kontrolera i wszystko jest w porządku.
Ale mam przypadek, w którym otrzymuję surowy kod JSON z innej usługi i muszę go zwrócić z mojego interfejsu webAPI. W tym kontekście nie mogę używać NewtonSOft, ale gdybym mógł, utworzyłbym JOBJECT z łańcucha (co wydaje się niepotrzebnym narzutem przetwarzania) i zwróciłbym to i wszystko byłoby dobrze ze światem.
Jednak chcę to po prostu zwrócić, ale jeśli zwrócę ciąg, klient otrzyma opakowanie JSON z moim kontekstem jako zakodowanym ciągiem.
Jak mogę jawnie zwrócić JSON z mojej metody kontrolera WebAPI?
źródło
HttpResponseMessage response
, a następnie przypisaćStringContent
do.Content
właściwości. Nie działa, jeśli przypiszesz StringContent w konstruktorze.Oto rozwiązanie @ carlosfigueira przystosowane do korzystania z interfejsu IHttpActionResult, który został wprowadzony wraz z WebApi2:
public IHttpActionResult Get() { string yourJson = GetJsonFromSomewhere(); if (string.IsNullOrEmpty(yourJson)){ return NotFound(); } var response = this.Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json"); return ResponseMessage(response); }
źródło
Jeśli chcesz zwrócić tylko ten JSON, bez korzystania z funkcji WebAPI (takich jak zezwolenie na XML), zawsze możesz napisać bezpośrednio do wyniku. Zakładając, że hostujesz to w ASP.NET, masz dostęp do
Response
obiektu, więc możesz zapisać go w ten sposób jako ciąg, a następnie nie musisz w rzeczywistości zwracać niczego ze swojej metody - już napisałeś tekst odpowiedzi do strumienia wyjściowego.źródło
przykładowy przykład zwracania danych JSON z metody GET interfejsu API sieci Web
[HttpGet] public IActionResult Get() { return Content("{\"firstName\": \"John\", \"lastName\": \"Doe\", \"lastUpdateTimeStamp\": \"2018-07-30T18:25:43.511Z\", \"nextUpdateTimeStamp\": \"2018-08-30T18:25:43.511Z\"); }
źródło
te również działają:
[HttpGet] [Route("RequestXXX")] public ActionResult RequestXXX() { string error = ""; try{ _session.RequestXXX(); } catch(Exception e) { error = e.Message; } return new JsonResult(new { error=error, explanation="An error happened"}); } [HttpGet] [Route("RequestXXX")] public ActionResult RequestXXX() { string error = ""; try{ _session.RequestXXX(); } catch(Exception e) { error = e.Message; } return new JsonResult(error); }
źródło
To działa dla mnie w .NET Core 3.1.
private async Task<ContentResult> ChannelCosmicRaysAsync(HttpRequestMessage request) { // client is HttpClient using var response = await client.SendAsync(request).ConfigureAwait(false); var responseContentString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); Response.StatusCode = (int)response.StatusCode; return Content(responseContentString, "application/json"); }
public Task<ContentResult> X() { var request = new HttpRequestMessage(HttpMethod.Post, url); (...) return ChannelCosmicRaysAsync(request); }
ContentResult
jestMicrosoft.AspNetCore.Mvc.ContentResult
.Pamiętaj, że to nie są nagłówki kanałów, ale w moim przypadku to jest to, czego potrzebuję.
źródło