Getting error parsing a Json response from a service c# - c#

I am consuming an api from a .NET project and I am getting a json response, but I can't parse it correctly using Newtonsoft.Json.
I want to get the values like eda50ef6a96442088e88401ffb4846df or 965507aad38245b1b7cc62a397c9af2e. I also checked this json with an online json validator and it says it's wrong. What should I do? Any help?
{
"resp": {
"state": "ok",
"Query": {
"Header": {
"Cell": {
"HeaderName": "Guid",
"Type": "System.Guid"
}
},
"Row": {
"Cell": {
"name": "Guid",
"eda50ef6a96442088e88401ffb4846df"
}
},
"Row": {
"Cell": {
"name": "Guid",
"965507aad38245b1b7cc62a397c9af2e"
}
}
}
}
}
I also put here the response of the service in xml format.
<resp state="ok">
<Query>
<Header>
<Cell>
<HeaderName>Guid</HeaderName>
<Type>System.Guid</Type>
</Cell>
</Header>
<Row>
<Cell name="Guid">eda50ef6a96442088e88401ffb4846df</Cell>
</Row>
<Row>
<Cell name="Guid">965507aad38245b1b7cc62a397c9af2e</Cell>
</Row>
</Query>
</resp>

As others have already pointed out, the "JSON" being produced by this API is definitely invalid as it does not conform to the JSON standard.
I want to address the second part of your question, "What should I do?"
Obviously, if you control the project or API which is producing this JSON, then you should fix it to make it produce valid JSON. Instead of hand-coding the output (which is most likely how this output came to be) you should instead build up objects in memory (using nested dictionaries and lists would be a good choice here) and then serialize them using a proper JSON serializer like Json.Net. The serializer will be able to turn them into correct JSON for you.
If you do NOT control the sproject or API which is producing this JSON, then you should definitely notify the project author that it is producing invalid output and ask them to fix it, if possible.
If the project owner cannot be contacted, or s/he can't or won't fix it, or if you don't have time to wait for a proper fix, then you should switch to using the XML version instead. This looks to be correctly formatted and you should be able to consume this without any trouble using standard XML classes like LINQ-to-XML.
If you absolutely must have JSON to work with, for whatever reason, then you can try using Json.Net to convert the XML response directly into JSON using JsonConvert.SerializeXNode:
string json = JsonConvert.SerializeXNode(XElement.Parse(xml), Formatting.Indented);
However, there are some potential pitfalls with this approach, notably that the conversion process can produce different JSON depending on the number of nodes in the XML. See Converting between JSON and XML for more information.
With the XML shown in your question, SerializeXNode would produce this JSON:
{
"resp": {
"#state": "ok",
"Query": {
"Header": {
"Cell": {
"HeaderName": "Guid",
"Type": "System.Guid"
}
},
"Row": [
{
"Cell": {
"#name": "Guid",
"#text": "eda50ef6a96442088e88401ffb4846df"
}
},
{
"Cell": {
"#name": "Guid",
"#text": "965507aad38245b1b7cc62a397c9af2e"
}
}
]
}
}
}

It looks like the JSON is malformed to me... particularly here:
"Row": {
"Cell": {
"name": "Guid",
"eda50ef6a96442088e88401ffb4846df"
}
Note that the string you want to get has no "Key" name. So the Cell Key has a value which is a JSON object with a name Key (whose value is "Guid"), but the long string has no key name.
It should have a key for that value, something like this:
"Row": {
"Cell": {
"name": "Guid",
"value": "eda50ef6a96442088e88401ffb4846df"
}
For the JSON to be valid, it needs to consist of key/value pairs.

Related

Schema validation using TypenameHandling.All and List<T>

i have a problem using the Newtonsoft.Json.Schema NuGet (version 3.0.11) with my Settings-Editor application. The GUI receives a list of settingsfiles (serialized as json) and json schemas for each type of settingsfile. The user can now edit the settingsfiles which are then validated against the schema for the respective file.
I (de-)serialize all my applicationspecific settings using TypeNameHandling = TypeNameHandling.All because there could be inherited types located within the specific settingsfile.
I generate the JSON schema on my settings class using NewtonSoft.Json.Schema like this:
new JSchemaGenerator().Generate(setting.GetType())
When i am trying to validate a live-edited string against the previously generated schema, i get the following ValidationError on the line of the ListOfItems-property:
Invalid type. Expected Array, Null but got Object.
The JSON of the serialized List looks like that:
{
...
"ListOfItems": {
"$type": "System.Collections.Generic.List`1[[MySubSettingsClass, MyAssembly]], mscorlib",
"$values": [
{
"$type": "MySubSettingsClass, MyAssembly",
...
}]
}
}
The Schema looks like that:
"ListOfItems": {
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/MySubSettingsClass"
}
},
Somehow, the schema validation is not able to interprete the list-type as an array.
I already tried replacing my list with an array of these sub-settings, but that gives me the same error:
{
"$type": "MySettingsClass, MyAssembly",
"ListOfItems": {
"$type": "MySubSettingsClass[], MyAssembly",
"$values": [
{
...
}
}
}
Can i solve that problem by using some kind of attributes above my list-property?

.NET MongoDB: Deserialize BsonDocument from BsonType Array

I look for the answer but nothing helps, so I post the question again, hope someone could help me out.
Let's say I have a simple JSON string like this:
[
{
"id": 1,
"name": "A"
},
{
"id": 2,
"name": "B"
}
]
And here is my code to parse that JSON into BsonDocument
using (var jsonreader = new JsonReader(json_data))
{
var context = BsonDeserializationContext.CreateRoot(jsonreader);
//Bson Array, how to deserialize???
var document = collection.DocumentSerializer.Deserialize(context);
collection.InsertOne(document);
}
It will return the error "System.FormatException: 'Cannot deserialize a 'BsonDocument' from BsonType 'Array'.'
If you want to directly convert Json to BsonDocument you should do it as following:
BsonDocument document = BsonDocument.Parse(json_data.toString());
You might want to share more of your code to give clearer picture of what are you trying to do. Anyway, I hope this sorts your issue.

Efficient method to work with JSON

I receive this JSON response:
{
"status": "Ok",
"total": 105373,
"result": [
{
"id": 668839,
"cn": "A-12157-68812",
"pD": "09-12-2012",
"cCD": "06-05-2012",
"cT": "PERM",
"fN": "COMCAST CABLE COMMUNICATIONS, LLC",
"s": "NJ",
"cR": "Certified",
"pT": "ENGINEER 3",
"vC": 6,
"cddt": "html"
},
{
"id": 725695,
"cn": "A-12361-25668",
"pD": "05-28-2013",
"cCD": "12-26-2012",
"cT": "PERM",
"fN": "L'ONVIE INC.",
"s": "NY",
"cR": "Certified",
"pT": "Biochemist",
"vC": 6,
"cddt": "html"
},
{
"id": 0,
"cn": "A-11199-93239",
"pD": "05-31-2012",
"cCD": "07-18-2011",
"cT": "PERM",
"fN": "ROCKWELL AUTOMATION, INC.",
"s": "PR",
"cR": "Certified",
"pT": "Marketing Managers",
"vC": -1
}]
}
What is the best way to convert this into an object so that I can apply various LINQ transforms to query for some meaningful data?
What is the efficient way to do this?
Should I create classes like:
public class Status {
string Status {get; set;}
int Total {get; set;}
IEnumerable<Result> Results {get; set;}
}
public class Result {
string Id {get; set;}
..................
}
And then figure out mapping/casting?
If you are using a recent version of Visual Studio you can use Edit > Paste Special > Paste JSON as Classes. This will save you loads of time:)
You will need to create your own classes if you are doing anything more than simple operations on the data. You can rename the fields from Json to more suitable names by using data attributes.
It depends on which deserializer you use though - Json.net or a built in .net version.
Try searching for dataContract and dataMember if you use a built-in .net deserializer or jsonProperty if you use json.net
Try Json.NET. Check out this docs about LINQ queries. You can even use Json.NET to map your JSON to .NET objects automatically.

Can I LINQ a JSON?

This is the JSON I get from a request on .NET:
{
"id": "110355660738",
"picture": {
"data": {
"url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn2/1027085_12033235063_5234302342947_n.jpg",
"is_silhouette": false
}
}
}
and I'd like to catch the field "url", using (maybe?) LINQ. I do many request as this, that differents a bit. So I won't to create a C# Class and deserialize it every time.
Is it a way to extract a single field? Thank you!
No need for Linq, just use dynamic (using Json.Net)
dynamic obj = JObject.Parse(json);
Console.WriteLine((string)obj.picture.data.url);
Linq version would not be much readable
JObject jObj = JObject.Parse(json);
var url = (string)jObj.Descendants()
.OfType<JProperty>()
.Where(p => p.Name == "url")
.First()
.Value;
Documentation: LINQ to JSON
I would not recommend LINQ. I would recommend a JSON library such as newtonsoft.json.
So you can do this:
string json = #"{
""Name"": ""Apple"",
""Expiry"": "2008-12-28T00:00:00",
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
string name = (string)o["Name"];
// Apple
JArray sizes = (JArray)o["Sizes"];
string smallest = (string)sizes[0];
// Small
Note:- this code has been copied from the samples present on the project site
http://james.newtonking.com/pages/json-net.aspx
In a bind you could always deserialize the JSON and serialize it to XML, and load the XML in a XDocument. Then you can use the classic Linq to XML. When you are done take the XML, deserialize it, and serialize it back to JSON to JSON. We used this technique to add JSON support to an application that was originally built for XML, it allowed near-zero modifications to get up and running.
You can easily query with LINQ like this
considering this JSON
{
"items": [
{
"id": "10",
"name": "one"
},
{
"id": "12",
"name": "two"
}
]
}
let's put it in a variable called json like this,
JObject json = JObject.Parse("{'items':[{'id':'10','name':'one'},{'id':'12','name':'two'}]}");
you can select all ids from the items where name is "one" using the following LINQ query
var Ids =
from item in json["items"]
where (string)item["name"] == "one"
select item["id"];
Then, you will have the result in an IEnumerable list

Parsing JSON in C#

I have a JSON string that I am sending to a c# server. It comprises an array of Event objects and an Array of relationship objects. The relationship objects describe the database table relationships.
However I'm having trouble getting data from the the JSON at the server. The object doesn't exist on the server to deserailize into and JSON.net throws parse errors when I try the following:
// Both throw parse errors
JObject o = JObject.Parse(Request.Form.ToString());
JsonConvert.DeserializeObject<MobileEvents>(Request.Form.ToString());
the JSON:
{
"CreateEvents": {
"Event": [
{
"Id": "1",
"Subject": "Hire a Clown"
}
],
"Relationship": [
{
"Primary": "Table1",
"Secondary": "Table2",
"Field": [
{
"Table1Id": "1",
"Table2Id": [
"101"
]
}
]
},
{
"Primary": "Table1",
"Secondary": "Table3",
"Field": [
{
"Table1Id": "1",
"Table3Id": [
"200025"
]
}
]
},
{
"Primary": "Table1",
"Secondary": "Table4",
"Field": [
{
"Table1Id": "1",
"Table4Id": [
"3"
]
}
]
}
]
}
}
Request.Form.ToString() would returns the result like "a=1&b=3", it's definitely not what you need.
If you're passing values as submiting a form, you can use Request.Form["your-key"] to get the value.
If you're passing values by the http body, you can use new StreamReader(Request.InputStream).ReadToEnd() to get the whole JSON string.
I think you have an error within your getting ...
It's not
this.Request.Form.ToString(); // see http://stackoverflow.com/questions/7065979/why-is-the-return-value-of-request-form-tostring-different-from-the-result-of for output
Instead it should be
this.Request.Form["myInputNAME"].ToString();
Important - really use the name-attribute of your input/select/...-element
Anyways: I would like to encourage you, to use eg. <asp:HiddenField runat="server" ID="foo" />. When you have a server-control you can then access its value by simple doing this.foo.Value at server-side, whereas at client-side you can access the input field like document.getElementById('<%= this.foo.ClientID %>')

Categories

Resources