Suppose I have a JSON request body req1, and it resulted in a JSON response resp1, some of whose key-values are identical to those in req1. Now suppose I have another JSON request req2, and I want to construct a JSON response resp2 which is a duplicate of resp1, but in which the common keys have their values replaced by the values from req2.
What strategy might be used to tackle this?
As a concrete example, suppose req1 is this:
{"Name":"Alan"}
And suppose this is resp1:
{"output":{"Name":"Alan", "Cat": "12"}}
Note that "Name":"Alan" appears in both.
If req2 is this:
{"Name":"Bancorp"}
Then I'd like to create resp2 from resp1 like this:
{"output":{"Name":"Bancorp", "Cat": "12"}}
Crucially, the document structure of req* and resp* are not known in advance, and the only knowledge is that the structure of req1 and req2 are similar, and likewise for resp1 and resp2.
In other words, I'm looking for a flexible pattern-recognition that will "learn" from an initial req1/resp1 pair by identifying fields that occurred in both, and then be able to respond to future req* inputs by making the proper substitutions to a copy of resp1.
Is this something which already exists? If not, how might it be implemented in JSON.Net?
I would deserialize your requests into separate objects first. You could then use reflection to get a list of all the properties of each object and filter the results to only show the common properties.
obj.GetType().GetProperties();
Once you have your list of properties that you need in the response object, you can create a new ExpandoObject and dynamically add the properties and corresponding values that you need.
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;
Once you're done, you can serialize this response object back to JSON.
Related
the problem is that i dont know how to create model for json from api.
I used some online json to c# generator but it creates a very high count of classes what is unnecessary and very problematic with time.
thats my json:
https://solomid-resources.s3.amazonaws.com/blitz/tft/data/items.json
Fixed with this model
https://pastebin.com/SpGe72P7
and this serialization line
Dictionary<string, TftItems> foo = Drzewo.Configuration.DeserializeJson<Dictionary<string, TftItems>>(data);
where Configuration.DeserializeJson is just generic function of
JsonConvert.DeserializeObject<T>(json)
First of all I have checked all old questions and found this one useful: Reading dynamic attributes of json into .net C# but wasn't so useful in my case, I'm missing something not sure what is it!
I'm trying to read dynamic JSON with nested dynamic attributes, here is the JSON:
{"data":{"cart":{"seats":{"3B00535EF2414332":{"212":{"6":["22","21"]}}}}}}
Please keep in mind that 3B00535EF2414332, 212 and 6 are dynamic each time I get this JSON.
In C#, I don't know how should I set the attributes as I need to provide a class with properties with exact the same name of the object to deserialize this object. I though about parsing it to dynamic object in C# and try to call it, but still can't as the only known value for me each time is 3B00535EF2414332 but other 2 dynamic properties are not known to me, I need to retrieve them.
I though about the dictionary way, but I couldn't create it right. Actually, I didn't understand it right.
Thanks for your time.
You can try this:
var results = JObject.Parse(json)
["data"]["cart"]["seats"]
.Children<JProperty>().First().Value
.Children<JProperty>().First().Value
.Children<JProperty>().First().Value
.ToObject<int[]>();
EDIT: you can also use this to retrieve the values along with the path names:
var seats = JObject.Parse(json)["data"]["cart"]["seats"].Children<JProperty>();
var unknown0 = seats.First();
var unknown1 = unknown0.Value.Children<JProperty>().First();
var unknown2 = unknown1.Value.Children<JProperty>().First();
// unknown0.Name -> 3B00535EF2414332
// unknown1.Name -> 212
// unknown2.Name -> 6;
// unknown2.Value.ToObject<int[]>() -> [22,21]
I have binary serialized objects in database. They are serialized with protobuf.
Now I need to generate some viewer to see the content of Database.
So, i read stream from database and deserialized it back to the objects.
It works and the result is list of objects:
var dbData = readData(someType);//it is IList collection
Now, I would like to save this list of objects to file to see the content of database. I thought it would be the best to save it to xml. So, i have tried:
var serializer = new XmlSerializer(dbData.GetType());
But i get an error: Cannot deserialize type 'My.Entities.IdBase' because it contains property 'Key' which has no public setter.
What now? I can't change the class definitions to have setters.
Should i save objects to json or plain text instead? Or should i extract all properties and values and save it to some xml? Any code example?
JSON.NET would be the answer here. You can find it in nuget. Use it like this:
JsonConvert.DeserializeObject<T>(input);
I'm receiving messages over a network using JSON.NET. The message format is somewhat dynamic, in that the messages will be represented by many different classes, each inheriting from a parent message. For example:
{
MessageName: "MessageType1",
Data1: 124,
Data2: "Something"
}
{
MessageName: "MessageType2",
OtherData: "Some data",
MoreData: "Even more",
ANumber: 25
}
The problem I'm having is that in JSON.NET, I have no idea how to figure out the name of the class (MessageType1/MessageType2/etc) in order to deserialize it into an instance of the class without deserializing it twice. There's a few options I've considered; the one I'm currently using is to use a container class containing the message name and the actual json message serialized to string, but this seems wasteful.
Another method I've considered is deserializing into a string/string dictionary and then performing the population of the class on my own, which seems messy and unnecessary considering JSON.NET can do that for me... as long as I know the class first.
I'm really hoping there's an easy way to have JSON.NET figure out a class name by examining the MessageName property and then continue to populate a class after examining that one property.
Thanks for the help!
JSON can deserialize into a well known class only. You need to specify the data layout (i.e. the class/type)
There are two alternatives:
1.) go one level deeper. Use the JSON Token parser to read the tokens from your JSON stream and act based on the tokens you find.
2.) as you suggested: Use a class layout flexible enough to hold all your possible variations like a key/value dictionary.
Something I'm confusing.
The Javascript is going to produce the following JSON data.
{type:"book" , author: "Lian", Publisher: "ABC"}
{type:"Newspaper", author: "Noke"}
This is only an example, actually I've got more than this.
Since I have common fields between different JSON data, so I don't know is it possible to pass this to C# at one time.
What I want to do is pass this to c# then do some processing, what is the best way to do? I'm using ASP.NET MVC2.
Thanks for your answer or hints.
The combination of the 2 JSON statements above are, together, not valid JSON. That being said, you will not be able to use the JavaScriptSerializer class to deserialize that data into c# structure directly. Instead you will have to do some manual parsing first, to either break it down into valid JSON or just do full on manual parsing.
What I would actually recommend is sending over valid JSON instead. You can accomplish this by doing something like this:
{list: [
{type:"book" , author: "Lian", Publisher: "ABC"},
{type:"Newspaper", author: "Noke"} ]
Hard to say exactly, since only you know the details of your use case. You can send this data over using a traditional 'ajax' request. This is very easy to do with out any of the many JS libraries out there, but I would recommend just going with one anyway - they offer higher level constructs that are easier to use (and address cross-browser idiosyncrasies).
Since you are using ASP.NET MVC2, I would recommend jQuery. Microsoft is now backing jQuery as their JS library of choice and even make it default for new web projects.
Once you pass the above JSON to C#, you can deserialize it by doing something like this:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var result = serialzer.Deserialize<Dictionary<string, object>>(postedJSONData);
Your result will then have a structure that looks like this, in C#:
Dictionary<string, object> result =>
{ "list" => object },
object => List<object>,
List<object> => Dictionary<string, object>
{ "type" => "book", "author" => "Lian" } // etc
[
{type:"book" , author: "Lian", Publisher: "ABC"},
{type:"Newspaper", author: "Noke"}
]
Is still valid JSON (well actually keys need to be enclosed in " as well), so you can .push() into an array each time you create a JSON record.
var list = [];
// code doing other stuff
list.push({type:"book" , author: "Lian", Publisher: "ABC"});
// more code doing other stuff
list.push({type:"Newspaper", author: "Noke"})
Once your JSON list is constructed, you can send that list to the backend in one go.
You can also use the JavaScriptSerializer to deserialize your own custom type. Esentially you make a very simple type with all the properties of your json objects then call
JavaScriptSerializer serializer = new JavaScriptSerializer();
MyType result = serialzer.Deserialize<MyType>(JsonData);
You can also deserialize an array
MyType[] result = serialzer.Deserialize<MyType[]>(JsonData);