Zwrócić ciąg JSON jawnie z Asp.net WEBAPI?

85

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?

niezdarny
źródło

Odpowiedzi:

197

Jest kilka alternatyw. Najprostszym z nich jest zwrócenie metody a HttpResponseMessagei utworzenie tej odpowiedzi na StringContentpodstawie ciągu znaków, podobnie do poniższego kodu:

public HttpResponseMessage Get()
{
    string yourJson = GetJsonFromSomewhere();
    var response = this.Request.CreateResponse(HttpStatusCode.OK);
    response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
    return response;
}

I sprawdzanie null lub pustego ciągu JSON

public HttpResponseMessage Get()
{
    string yourJson = GetJsonFromSomewhere();
    if (!string.IsNullOrEmpty(yourJson))
    {
        var response = this.Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
        return response;
    }
    throw new HttpResponseException(HttpStatusCode.NotFound);
}
carlosfigueira
źródło
4
Świetny. Robiłem ciąg JSON i zwracałem go jako ciąg, ale to wprowadziło nieuniknione dodatkowe "wokół wyniku. To powinno to naprawić.
dumbledad
1
To jest denerwujące. Musisz faktycznie utworzyć HttpResponseMessage response, a następnie przypisać StringContentdo .Contentwłaściwości. Nie działa, jeśli przypiszesz StringContent w konstruktorze.
Suamere,
15

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);
}
Jpsy
źródło
2

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 Responseobiektu, 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.

Joe Enos
źródło
1

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\");
}
Muni Chittem
źródło
2
Skąd pochodzi Treść? w pełni kwalifikowana nazwa lub instrukcja „using” byłaby pomocna.
granadaCoder
0

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);
}
eci
źródło
0

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 jest Microsoft.AspNetCore.Mvc.ContentResult .

Pamiętaj, że to nie są nagłówki kanałów, ale w moim przypadku to jest to, czego potrzebuję.

tymtam
źródło