Handling Byte Order Mark (BOM) character in Json.NET - json

For a .NET Core project, I'm consuming a public API that returns data formatted as JSON. However, some (not all) of their responses have a BOM character at the start of the string, which causes Visual Studio and Json.NET to not recognize the string as valid JSON. As a result, I get an error when using JsonConvert.DeserializeObject() to deserialize the string into my POCO object. I've been told by the API developers that the BOM is included by design, and that I should "set Json.Net to expect that". Is there a way to set Json.NET to handle the BOM without stripping it off the string manually?
Example follows, by request. You can see when the API GET completes successfully, I'm having to trim the BOM manually from the start of the string, otherwise the call to DeserializeObject() fails because the string is not valid JSON.
private static MyPOCO GetObjectFromApi(string url)
{
MyPOCO poco = new MyPOCO();
RestClient client = new RestClient(url);
RestRequest request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
if (response.IsSuccessful)
{
poco = JsonConvert.DeserializeObject<MyPOCO>(response.Content.TrimStart((char)65279)); // trim the byte order marker character at the start of the string
//poco = JsonConvert.DeserializeObject<MyPOCO>(response.Content); // this would throw an error because response.Content is not valid JSON
}
else
{
MyLogger.WriteLog("Api returned failure response");
}
return poco;
}

Related

HttpStringContent Making JSON Invalid?

httpClient = new HttpClient();
stringContent = new HttpStringContent(postBody, UnicodeEncoding.Utf8, "application/json");
httpResponse = await httpClient.PostAsync(uri, stringContent);
String responseString = await httpResponse.Content.ReadAsStringAsync();
Writing a UWP app and trying to send JSON data to a web server. In another method when I serialize an object to JSON postBody = JsonConvert.SerializeObject(parentModel);, I get valid JSON:
"{\"ParentId\":\"uwp#test.com\",\"ParentPrimaryId\":\"uwp#test.com\",\"ParentPassword\":\"n78mG2LB18ANtzr7gd2X/fILNELjbjOMuTWbhWoDvcg=\",\"ParentFirstName\":\"Bill\",\"ParentLastName\":\"Gates\",\"AddChildDistrictId\":\"\",\"RemoveChildDistrictId\":\"\",\"ParentToken\":null,\"ParentDistrictId\":\"\",\"ParentChildDistricts\":\"\",\"AppPlatform\":\"Windows 10.0.15063.138\",\"AppVersion\":10000,\"ParentAccountStatus\":1,\"ParentStatusCode\":0,\"ParentFailedSignInAttempt\":0}"
However, when I pass the post body to HttpStringContent, it gives me:
{{"ParentId":"uwp#test.com","ParentPrimaryId":"uwp#test.com","ParentPassword":"n78mG2LB18ANtzr7gd2X/fILNELjbjOMuTWbhWoDvcg=","ParentFirstName":"Bill","ParentLastName":"Gates","AddChildDistrictId":"","RemoveChildDistrictId":"","ParentToken":null,"ParentDistrictId":"","ParentChildDistricts":"","AppPlatform":"Windows 10.0.15063.138","AppVersion":10000,"ParentAccountStatus":1,"ParentStatusCode":0,"ParentFailedSignInAttempt":0}}
Which is invalid JSON. Is this what is being sent? Why does it add the extra outer brace and remove the beginning quotation marks?
I suspect those are actually the same string at the byte level, and the difference is in how Visual Studio is displaying them to you.
The first example is a syntactically correct C# literal string, surrounded in quotes with internal quotes escaped. The actual string of course doesn't contain backslash characters or starting/ending quotes; those are just required to represent the string in C#.
The second example looks like how Visual Studio's debugging tools display an object and its contents. In this case, the outer {} are how VS tells you it's a object; those characters aren't in the actual string.
So again, I think they are byte-for-byte the same actual string, just represented differently by the IDE.

Jettison can not convert json string to json object when there is an element has empty string value

My application is using camel rest (2.15.2) to catch a POST json String and then uses jettison to convert to a JSON Object. It is working fine with normal request.
POST request: {"request"={"lname"="aaa", "fname"="bb"}}
1. String body = exchange.getIn().getBody(String.class);
2. JSONObject obj = new JSONObject(body);
When i debug, variable body = {request={lname=aaa, fname=bb}}.
And line 2 returns a JSONObject. so far so good
if we try to another the request:
{"request"={"lname"=" ", "fname"="aa"}}
then body = {request={lname= , fname=aa}}
line2 returns Exception.
Could you please help me to fix this issue: convert json string which contains element has empty value string to json object.
The above request is acceptable in my scenarios.
Error:
org.codehaus.jettison.json.JSONException: Missing value. at character
15 of {request={lname= , fname=aa}} at
org.codehaus.jettison.json.JSONTokener.syntaxError(JSONTokener.java:463)
at
org.codehaus.jettison.json.JSONTokener.nextValue(JSONTokener.java:356)
at org.codehaus.jettison.json.JSONObject.(JSONObject.java:230)
at
org.codehaus.jettison.json.JSONTokener.newJSONObject(JSONTokener.java:412)
at
org.codehaus.jettison.json.JSONTokener.nextValue(JSONTokener.java:327)
at org.codehaus.jettison.json.JSONObject.(JSONObject.java:230)
at org.codehaus.jettison.json.JSONObject.(JSONObject.java:311)

How to convert a stream back to json?

In a .NET 3.5 Compact Framework / Windows CE app, I need to consume some WebAPI methods that return json. RestSharp looks like it would be great for this, except that it's not quite CF-ready (see Is Uri available in some other assembly than System in .NET 3.5, or how can I resolve Uri in this RestSharp code otherwise? for details).
So, I will probably use HttpWebRequest. I can return the value from the WebAPI methods with this code:
string uri = "http://localhost:48614/api/departments";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
MessageBox.Show("Content is " + reader.ReadToEnd());
}
else
{
MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
}
...but in order to use what's returned from reader.ReadToEnd():
...I need to convert it back to json so that I can then query the data with LINQ to JSON using either JSON.NET (http://json.codeplex.com/) or SimpleJson (http://simplejson.codeplex.com/)
Is that realistically possible (converting StreamReader data to JSON)? If so, how?
UPDATE
I'm trying to deserialize the "json" (or string that looks like json) with this code:
string uri = "http://localhost:48614/api/departments";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "GET";
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
DataContractJsonSerializer jasonCereal = new DataContractJsonSerializer(typeof(Department));
var dept = (Department)jasonCereal.ReadObject(reader.ReadToEnd());
MessageBox.Show(string.Format("accountId is {0}, deptName is {1}", dept.AccountId, dept.DeptName));
}
...but get two err msgs on the "var dept =" line:
0) The best overloaded method match for 'System.Runtime.Serialization.XmlObjectSerializer.ReadObject(System.IO.Stream)' has some invalid arguments
1) Argument '1': cannot convert from 'string' to 'System.IO.Stream'
So reader.ReadToEnd() returns a string, and DataContractJsonSerializer.ReadObject() expects a stream, apparently. Is there a better approach for this? Or, if I'm on the right track (although currently a section of track has been removed, so to speak), how should I get past this hurdle?
UPDATE 2
I added the System.Web.Extensions reference and then "using System.Web.Script.Serialization;" but this code:
JavaScriptSerializer jss = new JavaScriptSerializer();
var dept = jss.Deserialize<Department>(s);
MessageBox.Show(string.Format("accountId is {0}, deptName is {1}",
dept.AccountId, dept.DeptName));
...but the second line fails with:
"Type 'bla+Department' is not supported for deserialization of an array."
What type should receive the call to jss.Deserialize()? How is it defined?
Well,
the ReadToEnd() method is used to read the stream into a string and output it. If you need a stream out to pass it to a method requiring a stream, you shouldn't use this method.
From what I read on this page , it seems the BaseStream property of your reader would be more appropriate to use then.

JSON accepted format according to Newtonsoft Json

I am trying to parse some JSON objects which is made just of (string,string) pairs, in order to emulate Resjson behaviour. The file I am parsing contains this.
{
"greeting":"Hello world",
"_greeting.comment":"Hello comment.",
"_greeting.source":"Original Hello",
}
Please note the last comma is incorrect, and I also used http://jsonlint.com/ to test JSON syntax. It tells me it is incorrect, as I expected. My - slightly modified - code is :
string path = #"d:\resjson\example.resjson";
string jsonText = File.ReadAllText(path);
IDictionary<string, string> dict;
try
{
dict = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonText);
}
catch(Exception ex)
{
// code never reaches here
}
My above code returns the IDictionary with the 3 keys as if the formatting was correct. If I serialize back, the string obtained is without the last comma.
My questions are :
Is Newtonsoft.Json so permissive that it allows users slight errors ?
If so, can I set the permissiveness so that it is more strict ?
Is there a way to check if a string is valid JSON format, using
Newtonsoft.Json with and/or without the permissiveness?

RestSharp: get JSON string after deserialization?

using RestSharp is there a way to get the raw json string after it has been deserialized into an object? I need that for debugging purposes.
I'd like to see both the deserialized object and the originally received json string of that object. It's part of a much bigger json string, an item in an array and I only need that specific item json code that's got deserialized into the object.
To help you out this should work, this is a direct example of some of my work, so your's might be a bit different.
private void restClient()
{
string url = "http://apiurl.co.uk/json";
var restClient = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddParameter("apikey", "xxxxxxxxxx");
restClient.ExecuteAsync<Entry>(request, response =>
{
lstboxtop.Items.Add(response.Content);
});
}
The line lstboxtop is a listbox and using the response.content will literally print the whole api onto your app, if you call it first that would be what you are looking for