Retornar uma string JSON explicitamente do Asp.net WEBAPI?

88

Em alguns casos eu tenho NewtonSoft JSON.NET e no meu controlador eu apenas retorno o Jobject do meu controlador e está tudo bem.

Mas tenho um caso em que obtenho algum JSON bruto de outro serviço e preciso devolvê-lo de minha webAPI. Nesse contexto, não posso usar NewtonSOft, mas se pudesse, criaria um JOBJECT a partir da string (que parece sobrecarga de processamento desnecessário) e retornaria isso e tudo ficaria bem com o mundo.

No entanto, quero retornar isso de forma simples, mas se eu retornar a string, o cliente receberá um wrapper JSON com meu contexto como uma string codificada.

Como posso retornar explicitamente um JSON do meu método de controlador WebAPI?

desajeitado
fonte

Respostas:

201

Existem algumas alternativas. O mais simples é fazer com que seu método retorne a HttpResponseMessagee criar essa resposta com StringContentbase em sua string, algo semelhante ao código abaixo:

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

E verificar string JSON nula ou vazia

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
fonte
4
Excelente. Eu estava fazendo uma string JSON e retornando-a como uma string, mas isso introduziu um "extra inevitável" em torno do resultado. Isso deve corrigir isso.
dumbledad
1
Isso é irritante. Você realmente precisa criar o e HttpResponseMessage response, em seguida, atribuir o StringContentà .Contentpropriedade. Não funciona se você atribuir StringContent no Construtor.
Suamere de
16

Aqui está a solução de @carlosfigueira adaptada para usar a interface IHttpActionResult que foi introduzida com 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
fonte
2

Se você deseja retornar especificamente aquele JSON, sem usar recursos WebAPI (como permitir XML), você sempre pode gravar diretamente na saída. Assumindo que você está hospedando isso com ASP.NET, você tem acesso ao Responseobjeto, então você pode escrevê-lo dessa forma como uma string, então você não precisa realmente retornar nada do seu método - você já escreveu o texto de resposta para o fluxo de saída.

Joe Enos
fonte
1

exemplo de exemplo para retornar dados json do método GET da API da 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
fonte
2
De onde vem o conteúdo? um nome totalmente qualificado ou uma instrução "usando" seria útil.
granadaCoder
0

estes também funcionam:

[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
fonte
0

Isso funciona para mim no .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é Microsoft.AspNetCore.Mvc.ContentResult.

Observe que isso não canaliza cabeçalhos, mas no meu caso é disso que preciso.

tymtam
fonte