【问题标题】:Newtonsoft.Json SerializeObject without escape backslashes没有转义反斜杠的 Newtonsoft.Json SerializeObject
【发布时间】:2020-12-13 04:02:33
【问题描述】:

给定代码:

dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);

输出如下:

"{\"Bar\":\"something\"}"

在调试大型 json 文档时,很难阅读 - 使用 Newtonsoft.Json 的内置功能(不是可能破坏事物的正则表达式或黑客)有没有办法使输出成为带有 valie 的字符串:

{Bar: "something"}

【问题讨论】:

  • 您如何查看输出?它被呈现为不适合 JSON.NET 和 SerializeObject 的字符串文字,除非它被第二次序列化。如果您在 VS 中查看值(通过 Locals、Watch 等),那么它会将值呈现为代码,但应该可以选择以文本形式查看。
  • 是的,这是来自调试器查看 vs2012 中的字符串变量。我确实查看了查看器选项,它们是字符串、xml,我认为是 html
  • 参考这个......你可能会得到解决方案......stackoverflow.com/questions/13833900/…

标签: c# json json.net


【解决方案1】:

其实跟序列化器没有关系。这只是因为 c# 没有像 Javascipt 这样的单引号和双引号概念。所以它不能在不转义双引号的情况下显示字符串。 但是,如果您想将字符串放入 html/ cshtml 而不进行任何转义,您只需要像这样告诉编译器:

window.MYVAR = JSON.parse('@Html.Raw(ViewBag.MyStringFromCSharp)');

【讨论】:

    【解决方案2】:

    试试 JToken.Parse 方法。我发现即使我在调试器中查看 JSON 对象并且它们是正确的,当我去操作它们时,它们最终会被转换为文字(即添加了反斜杠)。 JToken.Parse 方法似乎可以避免这种情况。

    var token = JToken.Parse(text);
    

    所以在原始问题的情况下,它会是这样的:

    dynamic foo = new ExpandoObject();
    foo.Bar = "something";
    string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
    var token = JToken.Parse(json);
    //Do stuff with token -- not json string
    

    在我的情况下,问题是使用 JObject.Add(json) 无法识别我的字符串是 json 并且只是将整个字符串作为单个属性插入。一旦转换为 Jtoken,JSON 就会被正确解释。

    【讨论】:

      【解决方案3】:
          [HttpGet]
          public object Get(int id)
          {
      
              object result = "";
              var db = new dbEntities();
              var EO = new System.Dynamic.ExpandoObject() as IDictionary<string, Object>; //needed to return proper JSON without escape slashes
              try
              {
      
                  IEnumerable<usp_GetComplaint_Result> aRow =  db.usp_GetComplaint(id);
      
                  string DBL_QUOTE = new string(new char[] { '"' });
                  result = "{";
      
                  foreach (usp_GetComplaint_Result oneRow in aRow)
                  {
                      System.Reflection.PropertyInfo[] properties = typeof(usp_GetComplaint_Result).GetProperties();
      
                      foreach(System.Reflection.PropertyInfo property in properties)
                      {
                          var vValue = property.GetValue(oneRow) == null ? "null" : property.GetValue(oneRow);
                          EO.Add(property.Name,vValue);
                      }
                      break;
                  }
      
              }
              catch (Exception ex)
              {
                  result = ex.Message;
                  EO.Add("Error", result);
              }
              finally
              {
                  db.Dispose();
              }
      
              return Ok(EO);
      
          }
      

      【讨论】:

      • 尝试更清楚地解释为什么这是问题的答案。
      • 字面上的任何东西 :(
      【解决方案4】:

      返回IHttpActionResult并返回对象很简单

        public IHttpActionResult Get()
          {
      
              ExpandoObject foo = new ExpandoObject();
              foo = //query result
      
              return ok(foo)
          }
      

      【讨论】:

        【解决方案5】:

        嘿,我只是简单地写出放到一个文件中

         using (System.IO.StreamWriter file = 
                    new System.IO.StreamWriter(@"jsonGonna.txt", true))
                {
                    file.WriteLine(json);
                }
        

        现在只需运行该程序,您将获得没有黑色斜线,它适用于需要多次保存 JSON 的大型程序

        【讨论】:

          【解决方案6】:

          老问题,但我发现了这个,

          在我的例子中,我在调试器中查看 JSON 字符串,发现它正在添加转义。

          当我将 JSON 打印到控制台时,它没有转义字符。希望对您有所帮助。

          【讨论】:

            【解决方案7】:

            您应该使用JavaScriptSerializer.Serialize Method,而不是使用Newstonsoft.Json:

            dynamic foo = new ExpandoObject();
            foo.Bar = "something";
            var js = new JavaScriptSerializer( );
            string json = js.Serialize(foo);
            

            此方法会产生您正在寻找的输出。我读到了here

            【讨论】:

            • 上下文中的最佳答案。
            【解决方案8】:

            如果您在从 WebApi 方法返回值时发生这种情况,请尝试返回对象本身,而不是序列化对象并返回 json 字符串。 WebApi 默认会将响应中的对象序列化为 json;如果你返回一个字符串,它会转义它找到的任何双引号。

            所以而不是:

            public string Get()
            {
                ExpandoObject foo = new ExpandoObject();
                foo.Bar = "something";
                string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
                return json;
            }
            

            试试:

            public ExpandoObject Get()
            {
                ExpandoObject foo = new ExpandoObject();
                foo.Bar = "something";
                return foo;
            }
            

            【讨论】:

            • 如果我想编写单元测试来检查序列化输出的样子应该怎么做?
            【解决方案9】:

            当查看json 值时,您在调试器中看到的是字符串值,您应该在 C# 文件中使用它来获得相同的值。

            确实可以替换

            dynamic foo = new ExpandoObject();
            foo.Bar = "something";
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
            

            string json = "{\"Bar\":\"something\"}";
            

            不改变程序的行为。

            因此,要获得不同的值,您应该更改JsonConvert 的工作方式,但JsonConvert 符合JSON standard,因此忘记它!

            如果您实际上并没有序列化ExpandoObject(也不是任何其他不受您控制的密封类),您可以在您在json 中序列化的类型上使用DebuggerDisplayAttribute,来定义对象在运行期间的显示方式调试(在您的代码中,foo 实例)。

            但是字符串就是字符串,VisualStudio 是对的:双引号必须转义。

            【讨论】:

            • 当您 SerializeObject 来自 Web 服务的对象时会发生这种情况。您在 Web 浏览器输出中看到的是转义字符串,这使得输出无用,除非您想在客户端处理该问题。不,谢谢,我更愿意从我的 Web 服务将正确的 json 发送给我的客户。换句话说,我的 Web 服务应该返回我给它的字符串,就像我给它一样。
            • @TuncayGöncüoğlu 听起来您正在返回一个字符串对象,该对象再次被序列化为 JSON 字符串。将您的问题作为问题发布,我们可以帮助您解决问题。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-05-19
            • 2015-09-21
            • 2011-11-09
            • 2017-04-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多