【问题标题】:Return a JSON string explicitly from Asp.net WEBAPI?从 Asp.net WEBAPI 显式返回 JSON 字符串?
【发布时间】:2013-06-10 11:23:17
【问题描述】:

在某些情况下,我有 NewtonSoft JSON.NET,在我的控制器中,我只是从控制器返回 Jobject,一切都很好。

但我有一个案例,我从另一个服务获取了一些原始 JSON,需要从我的 webAPI 返回它。在这种情况下,我不能使用 NewtonSOft,但如果可以的话,我会从字符串创建一个 JOBJECT(这似乎是不必要的处理开销)并返回它,一切都会好起来的。

但是,我想简单地返回它,但如果我返回字符串,那么客户端会收到一个 JSON 包装器,其中包含我的上下文作为编码字符串。

如何从我的 WebAPI 控制器方法显式返回 JSON?

【问题讨论】:

    标签: asp.net-mvc json asp.net-web-api


    【解决方案1】:

    如果您特别想只返回该 JSON,而不使用 WebAPI 功能(例如允许 XML),您始终可以直接写入输出。假设您使用 ASP.NET 托管它,您可以访问 Response 对象,因此您可以将其写为字符串,那么您实际上不需要从您的方法中返回任何内容 - 您已经已将响应文本写入输出流。

    【讨论】:

      【解决方案2】:

      有几种选择。最简单的方法是让您的方法返回 HttpResponseMessage,并根据您的字符串使用 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;
      }
      

      并检查 null 或空 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);
      }
      

      【讨论】:

      • 优秀。我正在制作一个 JSON 字符串并将其作为字符串返回,但这在结果周围引入了不可避免的额外 "。这应该可以解决这个问题。
      • 这很烦人。您必须实际创建HttpResponseMessage response,然后将StringContent 分配给.Content 属性。如果在构造函数中分配 StringContent 则不起作用。
      【解决方案3】:

      这是@carlosfigueira 的解决方案,适用于使用 WebApi2 引入的 IHttpActionResult 接口:

      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);
      }
      

      【讨论】:

        【解决方案4】:

        从 web api GET 方法返回 json 数据的示例

        [HttpGet]
        public IActionResult Get()
        {
                    return Content("{\"firstName\": \"John\",  \"lastName\": \"Doe\", \"lastUpdateTimeStamp\": \"2018-07-30T18:25:43.511Z\",  \"nextUpdateTimeStamp\": \"2018-08-30T18:25:43.511Z\");
        }
        

        【讨论】:

        • 内容从何而来?完全限定名称或“使用”语句会有所帮助。
        • 我知道我迟到了,但我认为@granadaCoder 的评论有点误导。内容是一种功能;不是一个类,来自与 Ok() 相同的 ControllerBase
        • 啊,这是一个模棱两可的词。 “内容”。我说的是 OBJECT .. return 语句之后的东西。又名“返回内容”......那个(大写)“内容”的完全限定类型名称是什么? (而且我不是在询问小写的“内容”,如..魔术json字符串。
        • 也许我错过了什么;但 Muni 的答案是调用函数 Microsoft.AspNetCore.Mvc.ControllerBase.Content(),它返回 Microsoft.AspNetCore.Mvc.ContentResult 类型的对象。我的观点是没有返回 new 对象;我看不到通过添加 using 语句可以完全限定或澄清什么。在我看来,这与 return Ok(); 相同。被调用以调用基类函数并返回 Microsoft.AspNetCore.Mvc.OkResult() 类型的对象。我同意返回类型并不明显,但这并不是上述答案的缺陷
        【解决方案5】:

        这些也有效:

        [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);
        }
        

        【讨论】:

          【解决方案6】:

          这适用于 .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);
          }
          

          ContentResultMicrosoft.AspNetCore.Mvc.ContentResult

          请注意,这不是频道标题,但在我的情况下,这是我需要的。

          【讨论】:

            【解决方案7】:

            如果您的控制器方法返回 IActionResult,您可以通过手动设置输出格式化程序来实现。

            // Alternatively, if inheriting from ControllerBase you could do
            // var result = Ok(jsonAsString);
            var result = new OkObjectResult(jsonAsString);
            
            var formatter = new StringOutputFormatter();
            result.Formatters.Add(formatter);
            
            formatter.SupportedMediaTypes.Clear();
            formatter.SupportedMediaTypes.Add("application/json");
            

            【讨论】:

              猜你喜欢
              • 2010-12-04
              • 2013-12-13
              • 1970-01-01
              • 2017-07-22
              • 2017-08-08
              • 1970-01-01
              • 1970-01-01
              • 2017-06-12
              • 1970-01-01
              相关资源
              最近更新 更多