1

I've got a situation where some objects are being serialized into JSON using Json.NET, and then registered as a client script block. The object's JSON gets put into the javascript in a single quote literal kind of like this:

// javascript output, normal
reportParameters = '{ "Location" : "My house" }';

But sometimes it needs to put in values that contain apostrophes, like "Billy's House", so obviously I'm going to need to escape this or else the javascript breaks.

// javascript output scenario, bad
reportParameters = '{ "Location" : "Billy's House" }';

// what I need is this
reportParameters = '{ "Location" : "Billy\'s House" }';

I tried to do this:

// C# input
reportParameterText = reportParameterText.Replace("'", @"\'");`

However, this always changes it to "Billy\\'s House", and I cannot tell why. A lot of places where people have had similar problems say "It's just the debugger's way of representing one backslash," but in my case I still get 2 backslashes making its way into the javascript, so the backslash gets escaped instead of the apostrophe and everything breaks.

// javascript actual output, bad
reportParameters = '{ "Location" : "Billy\\'s House" }';

I've followed it through the debugger, and it has two backslashes before and after it gets serialized, so the serializer is not the problem. And as I said before it's definitely NOT just the debugger's representation of an escaped character, because these values are making it into the source code.

Other solutions I've tried, all C#:

reportParameterText = reportParameterText.Replace("'", "\'"); // No change

reportParameterText = reportParameterText.Replace("'", "\\'"); // Creates 2 backslashes

reportParameterText = reportParameterText.Replace("'", @"[%]");
reportParameterText = reportParameterText.Replace(@"[%]", @"\'"); // Creates 2 backslashes

The Question: Why am I always getting 2 backslashes, and how can I make sure I only put down one?

This is .Net 4.

SOLUTION

Thanks for all your help and information, everyone. I've solved my problem by combining several people's advice and essentially doing what @Ali123 suggested. As for the C# question of "Where is the second backslash coming from," it has to do with @Gusman's answer below.

My serialized string in C# is not safe as a string in Javascript, but it was still well-formed JSON. The JS black box of whatever accepts the string of a JSON object that was left lying around in the reportParameters variable, but that doesn't mean that I have to get that stringified JSON in C#.

So instead of String.Replace in C#, I've prepared the generated JS code to look like this:

var tempThing = { "Location" : "Billy's House" };
reportParameters = JSON.stringify(tempThing);
StartDoingThings();

Looking at it again, I can cut a line out of that, but it still works.

TL;DR thanks, I know it was a slightly confusing problem.

Daniel Stone
  • 267
  • 3
  • 10
  • 2
    What json serializer are you using that it can't handle apostrophes? Try Json.NET, I'm pretty sure it does things right. – Sam Axe Jun 14 '17 at 21:06
  • @SamAxe It is Json.NET. Will add that to the post. – Daniel Stone Jun 14 '17 at 21:07
  • See this question: https://stackoverflow.com/questions/1242118/how-to-escape-json-string – frodo2975 Jun 14 '17 at 21:09
  • Can you show us your exact input JSON? What is `reportParameterText ` before you do the replace? – pookie Jun 14 '17 at 21:16
  • 1
    I think your problem isn't with serialization. The JSON `{ "Location" : "Billy's House" }` doesn't need escaping, it's perfectly valid. The problem is here *"The object's JSON gets put into the javascript in a single quote literal"*, what code are you using for that. – Matt Burland Jun 14 '17 at 21:17
  • 1
    I'd also question if you need to have it be a string on the javascript side. What are you doing with the string? If you are just deserializing it into an object, then you can skip that whole step and just output: `reportParameters = { "Location" : "My house" };` – Matt Burland Jun 14 '17 at 21:19
  • @MattBurland good question, it's merely a problem I've inherited. I've grown accustomed to seeing bizarre solutions. They send off the JSON to the silverlight app that contains this ASP page in a web frame, if that helps you understand this crazy thing. It's been a long while since I've done js, is there a good method for taking that plain JSON object and then stringifying it so that they can send it off in the format they're expecting? – Daniel Stone Jun 14 '17 at 21:24
  • @pookie the exact input before replacing is `Women's Diagnostic` – Daniel Stone Jun 14 '17 at 21:25
  • @DanielStone: it's completely not clear what you are doing and where you are doing it. So it's really hard to even decode your problem. – Matt Burland Jun 14 '17 at 21:31
  • @MattBurland Yeah, my apologies, it's a very weird and very broken thing I'm working with. Even I can't tell where all of it happens; besides the aspx.cs backend page and the javascript being added, it also touches silverlight, WCF services, and a no-sql database. So this particular page's code executions jump around all over the place all the time. Debugging has been a real pain. – Daniel Stone Jun 14 '17 at 21:34
  • I cannot reproduce your issue in [dotnetfiddler](https://dotnetfiddle.net/gTMi5O). Where are you printing this string? It may be related to HTML escaping feature of ASP.NET. – Federico Dipuma Jun 14 '17 at 21:34

2 Answers2

1

Use JSON.stringify() before sending the data to the server //Data to send

var DTS = { "name": "someone's Name","phone": "123456" };
     $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "ItemsAndCart.aspx/AddCustomer",
                data: JSON.stringify(DTS),
                datatype: "json",
                success: function (result) {
                    alert(result.d);
                    console.log(result);
                },
                error: function (xmlhttprequest, textstatus, errorthrown) {
                    alert(" conection to the server failed ");
                    console.log("error: " + errorthrown);
                }
            });
Ali123
  • 740
  • 13
  • 38
  • Yes, this was the next thing I was going to try if I couldn't get the simpler replace to work. I'll be trying it momentarily – Daniel Stone Jun 14 '17 at 21:29
  • Yes, using JSON.stringify did solve my problem that was being blocked by the C# question I had, so thanks very much! I wish I could mark more than one thing as an answer. – Daniel Stone Jun 14 '17 at 21:55
  • I think you have chosen the right answer for your question. But my answer was the right answer for your situation. Both works fine. Good luck and happy coding. – Ali123 Jun 14 '17 at 21:59
0

You are mixing semantics. C# and javascript with double quotes use backslash as escape character like C, javascript with single quotes or C# with a prepended @ are literals.

When you set:

reportParameters = '{ "Location" : "Billy\'s House" }';

you are using literals, so the backslash is being included in the string. When you see the string in C# you see it escaped, as the backslash is the escape character it's escaped with another backslash character, but that doesn't means there are two backslases, there's only one, but the debugger in C# shows you it in it's escaped form.

If you want to compose correctly the string in javascript use this:

reportParameters = "{ \"Location\" : \"Billy's House\" }";
Gusman
  • 14,905
  • 2
  • 34
  • 50