1

When I use System.Web.Script.Serialization.Serialize() to serialize some data from a DataTable that happens to contain a quotation mark, I get a JSON string that appears to be valid.

The VB code I'm using to serialize is this:

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

EDIT (solution, per @Heinzi's answer below):

'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("]","")) & ";"

An example of the output (that contains a quotation mark) is this:

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

But when I try to parse it, like this:

var obj = JSON.parse(str);

I get this error: Uncaught SyntaxError: Unexpected token w in JSON at position 69

Why? I can't imagine that I need to manually search for and double-escape quote-marks...? Surely I can rely on the serializer to properly generate a usable json string?

2 Answers 2

2

Your string is improperly escaped. You have this string:

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

which you apparently want to encode as a JavaScript string literal. In JavaScript, \ has a special meaning, even when used inside a string enclosed by single quotes¹, so you need to escape it:

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

If there were any single quotes inside your string, you'd need to escape them as well.

Of course, you are right that you shouldn't have to do this manually. So the easiest solution would be to just run this string thorough JavaScriptSerializer.Serialize again:

// 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.\"}";

So, in a nutshell, you need to run Serialize twice:

  • once to transform your object into a JSON string, and
  • once to transform your JSON string into a JavaScript string literal.

¹ Try '"' === '\"' inside a JavaScript console and note that it yields true.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. I follow your logic, but it's not clear to me how to apply your answer, since I probably didn't include enough context in my original question. I've edited it to indicate that the data in question comes from a database, and is being serialized without actually handling individual text strings, so I'm unsure how to serialize it twice, as you suggest. Does this make sense? Can you easily suggest how to correctly serialize in this context?
@Octavient: DataTableToJSONWithJavaScriptSerializer returns a string. What do you do with that string? Please show that in your question.
I've modified the original question to show how that Function is used to deliver the string to the web page.
@Octavient: Thanks. Note that by creating str_javascript_string you manually add single quotes around your string. Why do you do that? You do that to transform your string a into a JavaScript string literal 'a'. But that's not a good way to transform a string into a JavaScript string literal: It fails if the string contains ' or (in your case) a backslash. Thus, don't do that. Either convert the string correctly (by running it through Serialize again instead of adding the single quotes) or just drop the single quotes (as suggested by my other answer) and assign it directly to obj.
That's it! Thank you! For posterity, I've edited my original question above, to reflect this Accepted answer. (not sure what the SO protocol on this kind of thing is--I'm open to feedback on this)
|
0

My other answer answered your problem as stated, but I want to suggest an alternative for your underlying problem:

Since JSON is usually (except when it contains some exotic Unicode whitespace characters) valid JavaScript, why stringify and parse your JSON object at all? Just drop the single quotes and use it directly as a JavaScript object:

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

1 Comment

I normally would do this, but this is data that is stored in browser storage (in compliant browsers) as a string, and since I assumed that serializing on the server would be as low-drama as stringifying on the client, I decided to serialize on the server. Which may prove to be a faulty assumption, of course.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.