Deserialize nested json string which contains special characters into an object - c#

I have user sending messages that might contain any special characters. I get that data as json string. I am trying to deserialize the string into an object and then pass it to my webapi.
But, I am not able to successfully deserialize the data. I have created a simple c# console app to test this function.
public class Program
{
public static void Main()
{
Console.WriteLine("Enter input:");
string data = Console.ReadLine();
// One of the SO article says,
// If the JSON is created using a JSON serializer, then all the
// special characters will be escaped properly
var sData = JsonConvert.SerializeObject(data);
MappedData mappedData = JsonConvert.DeserializeObject<MappedData>(dData.ToString());
Console.WriteLine(mappedData.PostData); //these need to be posted to webapi
Console.ReadKey();
}
}
public class MappedData
{
[JsonProperty("PostData")]
public string PostData { get; set; }
[JsonProperty("MessageQueueInformation")]
public string MessageQueueInformation { get; set; }
}
article referred: enter link description here
Test data that works (no special chars):
{ "MessageQueueInformation": '{"EntityId":"13","Action":"Add"}', "PostData": '{"listMessage":[{"message":"Successful case 1"}]}'}
This fails with error: Bad JSON escape sequence: \,.
{ "MessageQueueInformation": '{"EntityId":"13","Action":"Add"}', "PostData": '{"listMessage":[{"message":"Unsuccessful case- aaa /, \, ^, &, %, #'/"\\\,''!~"}]}'}

Your code is fine, but your user needs to change the messages he sends to actually be JSON. JSON input needs to be encoded properly.
If you want \ to appear in a string, then in a JSON string it will appear as \\.
If you want " to appear in a string, then it should appear as \".
If you want ' to appear in a string, then it should appear as \'.
{ "MessageQueueInformation": '{"EntityId":"13","Action":"Add"}', "PostData": '{"listMessage":[{"message":"Unsuccessful case- aaa /, \\, ^, &, %, #'/\"\\\\\\,\'\'!~"}]}'}

Related

Jsonconvert serializeobject not escaping single quote

C#, I have an Automobile class and in that class i have a vehicleTrim field.
I use JsonConvert.SerializeObject to serialize that class and it is not escaping the single quote.
This is causing an issue when i try to set the value of an object in the web via window.localStorage.setItem function.
example:
public class Automobile
{
public string vehicleTrim { get; set; }
}
var test = new Automobile()
{
vehicleTrim = "designer's package"
};
var serialized = JsonConvert.SerializeObject(test, Formatting.None);
// serialized output: {"vehicleTrim":"designer's package"}
// expected output : {"vehicleTrim":"designer\'s package"}
so now i want to set this json object to the localstorage of my web by calling this
var jsSetScript = $"window.localStorage.setItem('automobile', '{serialized}');";
await Control.EvaluateJavascriptAsync(jsSetScript);
EvaluateJavascriptAsync returns this error trying to read the json SyntaxError: Unexpected identifier 's'. Expected ')' to end an argument list.
I manaully tried this with the escaped single quote and it was fine. So the question is how can i make serializedobject method escape the single quote?
"\'" is not even a valid JSON string literal. From the JSON spec:
Thus ' does not need to be escaped, but if it is, it must appear as "\u0027". Only the 8 listed characters have a special, abbreviated escaping syntax. (For further details see RFC 8259.)
If "\u0027" meets your needs, then setting JsonSerializerSettings.StringEscapeHandling to StringEscapeHandling.EscapeHtml should do the trick. From the docs:
StringEscapeHandling Enumeration
Specifies how strings are escaped when writing JSON text.
Default 0 Only control characters (e.g. newline) are escaped.
EscapeNonAscii 1 All non-ASCII and control characters (e.g. newline) are escaped.
EscapeHtml 2 HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped.
Thus the following now succeeds:
var settings = new JsonSerializerSettings
{
StringEscapeHandling = StringEscapeHandling.EscapeHtml,
};
var serialized = JsonConvert.SerializeObject(test, Formatting.None, settings);
Console.WriteLine(serialized);
// Outputs {"vehicleTrim":"designer\u0027s package"}
Assert.IsTrue(!serialized.Contains('\''));
// Succeeds
Demo fiddle here.

C# preserve escape sequence when reading JSON content using Json.NET

C# preserve escape sequence when reading JSON content using Json.NET
Given the following json text content:
{ "Pattern": "[0-9]*\t[a-z]+" }
Which is reflected in a simple class:
public class Rule
{
public string Pattern { get; set; }
public bool Test(string text)
{
return new Regex(Pattern).IsMatch(text);
}
}
And it's deserialised like this:
var json = System.IO.File.ReadAllText("file.json");
var rule = JsonConvert.DeserializeObject<Rule>(text);
The value of Pattern is supposed to be a regex pattern. The problem is that, once the content is read, the "\t" escape sequence is immediately applied as a escape character which is a tab, resulting in the string value: [0-9]* [a-z]+.
What I understand is that the content is somewhat malformed, because it should look like this: [0-9]*\\t[a-z]+ to be valid within the Json content, escaping the backslash so it could be preserved and result into the actual pattern [0-9]*\t[a-z]+. But the file is user edited and I would just like to be able to loosely interpret the content, assuming that backslashes should be preserved (and escape sequences would not be transformed).
I tried to implement a custom JsonConverter but when looking up the token, the value is already resolved.
FIDDLE
I've tried the below code and it works...maybe i don't understand what is the problem or you can provide a sample that doesn't work with this:
StreamReader s= new StreamReader(#"test.txt");
string json = s.ReadToEnd();
json=json.Replace("\\","\\\\");
JObject obj = JObject.Parse(json);
string pattern = obj["Pattern"].ToString();
bool test = Regex.IsMatch("1 a", pattern);
test.txt contains just this:
{ "Pattern": "[0-9]*\t[a-z]+" }
Edit
As Thomasjaworsky remarks, instead of json=json.Replace("\\","\\\\"); is better to use Regex.Replace(json, #"(?<!\\)[\\](?!\\)", #"\\")
, it will do the same replace, but only if not already escaped. Two backspaces in row are untouched.

C# JSONConvert.DeserializeObject JSON with Newlines

I have the following sample JSON in a variable called JSONContent
[
{"comment":"This is \\na comment"},
{"comment":"This is another comment"}
]
I type the JSON as such:
public class Comments
{
[JsonProperty("comment")]
public string comment { get; set; }
}
And Deserialize as such:
var Result = JsonConvert.DeserializeObject<List<Comments>>(JSONContent);
I then loop through the RESULT:
// Loop through the JSON object and populate the rows
foreach (var message in Result)
{
doSomething( message.comment );
}
When I inspect the message.comment it shows as:
This is \\na comment
This is another comment
What happens later is I am saving the comment into a database but the database shows the literal "\n" in the result instead of the hopeful newline. This is of course because c# is just converting the \\ to a literal \ and ignoring the n.
I know I can do a replace on the comment, but it feels like I am missing something that tells JSONConvert.DeserializeObject to do this for me.

JSON.Net deserialize string which contains special characters

How do I parse JSON string with one of the values containing special characters?
JObject obj = JObject.Parse(str);
str value:
{
"message": "some !##$%^&*(){}:"?/?/|"':>;><{"d":"v"}"
}
I have got execption: After parsing a value an unexpected character was encountered: {.
That JSON is invalid. If a JSON string contains special characters like double quotes ", backslashes \ or slashes /, they need to be escaped with backslashes \. (See JSON.org.) No JSON parser, including Json.Net, will be able to deal with a JSON string that isn't properly formatted in the first place.
Your JSON would need to look like this to be able to be parsed correctly:
{
"message": "some !##$%^&*(){}:\"?/?/|\"':>;><{\"d\":\"v\"}"
}
The solution is to correctly serialize the string at the source.
Take your JSON and .stringify() it.
{
"message": JSON.stringify("your text here")
}
If you have raw data in your ASP.NET MVC view, you can follow this way:
{
"message": JSON.stringify("#Html.Raw(HttpUtility.JavaScriptStringEncode(Model.MyString))")
}
You can also try more preferred way:
JSON.stringify({ "message" : message });

how to validate JSON string before converting to XML in C#

I will receive an response in the form of JSON string.
We have an existing tool developed in C# which will take input in XML format.
Hence i am converting the JSON string obtained from server using Newtonsoft.JSON to XML string and passing to the tool.
Problem:
When converting JSON response to XML, I am getting an error
"Failed to process request. Reason: The ' ' character, hexadecimal
value 0x20, cannot be included in a name."
The above error indicates that the JSON Key contains a space [For Example: \"POI Items\":[{\"lat\":{\"value\":\"00\"}] which cannot be converted to XML element.
Is there any approach to identify spaces only JSON key's ["POI Items"] and remove the spaces in it?
Also suggest any alternative solution so that we needn't change the existing solution?
Regards,
Sudhir
You can use Json.Net and replace the names while loading the json..
JsonSerializer ser = new JsonSerializer();
var jObj = ser.Deserialize(new JReader(new StringReader(json))) as JObject;
var newJson = jObj.ToString(Newtonsoft.Json.Formatting.None);
.
public class JReader : Newtonsoft.Json.JsonTextReader
{
public JReader(TextReader r) : base(r)
{
}
public override bool Read()
{
bool b = base.Read();
if (base.CurrentState == State.Property && ((string)base.Value).Contains(' '))
{
base.SetToken(JsonToken.PropertyName,((string)base.Value).Replace(" ", "_"));
}
return b;
}
}
Input : {"POI Items":[{"lat":{"value":"00","ab cd":"de fg"}}]}
Output: {"POI_Items":[{"lat":{"value":"00","ab_cd":"de fg"}}]}
I recommend using some sort of Regex.Replace().
Search the input string for something like:
\"([a-zA-Z0-9]+) ([a-zA-Z0-9]+)\":
and then replace something like (mind the missing space):
\"(1)(2)\":
The 1st pair of parenthesis contain the first word in a variable name, the 2nd pair of parenthesis means the 2nd word. The : guarantees that this operation will be done in variable names only (not in string data). the JSON variable names are inside a pair of \"s.
Maybe it's not 100% correct but you can start searching by this.
For details check MSDN, and some Regex examples
http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace.aspx

Categories