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.
Related
Is this json data format?
string json = {"answer":"Line 1","mark": 1},{"answer":"Line 3","mark": 1}
I try below code but it only working with one param. ex: {"answer":"Line 1","mark": 1}. I try split json string but it isn't best way.
JObject jObject = JObject.Parse(json );
string asw = jObject["answer"].ToString();
int mark = (int)jObject["mark"];
txtAnswer.Text = asw + "////" + mark + "\n";
This is a very basic JSON question which any number of tutorials could've answered for you.
Is it valid JSON ? No, and JSONLint could've told you that.
How do you read it in ?
First, wrap your JSON in square brackets so it's valid.
Then, define a class to store the records in:
public class Something
{
public string answer { get; set; }
public string mark { get; set; }
}
And finally, use JSON.Net to convert your string into a list of these records.
string json = "[{\"answer\":\"Line 1\",\"mark\": 1},{\"answer\":\"Line 3\",\"mark\": 1}]";
List<Something> records = JsonConvert.DeserializeObject<List<Something>>(json); // JSON.Net
foreach (Something record in records)
{
System.Diagnostics.Trace.WriteLine(string.Format("Answer: {0}, Mark: {1}", record.answer, record.mark));
}
Easy as that.
Is this json data format?
string json = {"answer":"Line 1","mark": 1},{"answer":"Line 3","mark": 1}
Nope, what you've got there doesn't look like valid C# or JSON. Try putting it inside a JSON array, then inside a proper string:
string json = "[{\"answer\":\"Line 1\",\"mark\": 1},{\"answer\":\"Line 3\",\"mark\": 1}]";
(Hope I've got all the escaping right there.)
That's the C# escaped equivalent of the following JSON:
[{"answer":"Line 1","mark": 1}, {"answer":"Line 3","mark": 1}]
Then read up on JObject.Parse()for more info.
Yes it is json format. But There are multiple objects. You are not looping through it. One way could be
dynamic dynJson = JsonConvert.DeserializeObject(json);
foreach (var item in dynJson)
{
Console.WriteLine("{0} {1}\n", item.answer, item.mark);
}
I'm having troubles de-serializing this JSON string using JSON.NET (note the quotes):
"[]"
Depending on which JSON validation website you go to, this is valid JSON (jsonlint for example says it is).
The JSON.NET code:
void Main()
{
string json = "\"[]\"";
var x = JsonConvert.DeserializeObject<User[]>(json);
Console.WriteLine(x);
}
// Define other methods and classes here
public class User
{
public string Id { get; set; }
public int Age { get; set; }
}
The exception
Error converting value "[]" to type 'UserQuery+User[]'. Path '', line 1, position 4.
Is there a way of forcing JSON.NET to parse this?
Part 1: Is "[]" valid JSON?
There are several documents and standards on JSON, and hundreds of parsers; and some of them suppose that JSON can only be object {} or an array [], but some allow single values like strings, numbers to be used as JSON.
Read this article, it widely describes this problem.
What is the minimum valid JSON?
This dispute on JSON validity is another question. In your case, it doesn't matter, because...
Part 2: why your code isn't working.
Even if we allow non-objects \ non-arrays to be valid JSON, then your JSON represents a single string equal to "[]". It could be anything else, not brackets, it is not an array notation, but just two symbols "[" and "]".
However, you try to parse this JSON as an array of objects, which will anyway result into error.
In other words, even if it is a valid JSON, then it is a valid JSON string, not JSON array.
var str1 = JSON.parse("\"[]\""),
str2 = JSON.parse("\"could be anything else, not brackets\""),
arr = JSON.parse("[]");
console.log(typeof str1);
console.log(typeof str2);
console.log(typeof arr);
var str1_s = JSON.stringify([]);
console.log("Valid JSON of an empty array: " + str1_s);
var arr_s = JSON.stringify("[]");
console.log("Partly valid JSON of a string '[]': " + arr_s);
Part 3: what should you do
The best idea - stop using invalid JSON as input. Tell whoever gave you this JSON that it is invalid JSON array and you cannot use it. You would be able to deserialize a JSON into your array of User if it was correct just like you use it:
string json = "[]";
var x = JsonConvert.DeserializeObject<User[]>(json);
Console.WriteLine(x);
If this JSON is provided from 3rd party services and you can do nothing about that, then you need to tidy it up and make it valid. Yeah, unfortunately, sometimes it happens.
How? It depends on what is your value when there ARE objects (users).
It may be a JSON-serialized JSON-string (double-serialized) like this, and then you need to deserialize a string, and then deserialize an array.
Or it can just have two odd quotes in the beginning and the end, and you can just remove them.
It is valid JSON, but the deserializer failes because the datatypes do not match.
"[]"
Is a string, so the deserializer wants to serialize it to a string.
[]
Is an empty array. So, in short, this should work:
string json = "[]";
var x = JsonConvert.DeserializeObject<User[]>(json);
Console.WriteLine(x);
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.
My C# class is
public class Man
{
public string name {get; set;}
}
String to deserialize is like this
var content = "[{name: \"john\"}]"
Now before saving to db, I was doing check that if string can be deserialized to C# object then store it. This check passes
JsonConvert.DeserializeObject<List<Man>>(content)
So I save this string in db but when I do JSON.parse over saved string in javascript, it crashes with error
JSON.parse("[{name: \"john\"}]")
SyntaxError: Unexpected token n
Now I understand that by surrounding quotes around key ("name") this can be solved. This is correct string that works in both JSON.parse and JsonConvert.DeserializeObject
var content = "[{\"name\": \"john\"}]
Problem is I have many such ill formed strings in db already that crash on JSON.parse only. What is the best way to convert such strings so that JSON.parse will work? Something better than string.replace
Please note that actual strings are quite big and complicated compared to example given.
You can use the using Newtonsoft.Json; it will DeserializeObject object even your json data in var content = "[{name: \"john\"}]" format.
value contains data like :{StyleId:"1710","SelectedItemToColorMap":{1391:"583",21531:"7733"}}
var jsondata = JsonConvert.DeserializeObject(value);
after DeserializeObject the jsondata look like
{
"StyleId": "1710",
"SelectedItemToColorMap": {
"1391": "583",
"21531": "7733"
}
}
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