I need to manage char like ' in my JSONP request, trought Ajax by jquery. So (from C#) this is what I've done :
myText = "Hello I'm a string";
myText.Replace("'", "\'");
Response.Write(Request["callback"] + "({ htmlModulo: '" + myText + "'});");
but on Client side it broke :
parsererror - SyntaxError: missing } after property list
so, How can I manage ' if the replace doesnt works?
Serializing JSON is already solved for you by .NET. Use System.Web.Script.Serialization.JavaScriptSerializer:
var serializer = new JavaScriptSerializer();
To construct JSONP you just need to concatenate prefix (either hardcoded or passed in "callback" query parameter) and suffix (normally just ), but sometimes you may need to pass extra parameters depending on what caller expect like ,42, null) ) with JSON text.
Sample below shows constructing JSONP based on "callback" parameter, replace value of jsonpPrefix based on your needs.
var myText = "Hello I'm a string";
var jsonpPrefix = Request["callback"] + "(";
var jsonpSuffix = ")";
var jsonp =
jsonpPrefix +
serializer.Serialize(new {htmlModulo = myText}) +
jsonpSuffix);
Response.Write(jsonp);
You should always use a serializer, because doing it yourself means you're more likely to mess up and violate the JSON spec. For example, you are not quoting the key, which is required by JSON, so jQuery and other JSON parsers will be very confused. It will handle all characters that need to be escaped, as well.
More on constructing JSON can be found in How to create JSON string in C#.
leave the text as it is, but use double quotes to escape it in json:
Response.Write(Request["callback"] + "({ htmlModulo: \"" + myText + "\"});");
you could also try this one:
var jsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = jsonSerializer.Serialize(yourCustomObject);
and then i leave this as well
You would need to do:
myText.Replace("'", "\\'");
If you want an escaped single quote in the value of your htmlModulo property. However, your actual JSON would still be invalid. According to the specification, you should be using double quotes to surround key names and values. Thus, for your response to be valid, you would need to send:
{"htmlModulo": "myText value"}
It really shouldn't matter with JSONP since that relies on inserting a new script element into the DOM. Thus even the improper JSON would be interpreted correctly by the JavaScript interpreter. The problem is if you ever request the data as plain JSON. If you do that, then the way you are sending it now will fail with a variety of libraries. In particular, jQuery will fail silently with improper JSON.
Related
Json.Net allows new lines in a string value during deserialization which is against the JSON specification - how to prevent that and make JSON.Net to strictly enforce JSON rules?
We have some server side code that uses Newtonsoft to parse some JSON. The same JSON seems to fail to parse in javascript, and mysql's JSON_VALID function returns 0. Just wondering if there is a way to have Newtonsoft be more strict about deserialization. Example, here is code that runs, that should throw an exception because JSON can not have embedded new lines in strings.
string jsonStr = "{ \"bob\":\"line1\nline2\" }";
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonStr);
If you look at jsonStr in the debugger, specifically using the text visualizer, you see the line break. As expected this exact string gets passed to an actual JavaScript engine, parsing fails:
JSON.parse("{ \"bob\":\"line1\nline2\" }")
VM137:1 Uncaught SyntaxError: Unexpected token
Note that serialization code seems to do the "right" thing. i.e. escapes the slash in the new line when creating output.
public class Test
{
public string Name { get; set;}
}
Test t = new Test();
t.Name = "Bob\nFrank";
string jsonOut = Newtonsoft.Json.JsonConvert.SerializeObject(t);
Am I missing something?
I've debugged the Newtonsoft Json.NET and I'll say you can't. Everything that is interesting happens in the JsonTextReader class, and there is no useful override point. The path you are interested in is Read()->ParseValue()->ParseString()->ReadStringIntoBuffer() and there, toward the end there are:
case StringUtils.CarriageReturn:
_charPos = charPos - 1;
ProcessCarriageReturn(true);
charPos = _charPos;
break;
case StringUtils.LineFeed:
_charPos = charPos - 1;
ProcessLineFeed();
charPos = _charPos;
break;
that will "accept" newlines inside strings.
Worse, there is not even an overridable method or event about "begin and end of string parsing".
You could clearly rewrite the whole JsonTextReader, but you can't simply copy and paste it in a new file, because it uses internal classes of Json.NET (like StringBuffer, StringReference, StringUtils, CollectionUtils, ConvertUtils, MiscellaneousUtils (but only for .Assert) plus internal methods of JsonReader...)
Remember that if all you want is check if the Json is valid, you can try the other parsers that exist. Microsoft gives you two: there is the (old)JavascriptSerializer and the (new)JsonSerializer.
I want to pass a filepath through JSON. On deserializing I am getting error:
Unrecognized escape sequence. (43): {"Jobtype": "StepBatch","SelectedId": "D:\Input\file1.CATPart"}
I have escaped characters but it still shows error...am I missing something here?
string json = "{\"Jobtype\": \"StepBatch\",\"SelectedId\": \"D:\\Input\\file1.CATPart\"}";
var jsonObj = new JavaScriptSerializer().Deserialize<List<Arguments>>(json);
The problem is that the content of your string at execution time is:
{"Jobtype": "StepBatch","SelectedId": "D:\Input\file1.CATPart"}
That's not valid JSON, because of the backslashes in the value for SelectedId. You'd need the JSON to be:
{"Jobtype": "StepBatch","SelectedId": "D:\\Input\\file1.CATPart"}
so your C# would have to be:
string json = "{\"Jobtype\": \"StepBatch\",\"SelectedId\": \"D:\\\\Input\\\\file1.CATPart\"}";
However, given that you're immediately deserializing the JSON anyway, I'd suggest getting rid of the JSON part entirely, and just creating the Arguments values yourself.
If you need to produce JSON, create the right values directly, and then get JavaScriptSerializer (or preferrably Json.NET) to create the JSON for you, instead of hand-coding it.
I'm using System.Web.Script.Serialization.JavaScriptSerializer() to serialize dictionary object into JSON string. I need to send this JSON string to API sitting in the cloud. However, when we serialize it, serializer replaces all the double quotes with \"
For example -
Ideal json_string = {"k":"json", "data":"yeehaw"}
Serializer messed up json_string = {\"k\":\"json\",\"data\":\"yeehaw\" }
Any idea why it is doing so? And I also used external packages like json.net but it still doesn't fix the issues.
Code -
Dictionary<string, string> json_value = new Dictionary<string, string>();
json_value.Add("k", "json");
json_value.Add("data", "yeehaw");
var jsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string json_string = jsonSerializer.Serialize(json_value);
I'm going to hazard the guess that you're looking in the IDE at a breakpoint. In which case, there is no problem here. What you are seeing is perfectly valid JSON; simply the IDE is using the escaped string notation to display it to you. The contents of the string, however, are your "ideal" string. It uses the escaped version for various reasons:
so that you can correctly see and identify non-text characters like tab, carriage-return, new-line, etc
so that strings with lots of newlines can be displayed in a horizontal-based view
so that it can be clear that it is a string, i.e. "foo with \" a quote in" (the outer-quotes tell you it is a string; if the inner quote wasn't escaped it would be confusing)
so that you can copy/paste the value into the editor or immediate-window (etc) without having to add escaping yourself
Make sure you're not double serializating the object. It happened to me some days ago.
What you're seeing is a escape character
Your JSON is a String and when you want to have " in a string you must use one of the following:
string alias = #"My alias is ""Tx3""";
or
string alias = "My alias is \"Tx3\"";
Update
Just to clarify. What I wanted say here is that your JSON is perfectly valid. You're seeing the special characters in the IDE and that is perfectly normal like Jon & Marc are pointing in their answers and comments. Problem lies somewhere else than those \ characters.
I recognized that based on a context in which I want to use some parameters, there are at least 4 kinds of encoding that are necessary to avoid corrupted code being executed :
Javascript encoding when constructing a javascript code, e.g.
var a = "what's up ?"
var b = "alert('" + a + "');"
eval(b); // or anything else that executes b as code
URL encoding when using a string as a parameter into the url, e.g.
var a = "Bonnie & Clyde";
var b = "mypage.html?par=" + a;
window.location.href = b; // or anything else that tries to use b as URL
HTML encoding when using a string as an HTML source of some element, e.g.
var a = "<script>alert('hi');</script>";
b.innerHTML = a; // or anything else that interprets a directly
HTML attribute encoding when using a string as a value of an attribute, e.g.
var a = 'alert("hello")';
var b = '<img onclick="' + a + '" />'; // or anything else that uses a as a (part of) a tag's attribute
While in the ASP.NET codebehind I'm aware of ways to encode the string in all 4 cases (using e.g. DataContractJsonSerializer, HttpUtility.UrlEncode, HttpUtility.HtmlEncode and HttpUtility.HtmlAttributeEncode), it would be quite interesting to know whether there are some utilities that I could use directly from javascript to encode / decode strings in these 4 cases.
Case 2 can be dealt with using encodeURIComponent(), as danp suggested.
Case 3 won't execute the script in most browsers. If you want the output to the document to be <script>...</script>, you should edit the text content of the element instead:
var a = "<script>alert('hi');</script>";
if ("textContent" in b)
b.textContent = a; // W3C DOM
else
b.innerText = a; // Internet Explorer <=8
Cases 1, and 4 aren't really encoding issues, they're sanitation issues. Encoding the strings passed to these functions would probably cause a syntax error or just result in a string value that isn't assigned to anything. Sanitizing usually involves looking for certain patterns and either allowing the action or disallowing it - it's safer to have a whitelist than a blacklist (that sounds terrible!).
Internet Explorer 8 has an interesting function called window.toStaticHTML() that will remove any script content from a HTML string. Very useful for sanitizing HTML before inserting into the DOM. Unfortunately, it's proprietary so you won't find this function in other browsers.
You can use the javascript function escape(..) for some of these purposes.
e: actually forget! sorry, it's a deprecated function - encodeURI(), decodeURI() etc are the way forward! Details here.
escape and unescape functions do not
work properly for non-ASCII characters
and have been deprecated. In
JavaScript 1.5 and later, use
encodeURI, decodeURI,
encodeURIComponent, and
decodeURIComponent.
The escape and unescape functions let
you encode and decode strings. The
escape function returns the
hexadecimal encoding of an argument in
the ISO Latin character set. The
unescape function returns the ASCII
string for the specified hexadecimal
encoding value.encoding value.
I'm using C# to send JSON to a PHP-Script, like this:
string json = "{";
json += "\"prop\":\"some text\"";
json += "}";
PostSubmitter post = new PostSubmitter();
post.Url = "http://localhost/synch/notein.php";
post.Type = PostSubmitter.PostTypeEnum.Post;
post.PostItems.Add("note", json);
post.Post();
Of course I'll have to escape the inner quotes, but they get sended to the script! To make things worse: There is text, which already has quotation marks, so those must be escaped to be valid JSON. In this case I want the backslashes to be transmitted. Any idea to accomplish this?
Why not serialize the custom object to json result. That way you don't have to worry about the escaping, the framework would... Here is an example using JavaScriptSerializer - Convert objects to JSON in C# using JavaScriptSerializer
Escape your backslashes \\:
json += "\\\"prop\":\\\"some text\\\"";
Ooops, thought PostSubmitter is from the .NET-framework, but it's third-party. Nevertheless: Turned out that this is a PHP-problem. If someone has a similar problem: Look for get_magic_quotes_gpc in PHP-docs.