Вернуть строку JSON явно из Asp.net WEBAPI?

88

В некоторых случаях у меня есть NewtonSoft JSON.NET, и в моем контроллере я просто возвращаю Jobject из своего контроллера, и все хорошо.

Но у меня есть случай, когда я получаю необработанный JSON из другой службы и мне нужно вернуть его из моего webAPI. В этом контексте я не могу использовать NewtonSOft, но если бы я мог, я бы создал JOBJECT из строки (что кажется ненужными накладными расходами на обработку) и вернул бы его, и все было бы в порядке с миром.

Однако я хочу просто вернуть это, но если я верну строку, то клиент получит оболочку JSON с моим контекстом в виде закодированной строки.

Как я могу явно вернуть JSON из моего метода контроллера WebAPI?

глупый
источник

Ответы:

201

Есть несколько альтернатив. Самый простой - заставить ваш метод возвращать a HttpResponseMessageи создавать этот ответ с помощью a StringContentна основе вашей строки, что-то вроде кода ниже:

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

И проверка нулевой или пустой строки 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);
}
Карлосфигейра
источник
4
Превосходно. Я создавал строку JSON и возвращал ее как строку, но это привело к неизбежному дополнительному
значению
1
Это раздражает. Вам нужно создать объект HttpResponseMessage response, а затем назначить StringContentего .Contentсвойству. Это не сработает, если вы назначите StringContent в конструкторе.
Suamere
16

Вот решение @ carlosfigueira, адаптированное для использования интерфейса IHttpActionResult, представленного с 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
источник
2

Если вы специально хотите вернуть только этот JSON, без использования функций WebAPI (например, разрешения XML), вы всегда можете писать прямо в вывод. Предполагая, что вы размещаете это с помощью ASP.NET, у вас есть доступ к Responseобъекту, поэтому вы можете записать его таким образом в виде строки, тогда вам фактически не нужно ничего возвращать из вашего метода - вы уже написали текст ответа на выходной поток.

Джо Энос
источник
1

пример примера для возврата данных json из метода GET веб-API

[HttpGet]
public IActionResult Get()
{
            return Content("{\"firstName\": \"John\",  \"lastName\": \"Doe\", \"lastUpdateTimeStamp\": \"2018-07-30T18:25:43.511Z\",  \"nextUpdateTimeStamp\": \"2018-08-30T18:25:43.511Z\");
}
Муни Читтем
источник
2
Откуда берется Контент? было бы полезно использовать полное имя или оператор using.
granadaCoder
0

они также работают:

[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
источник
0

У меня это работает в .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.

Обратите внимание, это не заголовки каналов, но в моем случае это то, что мне нужно.

тымтам
источник