JSON string failing in JSON.parse but passes JsonConvert.DeserializeObject - c#

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"
}
}

Related

How do I format a one line JSON string

I'm creating a GUI in Visual Studio which is going to fetch JSON data from an API to display in a text box, and I want it to be displayed formatted so it's readable.
I have tried to use the Newtonsoft.Json library to solve the problem, but it seems like it does not work on one liners of JSON and must take an object containing different types of JSON data.
using (WebClient wc = new WebClient())
{
string API_Key = "000000000000000000000"; // URL with API key containing the JSON data
string JSON_Data_URL = $"https://www.nobil.no/api/server/datadump.php?apikey={API_Key}&countrycode=NOR&fromdate=2005-01-01&format=json";
LoadJSON.Increment(-100); // Reset loadbar
string JSON_Data = JsonConvert.SerializeObject(wc.DownloadString(JSON_Data_URL), Formatting.Indented); // Format JSON data
DataResults.Text = JSON_Data; // Add JSON data to textbox
LoadJSON.Increment(100); // Display when the JSON data is fetched
}
I thought it would output an formatted JSON string, but seems like it instead is just adding backslashes to the JSON. I also tried to replace the backslashes with a new line and 4 spaces, but that didn't look right either.
Edit
This is not a duplicate as the problem seemed to be that I needed to convert the string to an object.
The problem is, that you are serializing a string and not an object.
string JSON_Data = "..." // Get your json from your API
object JSON_Object = JsonConvert.DeserializeObject(JSON_Data);
string JSON_Data_Formatted = JsonConvert.SerializeObject(JSON_Object, Formatting.Indented);

Is "[]" valid JSON?

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

Json get array object from JSON Object C#

I have this json string passed to my webapi
string jsonstring = "{\"datamodel\": \"[{\"K1\":\"V1\",\"K2\":\"V2\"}]\"}";
I may have more than on pair of (K,V) inside. How do i parse this in C# ?
I thought i could first convert my string to a JObject and get the key for datamodel from that and then use JArray to parse the K,V. But its throwing a jsonreader exception on the first line of code here
JObject my_obj = JsonConvert.DeserializeObject<JObject>(jsonstring.ToString());
and then do this..
JObject data = my_obj["datamodel"].Value<JObject>();
First of all, the JSON string you are posting is not valid. Given your comment, you can clean up the quotes before and after the square brackets using this snippet:
string jsonstring = "{\"datamodel\": \"[{\"K1\":\"V1\",\"K2\":\"V2\"}]\"}";;
string jsonstringCleaned = jsonstring.Replace("\"[", "[").Replace("]\"", "]");
var my_obj = JsonConvert.DeserializeObject<JObject>(jsonstringCleaned);
The code is right, but the exception you are getting is related to the formatting of your JSON string. If you put valid JSON in this code, it should work as expected.
There are \" missing around V1 in your JSON string.
It should look like this:
string jsonstring = "{\"datamodel\": \"[{\"K1\":\"V1\",\"K2\":\"V2\"}]\"}";
First always make sure that you have a valid Json string. A simple way to do that is paste it into a Json to C# converter tool, such as this one: http://json2csharp.com/
It may be simpler and more readable to use single quotes within your Json string if that is an option, as it avoids the need to escape the double quotes:
string jsonstring = "{'datamodel': [{'K1':'V1','K2':'V2'}]}"
Now we deserialize the object and get the JArray. There is no need to call the ToString() on the JSON jsonstring string.
var my_obj = JsonConvert.DeserializeObject<JObject>(jsonstring);
var data = (JArray)my_obj["datamodel"];
A better and more concise way to accomplish the same result could be to just use JObject.Parse. We can accomplish the same result with just one line of code.
var data = (JArray)JObject.Parse(jsonstring)["datamodel"];

string being appened to json output

I am trying to use json.net to produce a web service but I am a bit perplexed as to why < string > is showing in the dummy data
[WebMethod]
public string getCustomerInfo(string IVACode)
{
var customerData = _dal.apertureAppstblCustomers.Where(a => a.IVACode == IVACode).ToList();
var jsonstring = JsonConvert.SerializeObject(customerData);
return jsonstring;
}
ie its starting like <string> and ending </string> how do i get it to display CustomerInformationinstead of string is it good practise to be naming the nodes?.
[{"id":"7aee450a-a9a7-4f19-83d3-467a3b8a39c0","IVACode":"IVA002","FirstName":"Peter","LastName":"Carson","AddressLine1":"Waters Edge Belfast","AddressLine2":null,"Town":"Belfast","County":"Down","PostCode":"BT99YXX","Telephone":null,"EmailAddress":"email","isActive":true,"authUserName":null,"authCreatedDate":null,"personalProgressValue":null,"contributionsToDate":null,"totalContributions":null,"totalArrears":50000.00,"totalPaid":null,"isDeleted":false,"deviceId":null,"deviceOs":null}]
You will need to convert the serialized string back to your object and then consume it to show the relevant information.
Example below.
JsonConvert.DeserializeObject(jsonstring)
You shouldn't get that in the serialized string but you can replace those tokens using Replace() string function like
jsonstring = jsonstring.Replace("<string>","").Replace("</string>","");

Retrieve Json from service and pass to ApiController

I want to directly capture JSON from an external API in a service layer, return that to a MVC 4 ApiController, and then output the JSON through that ApiController. I'm basically writing a wrapper around another API service because some other actions have to happen at the same time (authentication, etc). The problem is that the JSON gets converted to a string and is passed around as a string in my C# code. This just adds escape characters to the JSON. Is there anyway I can just pass the JSON object around in my C# code? Details of my implementation are below.
In a service layer, I'm consuming an API that provides JSON via the method below.
return new WebClient().DownloadString(url);
Unfortunately this returns a string. As this API is already returning JSON to me this is problematic because lots of escape characters get added to the string.
The JSON should look something like this
[{"Citation":{"Attachments":[{"AttachedPersonIds":null,..."Type":"Record"}]
But instead it now looks like this
"[{\"Citation\":{\"Attachments\":[{\"AttachedPersonIds\":null,...\"Type\":\"Record\"}]"
After I get this string I return it through a couple of methods to an ApiController (which is setup to return JSON) like this.
public class HintsController : ApiController
{
public string Get(string treeId, string personId)
{
return _hintService.GetHints(treeId, personId);
}
}
I've tried to convert the string to a Literal string and tried serializing the string again. Doing this just adds more escape characters and doesn't solve the problem. I think the problem is with how I'm consuming the initial call because it's casting it from JSON to a string. But I don't know how to avoid this.
Thanks in advance for any ideas.
Because the controller returns a string, the JSON formatter is serializing the entire string to a JSON string and escaping the embedded quote characters.
You can do something like this:
public HttpResponseMessage Get()
{
var resp = new HttpResponseMessage()
{
Content = new StringContent("{json here...}")
};
resp.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/json");
return resp;
}
This assumes that you always want to return JSON.
You can turn it into a dynamic object and pass that around, if you really want to pass the objects.
I can't tell where the literal escape characters are coming from, can you be a little more clear on that. Is the API generating them, or is there some other point in our code? I've seen them in the debug window before, when the string didn't actually contain them, and printing/etc worked normally.
You can use Json.net (standard), the built in serializer, https://github.com/jsonfx/jsonfx and others .
From the jsonfx site:
var reader = new JsonReader(); var writer = new JsonWriter();
string input = #"{ ""foo"": true, ""array"": [ 42, false, ""Hello!"", null ] }";
dynamic output = reader.Read(input);
Console.WriteLine(output.array[0]); // 42
string json = writer.Write(output);
Console.WriteLine(json); // {"foo":true,"array":[42,false,"Hello!",null]}
There are a few other ways ways, see these threads:
Deserialize json object into dynamic object using Json.net
Deserialize JSON into C# dynamic object?

Categories