How to parse JSON while using variables? - c#

I am parsing JSON using C#
This code works fine:
var json = webClient.DownloadString("API KEY");
Newtonsoft.Json.Linq.JObject o = Newtonsoft.Json.Linq.JObject.Parse(json);
Console.WriteLine(DefindexS);
price = (double)o["response"]["prices"]["5021"]["6"]["0"]["current"]["value"];
currency = (string)o["response"]["prices"]["5021"]["6"]["0"]["current"]["currency"];
Console.WriteLine("price" + price);
Console.WriteLine("Currency" + currency);
It prints correctly
price7.11
Currencymetal
here is the catch. The "5021" in both the cases above needs to be replaced by a variable which is set by the user. The JSON data is alright. as long as the number is correct, it will return a proper value.
The variable is DefindexS. I tried parsing by replacing "5021" by DefindexS (I have set the value to 5021) but it gave me an Unhandled Exception error.
Then I tried to format it and did this:
string realdef = String.Format("\"{0}\"", DefindexS.ToString());
Console.WriteLine(realdef);
var json = webClient.DownloadString("API KEY");
Newtonsoft.Json.Linq.JObject o = Newtonsoft.Json.Linq.JObject.Parse(json);
price = (double)o["response"]["prices"][realdef]["6"]["0"]["current"]["value"];
currency = (string)o["response"]["prices"][realdef]["6"]["0"]["current"]["currency"];
Console.WriteLine("price" + price);
Console.WriteLine("Currency" + currency);
The outcome:
"5021"
and then it crashes.. realdef prints as "5021" so the formatting happened properly. Why am I still getting an error?

You don't have to add the quotes around your variable. So this line of code is not needed:
string realdef = String.Format("\"{0}\"", DefindexS.ToString());
It should work when you change it to
string realdef = DefindexS.ToString();

Related

C# How to get rid of "\" from JSON?

I have following C# code which generates output like this:
Task<OnlineResponse> task = client.Execute(query);
OnlineResponse response = task.Result;
Result result = response.Results[0];
dynamic resultJson = JsonConvert.SerializeObject(result.Data);
var x = Regex.Replace(resultJson.ToString(), #"[\[\]']+", "");
return x;
This is output:
"{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756289-919567--
accrual\",\"BATCH_DATE\":\"02/01/2022\"}},
{\"GLDETAIL\":{\"RECORDNO\":\"264378-1756290-919568--
accrual\",\"BATCH_DATE\":\"02/01/2022\"}}"
I am trying to get rid of all backslashes.
I applied "Regex.Replace", but it would not work.
This is expected output:
"{"GLDETAIL":{"RECORDNO":"264378-1756289-919567--
accrual","BATCH_DATE":"02/01/2022"}},
{"GLDETAIL":{"RECORDNO":"264378-1756290-919568--
accrual","BATCH_DATE":"02/01/2022"}}"
you serialized json string twice. just return the result.Data as it is. its already a json string. if you remove backslashes you wont be able deserilze the object.

Why am I getting FormatException on this?

I am trying to convert a System.string to a System.double, the input is: He: 4.002602 amu
Code:
string[] data = line.Replace(" ", "").Replace("amu", "").Split(new char[] { ':' });
double i = Convert.ToDouble(data[1]);
I have tried:
string[] data = line.Replace(" ", "").Replace("amu", "").Split(new char[] { ':' });
double i = Convert.ToDouble(data[1], CultureInfo.InvariantCulture);
You can use following regular expression without splitting a string which mixed with number and words:
// using System.Text.RegularExpressions
var resultString = Regex.Match(line, #"\d.\d+").Value;
If format of input is something+blank+doubleNumber+blank+something you can use following code:
string line = "He: 4.002602 amu";
int intLspacePos = line.IndexOf(" ") + 1;
int intRspacePos = line.LastIndexOf(" ");
string strNumber = line.Substring(intLspacePos, intRspacePos - intLspacePos);
double dblNumber = Convert.ToDouble(strNumber);
Instead of Convert.ToDouble() use the double.Parse() method, preferably using the invariant culture when the user input is always using a period sign as decimal separator.
So try something like this:
double i = double.Parse(data[1], CultureInfo.InvariantCulture);
EDIT:
I've seen in the screenshot you posted in the comments above that you're not actually checking the contents of data[1] before passing it to the Convert.ToDouble method.
According to MSDN the only case when a FormatException is thrown should be when providing a non-numeric text value (see here). Therefor I'd suggest to add a check for empty strings and null values before, passing the value to the Convert.ToDouble() method. Try updating your code to something like this:
foreach (string line in raw) {
string[] data = line.Replace(" ", "").Replace("amu", "").Split(new char[] { ':' });
if (!string.IsNullOrWhiteSpace(data[1]) {
double i = Convert.ToDouble(data[1], CultureInfo.InvariantCulture);
} else {
// Invalid value in data[1]
// Maybe set a breakpoint here and investigate further if necessary
}
}
If this still throws a FormatException then the contents of data[1] must be some non-numeric and non-empty text value, so in that case you should probably check the contents of the data array using the debugger and find out how / why that invalid value got there.
you can convert with specific culture info as below. 2057 is LCID for English (UK).
double i = Convert.ToDouble(data[1], CultureInfo.GetCultureInfo(2057));

How to parse JSON objects with double quotes in one of its property values

If I have a json string, with one of its property values having a double quote in it, I am not able to parse it.
For example, if my object is { "Name" : "Six \" Pipe" } then the following gives me an error - Unexpected token P.
var str = '{ "Name" : "Six \" Pipe" }';
JSON.parse(str); //error
$.parseJSON(str); //error
The string is formed in a razor view as follows -
var str = new JavaScriptSerializer().Serialize(obj);
And then in JavaScript I am doing
var obj = JSON.parse('#(Html.Raw(str))');
How can I parse such strings?
You should escape the backslashes since in JS it will only \" will be converted to " and will make the JSON incorrect. The blackslash is discarded by javascript.
so the correct string would be-
var str = '{ "Name" : "Six \\" Pipe" }';
JSON.parse(str); //works
Edit:
So, if you want to create a literal backslash in JS, you have to escape it. You can do this while creating this string and double-escaping the key's value. One way to tackle this could be -
To html encode the strings (key values) just like: " instead of \" etc. This seems straight forward to me with .Net. I'm not sure but HttpServerUtility.HtmlEncode could help. Then on the javascript side you could be able to parse straight away- fiddle
I encountered same issue. After spending a lot of time trying to deal with that quotes I came to this solution
#{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var obj = new {name = "\"Name1\""};
var objJson = serializer.Serialize(obj);
}
<script>
var jsObject = #Html.Raw(objJson);
</script>
I use json as js object without any parsing, html result will be like
<script>
var jsObject = {"name":"\"Name1\""} ;
</script>
which is correct JavaScript. Hope it will be helpfull for somebody

Newtonsoft Json.Net correct parsing of string arrays inside a JSON object

I have the following problem, I want to parse a Json object I get passed by a url query string
e.g.
...&json={tags=[tag1,tag2]}
I have used
JsonConvert.DeserializeObject<Dictionary<string, object>>(json)
But when calling the Deserialize method I get an error
Newtonsoft.Json.JsonReaderException : Unexpected character encountered while parsing value: d. Line 1, position 8.
If I pass in the string
"{tags:[\"tag1\",\"tag2\"]}
It works fine, I don't want my users to have to add the "" quotes
Is there a way to work around this problem?
pseudocode For a solution could be...
Grab the json query string element.
Split on first equals "=".
Grab all text between "{tags=[" and "]}"
Take that text split on ","
trim any whitespace off of the items.
Join them back together but put quotes around them and coma delimited them.
put that value back inbetween "{tags=[" and "]}" ie "{tags=[" + newValue+ "]}"
Here is some sample C# code...
[Test]
public void TestHack()
{
string almost = "{tags=[tag1,tag2]}";
string json = this.HackToJson(almost);
Trace.WriteLine(json);
}
public string HackToJson(string almostJson)
{
if( almostJson.StartsWith("{tags=[") && almostJson.EndsWith("]}"))
{
int tagsLen = "{tags=[".Length;
string tags = almostJson.Substring(tagsLen, almostJson.Length - (tagsLen + 2));
var items = tags.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var itemsCleaned = (from c in items select "\"" + c.Trim() + "\"");
var jsonpart = string.Join(",", itemsCleaned);
var json = string.Format("{{tags=[{0}]}}", jsonpart);
return json;
}
throw new NotImplementedException("not sure what to do here... ");
}

Json.NET: Deserilization with Double Quotes

I am trying to deserialize a json string received as a response from the service. The client is Windows Phone 7, in C#. I am using Json .NET - James Newton-King deserializor to directly convert the Json string to objects. But sometimes the Json string contains some comments information with double quotes (") in them and the deserializer fails and throws an error. Looks like this is an invalid Json string according to Jsonlint.
{
"Name": "A1",
"Description": "description of the "object" A1"
}
How to handle such Json String. If it is (\"), then it works. But I cannot replace all (") with (\") as there might be double quotes in other part of the json string. Is there any decode function of Json .Net?
It looks like HttpUtility.JavaScriptStringEncode might solve your issue.
HttpUtility.JavaScriptStringEncode(JsonConvert.SerializeObject(yourObject))
Just do:
yourJsonString = yourJsonString.Replace("\"", "\\u022");
object o = JSonConvert.Deserialize(yourJsonString);
\u022 is the ascii code for double quotes. So replacing quotes for \u022 will be recognized by your browser.
And use \ in "\u022" to make c# recognize backslash character.
Cheers
You can improving this.
static private T CleanJson<T>(string jsonData)
{
var json = jsonData.Replace("\t", "").Replace("\r\n", "");
var loop = true;
do
{
try
{
var m = JsonConvert.DeserializeObject<T>(json);
loop = false;
}
catch (JsonReaderException ex)
{
var position = ex.LinePosition;
var invalidChar = json.Substring(position - 2, 2);
invalidChar = invalidChar.Replace("\"", "'");
json = $"{json.Substring(0, position -1)}{invalidChar}{json.Substring(position)}";
}
} while (loop);
return JsonConvert.DeserializeObject<T>(json);
}
Example;
var item = CleanJson<ModelItem>(jsonString);
I had the same problem and i found a possible solution. The idea is to catch the JsonReaderException. This exception bring to you the attribute "LinePosition". You can replace this position to an empty character (' '). And then, you use this method recursively until whole json is fixed.
This is my example:
private JToken processJsonString(string data, int failPosition)
{
string json = "";
var doubleQuote = "\"";
try
{
var jsonChars = data.ToCharArray();
if (jsonChars[failPosition - 1].ToString().Equals(doubleQuote))
{
jsonChars[failPosition - 1] = ' ';
}
json = new string(jsonChars);
return JToken.Parse(json);
}
catch(JsonReaderException jsonException)
{
return this.processJsonString(json, jsonException.LinePosition);
}
}
I hope you enjoy it.
I would recommend to write email to server admin/webmaster and to ask them fix this issue with json.
But if this is impossible, you can write simple parse that finds nonescaped doublequotes inside doublequotes and escapes them. It will hardly be >20lines of code.
you can use newtonsoft library to convert it to object( to replace \" with "):
dynamic o = JObject.Parse(jsondata);
return Json(o);

Categories

Resources