String builder in c# json problem with \" [duplicate] - c#

This question already has answers here:
C# to JSON serialization using JSON.Net
(2 answers)
Closed 2 months ago.
I created an exaple to demonstrate the problem. I am trying by string builder create a json but there is one problem when the Model.Code contains the \".
If the model value contains double quote json is not valid.
public class Model
{
public string Name { get; set; }
public string Code { get; set; }
}
List<Model> list = new List<Model>();
list.Add(new Model()
{
Name = "Test1",
Code = "124565123"
});
list.Add(new Model() {
Name = "Test2",
Code= "123 \"45"
});
list.Add(new Model()
{
Name = "Test3",
Code = "456"
});
var sb = new StringBuilder();
sb.Append($"\"item_name\":\"{list[0].Name}\",");
sb.Append($"\"item_id\":\"{list[0].Code}\",");
sb.Append($"\"item_name\":\"{list[1].Name}\",");
sb.Append($"\"item_id\":\"{list[1].Code}\",");
sb.Append($"\"item_name\":\"{list[2].Name}\",");
sb.Append($"\"item_id\":\"{list[2].Code}\",");
return sb.ToString();

Add reference to Newtonsoft Json.NET library and serialize the list to json
string json = JsonConvert.SerializeObject(list);

since you are using StringBuilder, " will be Considered as " in the String value just like below
"item_name":"Test1","item_id":"124565123","item_name":"Test2","item_id":"123 "45","item_name":"Test3","item_id":"456",
so , if you want to Convert it to Json , then Json will not Consider value with Double Quote In Between.
Moreover, backslash with double quote ' \" ' suppose to Escape Special Character while Converting to json
I am not sure that you want to Keep that special Character in you Json string If yes then In My Opinion you should try by placing double backslash \\" and Double Quote before your Special Character. and json will Accept it
ex.
\\"45

Related

Split string with multiple json strings [duplicate]

This question already has answers here:
What is the correct way to use JSON.NET to parse stream of JSON objects?
(1 answer)
Best ways to split a string with matching curly braces
(2 answers)
Closed 5 years ago.
I am trying to split a c# string that has multiple json strings in it
Example:
{"id":0,"username":"test"}{"id":8,"username":"testuser"}
How can I loop through each json string in its own 'foreach' loop
hi you can do some trikk on invalid json...
string myinvalidJson = "{\"id\":0,\"username\":\"test\"}{\"id\":8,\"username\":\"testuser\"}";
foreach(var item in myinvalidJson.Replace("}{", "}|{").Split('|')) {
...
}
or create valid json and deserialize with newtonsoft
string myinvalidJson = "{\"id\":0,\"username\":\"test\"}{\"id\":8,\"username\":\"testuser\"}";
var validJson = "[" + myinvalidJson.Replace("}{", "},{") + "]";
You may Deserialize it into array of structure type using Newtonsoft.Json
to do this you need to have a string matching an array of JSONs like below:
"[{\"id\":0,\"username\":\"test\"},{\"id\":8,\"username\":\"testuser\"}]"
next lets have strucure type called 'User' like below:
public class User
{
public int Id { get; set; }
public string Username{ get; set; }
}
finally do Deserialize:
string str = "[{\"id\":0,\"username\":\"test\"},{\"id\":8,\"username\":\"testuser\"}]";
User[] res = Newtonsoft.Json.JsonConvert.DeserializeObject<User[]>(str);
Now you are able to do 'foreach' loop on res array.

How to use string interpolation and verbatim string together to create a JSON string literal?

I'm trying to create a string literal representing an array of JSON objects so I thought of using string interpolation feature as shown in the code below:
public static void MyMethod(string abc, int pqr)
{
string p = $"[{{\"Key\":\"{abc}\",\"Value\": {pqr} }}]";
}
Now I thought of using verbatim string so that I don't have to escape double quotes using backslashes. So I came to know through this answer that verbatim string and string interpolation can be used together. So I changed my code as below:
public static void MyMethod(string abc, int pqr)
{
string p = $#"[{{"Key":"{abc}","Value": {pqr} }}]";
}
But it fails to compile. Can anyone help me if there is anything wrong in my usage or it will not be possible to escape double quotes in such a case using string verbatim feature of C#?
The best way is to use JSON serializers as they have in-built handling related to escape characters and other things. See here.
However, if we want to go through this path only to create the JSON string manually, then it can be solved as follows by changing the inner double quotes to single quotes :
public static string MyMethod(string abc, int pqr)
{
string p = $#"[{{'Key':'{ abc}','Value': {pqr} }}]";
return p;
}
I agree with everyone else that building it from strings is a bad idea.
I also understand that you don't want to include an extra dependency.
Here's a bit of code I wrote previously to convert a Dictionary to a JSON string. It's pretty basic, only accepts string types, and doesn't escape quote marks in any of the names/values, but that can be done fairly easily.
If you're trying to serialize a large JSON string from basic types, this is the way I'd recommend to do it. It'll help you stay sane.
private static string DictToJson(Dictionary<string, string> Dict)
{
var json = new StringBuilder();
foreach (var Key in Dict.Keys)
{
if (json.Length != 0)
json = json.Append(",\n");
json.AppendFormat("\"{0}\" : \"{1}\"", Key, Dict[Key]);
}
return "{" + json.ToString() + "}";
}
you can create dictionary and serialize it to json using Json.NET does this.
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("key1", "value1");
values.Add("key2", "value2");
string json = JsonConvert.SerializeObject(values);
// {
// "key1": "value1",
// "key2": "value2"
// }
you can see here more detail : http://www.newtonsoft.com/json/help/html/SerializingCollections.htm

How to read JSON data?

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);
}

How to deserialize Json in a Json?

Here is my json returned by php web application:
{"subtotal":475,"tax":47.5,"discount_section":[{"amount":237.5,"name":"test prior for percentage discount
"}],"grand_total_incl_tax":332.5}
I use c# and json.net to decode the abvoe json
var cart = webClient.DownloadString("http://localhost/m1/pos_addToCart.php?pidstr=" + pid_str);
dynamic result = JObject.Parse(cart);
But there is an error on this line:
order_discount_section.Text = result.discount_section;
Error:
Cannot implicitly convert type 'Newtonsoft.Json.Linq.JToken' to 'string'
How to convert this json to String like:
Key1 = Value1
Key2 = Value2
Key3 = Value3
Based upon your supplied json discount_section is a map so it can't be expressed as a string. It's like trying to convert a dictionary to a string or an array to a string.
If you want it as a string representation then adding ToString() after the result.discount_section (i.e. result.discount_section.ToString()) should accomplish that.
Though I would suggest that you either store the data through placeholder values such as:
string name = result.discount_section[0].name (same with amount but float/decimal/double...).
Or if you wanted it as text have it as
text = "Name: " + result.discount_section[0].name
+ "Amount: " + result.discount_section[0].amount.ToString();`
Obviously using a stringbuilder or other tool would be better (such as string.format) but I'll leave that as an 'exercise' to you.
Edit:
The for loop for all of the results.
totalText = ""
for (i = 0; i < result.discount_section.length; i++) {
totalText += "Name: " + result.discount_section[i].name + "Amount: " + result.discount_section[i].amount.ToString() + "\n";
}
Obviously if you wanted an array of strings then you would just build an array then just use i as your string array index as well.
Json.NET provides a correct behaviour.
As from your example string, it can be seen, that discount_section is a json array, or JArray, descendant of JToken after parsing to JObject.
If you want to access inner member of this array, as name for example, you should call it as
order_discount_section.Text = result.discount_section[0].name;
If you want to write the full notation of discount_section as is, you should explicitly call ToString method:
order_discount_section.Text = result.discount_section.ToString();
Although, dealing with dynamics is not useful, while your working with separate service responsing in JSON. It will be better to define a single class, which will handle json values, so you could not only look what json is passing, but to work with it
You may consider working with objects and deserialize using JsonConvert.DeserializeObject. Example:
class Discount
{
public Decimal Amount { get; set; }
public String Name { get; set; }
}
class Response
{
public Decimal Subtotal { get; set; }
public Decimal Tax { get; set; }
public List<Discount> Discount_section { get; set; }
public Grand_total_incl_tax { get; set; }
}
var response = JsonConvert.DeserializeObject<Response>(cart);
This approach is good when object structure is relatively fixed and has the following advantages:
clear structure
relevant errors when you have a type mismatch (JSON -> property)
result.discount_section is collection. you can not set directly to string variable.
try this.
var result= JObject.Parse(cart);
dynamic[] discountSection = result["discount_section"].ToArray<dynamic>();
decimal amount = discountSection[0].amount;
decimal name = discountSection[0].name;
for dictionary
Dictionary<string,decimal> discountDictionary = discountSection.ToDictionary<dynamic, string, decimal>((d) => d.name, (d) => d.amount);

Store Hardcoded JSON string to variable

I'm having an issue storing this json string to a variable. It's gotta be something stupid I am missing here
private string someJson = #"{
"ErrorMessage": "",
"ErrorDetails": {
"ErrorID": 111,
"Description": {
"Short": 0,
"Verbose": 20
},
"ErrorDate": ""
}
}";
You have to escape the "'s if you use the # symbol it doesn't allow the \ to be used as an escape after the first ". So the two options are:
don't use the # and use \ to escape the "
string someJson = "{\"ErrorMessage\": \"\",\"ErrorDetails\": {\"ErrorID\": 111,\"Description\":{\"Short\": 0,\"Verbose\": 20},\"ErrorDate\": \"\"}}";
or use double quotes
string someJson =#"{""ErrorMessage"": """",""ErrorDetails"": {""ErrorID"": 111,""Description"": {""Short"": 0,""Verbose"": 20},""ErrorDate"": """"}}";
First things first, I'll throw this out there: It's for this reason in JSON blobs that I like to use single quotes.
But, much depends on how you're going to declare your string variable.
string jsonBlob = #"{ 'Foo': 'Bar' }";
string otherBlob = #"{ ""Foo"": ""Bar"" }";
...This is an ASCII-encoded string, and it should play nicely with single quotes. You can use the double-double-quote escape sequence to escape the doubles, but a single quote setup is cleaner. Note that \" won't work in this case.
string jsonBlob = "{ 'Foo': 'Bar' }";
string otherBlob = "{ \"Foo\": \"Bar\" }";
...This declaration uses C#'s default string encoding, Unicode. Note that you have to use the slash escape sequence with double quotes - double-doubles will not work - but that singles are unaffected.
From this, you can see that single-quote JSON literals are unaffected by the C# string encoding that is being used. This is why I say that single-quotes are better to use in a hardcoded JSON blob than doubles - they're less work, and more readable.
Simple Approach is to copy the JSON to a .json file and read that file in the code
string jsonData = string.Empty;
jsonData = File.ReadAllText(#"\UISettings.json");
Writing JSON inline with c# in strings is a bit clunky because of the double quotes required by the JSON standard which need escaping in c# as shown in the other answers. One elegant workaround is to use c# dynamic and JObject from JSON.Net.
dynamic message = new JObject();
message.ErrorMessage = "";
message.ErrorDetails = new JObject();
message.ErrorDetails.ErrorId = 111;
message.ErrorDetails.Description = new JObject();
message.ErrorDetails.Description.Short = 0;
Console.WriteLine(message.ToString());
// Ouputs:
// {
// "ErrorMessage": "",
// "ErrorDetails": {
// "ErrorID": 111,
// "Description": {
// "Short": 0
// .....
See https://www.newtonsoft.com/json/help/html/CreateJsonDynamic.htm.
I had this same problem I ended up writing an open source online converter that takes a JSON string and spits out the C# excaped string with the double quotes syntax. So
{ "foo":"bar"}
will be escaped into
var jsonString = #"{ ""foo"":""bar""}";
https://json-to-c-sharp.ndolestudio.com
https://github.com/AchoArnold/json-to-c-sharp
Starting from C# 11 supported on .NET 7, it's possible to embed a JSON string without any modification by enclosing it in triple quote characters, a feature called Raw string literal (learn.microsoft.com). Related useful language feature is StringSyntaxAttribute that allows Visual Studio to recognize the string variable is a JSON string and highlight any typos. A sample:
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
internal class Program
{
[StringSyntax(StringSyntaxAttribute.Json)]
private const string myCountry = """{"Name": "Slovakia", "CountryCode": 421}""";
private static void Main(string[] args)
{
var _ = JsonSerializer.Deserialize<Country>(myCountry);
}
class Country
{
public string Name { get; set; } = default!;
public int CountryCode { get; set; }
}
}
A Put the cart before the horse solution would be to serialize a anonymous class into a string:
var someJson = JsonConvert.SerializeObject(
new
{
ErrorMessage = "",
ErrorDetails = new
{
ErrorID = 111,
Description = new
{
Short = 0,
Verbose = 20
},
ErrorDate = ""
}
});
If you are using Visual Studio, then Select the whole JSON string then crtl+f to find the double quotes in the selection and then replace " with ""

Categories