无法解析由.NET Serializer

时间:2017-09-09 13:15:55

标签: c# asp.net json serialization escaping

当我使用System.Web.Script.Serialization.Serialize()序列化来自恰好包含引号的DataTable中的某些数据时,我得到一个看似有效的JSON字符串。

用于序列化的VB代码是:

Public Shared Function DataTableToJSONWithJavaScriptSerializer(table As DataTable) As String
        Dim jsSerializer As New JavaScriptSerializer()
        Dim parentRow As New List(Of Dictionary(Of String, Object))()
        Dim childRow As Dictionary(Of String, Object)
        For Each row As DataRow In table.Rows
            childRow = New Dictionary(Of String, Object)()
            For Each col As DataColumn In table.Columns
                childRow.Add(col.ColumnName, row(col))
            Next
            parentRow.Add(childRow)
        Next
        Return jsSerializer.Serialize(parentRow)
End Function

Dim str_sql As String = "SELECT TOP 1 create_date, content FROM tbl_dent"
Dim obj_rdr As SqlDataReader
' ...
' some code suppressed for brevity
Dim obj_dt As New DataTable()
obj_dt.Load(obj_rdr)
Dim str_javascript_string As String = "var str = '" _
    & DataTableToJSONWithJavaScriptSerializer(obj_dt).Replace("[","").Replace("]","") & "';"
' append this script to web page

编辑(解决方案,根据@ Heinzi的回答):

'instead of this:
Dim str_javascript_string As String = "var str = '" _
    & DataTableToJSONWithJavaScriptSerializer(obj_dt).Replace("[","").Replace("]","") & "';"
'this:
Dim jsSecondSerializer As New JavaScriptSerializer()
Dim str_javascript_string As String = "var str = " _
    & jsSecondSerializer.serialize(DataTableToJSONWithJavaScriptSerializer(obj_dt).Replace("[","").Replace("]","")) & ";"

输出的示例(包含引号)是:

var str = '{"create_date":"2017-09-08T22:30:11.674Z","content":"This dent is 4\" wide."}';

但是当我尝试解析它时,就像这样:

var obj = JSON.parse(str);

我收到此错误:未捕获的SyntaxError:位置69的JSON中出现意外的标记w

为什么呢?我无法想象我需要手动搜索和双重报价标记......?当然,我可以依靠序列化器来正确生成可用的json字符串吗?

2 个答案:

答案 0 :(得分:2)

您的字符串未正确转义。你有这个字符串:

{"create_date":"2017-09-08T22:30:11.674Z","content":"This dent is 4\" wide."}

您显然希望将其编码为JavaScript字符串文字。在JavaScript中,\具有特殊含义,即使在单引号¹所包含的字符串中使用,因此您需要将其转义:

// JavaScript
var str = '{"create_date":"2017-09-08T22:30:11.674Z","content":"This dent is 4\\" wide."}';

如果你的字符串中有任何单引号,你也需要将它们转义。

当然,你是对的,你不应该手动这样做。因此,最简单的解决方案是再次通过JavaScriptSerializer.Serialize运行此字符串:

// C#
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var x = serializer.Serialize(@"{""create_date"":""2017-09-08T22:30:11.674Z"",""content"":""This dent is 4\"" wide.""}");
Console.WriteLine("var str = " + x + ";");

// yields
// var str = "{\"create_date\":\"2017-09-08T22:30:11.674Z\",\"content\":\"This dent is 4\\\" wide.\"}";

因此,简而言之,您需要运行Serialize 两次

  • 将您的对象转换为JSON字符串,然后
  • 将您的JSON字符串转换为JavaScript字符串文字。

¹在JavaScript控制台中尝试'"' === '\"'并注意它会产生true

答案 1 :(得分:0)

我的其他答案已经解决了您所说的问题,但我想为您的基础问题提出替代方案:

由于JSON通常是  (except when it contains some exotic Unicode whitespace characters)有效的JavaScript,为什么要对你的JSON对象进行字符串化和解析呢?只需删除单引号并直接将其用作JavaScript对象:

// JavaScript
var obj = {"create_date":"2017-09-08T22:30:11.674Z","content":"This dent is 4\" wide."};