Deserialize JSON string in C# without using reflection - c#

I'm working on a sandbox solution in Sharepoint, the important restrictions (regarding to this question) due to that are the use of .net 3.5 and there are no reflections allowed.
EXAMPLE 1
If I try to deserialize as JSON string into a simple class like this it works fine:
JSON STRING
{"field":"Picture1","url":"whatever"}
C# CLASS
public class PictureSetting
{
public string field { get; set; }
public string url { get; set; }
}
EXAMPLE 2
But if I try to deserialize a bit more complex string I get an error:
JSON STRING
{
"Rows": [
{
"Columns": [
{
"Width": "100"
}
]
}
]
}
C# CLASSES
internal class PageStructure
{
public List<StructureElement> Rows { get; set; }
public PageStructure()
{
Rows = new List<StructureElement>();
}
}
internal class StructureElement
{
public List<BlockAssigment> Columns { get; set; }
public StructureElement()
{
Columns = new List<BlockAssigment>();
}
}
internal class BlockAssigment
{
public string Width { get; set; }
}
ERROR
Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
*DESERIALIZATION
The code I use for deserialization of both examples is just standard .net:
var serializer = new JavaScriptSerializer();
var obj = serializer.Deserialize<PageStructure>("jsonstring");
So it seems that for the first example .net is not using reflection because that works. So the question is:
Is there a way to deserialize the second example without having .net using reflection internally?
Modifying both JSON string and C# classes are no problem, I just have to keep the structure (base object with rows including columns) somehow.

I suspect the biggest problem is actually here:
public class PictureSetting // public, works
versus
internal class PageStructure // non-public, permission denied
it sounds to me like the sandbox is preventing reflection of non-public types/members. This would be consistent with most sandboxes, for example Silverlight: you can use reflection, but only for things that the could would be able to do normally - i.e. access public types / members. Try making PageStructure, StructureElement and BlockAssigment into public classes.

You can use this service http://json2csharp.com/ to generate correct C# clasees for parsing json.

Related

Need help deserializing C# / .NET 6 into seperate objects

I am attempting to use JsonSerializer.Deserialize() from System.Text.JSON in .NET 6.
I have no control over the format of the JSON.
I have used it successfully in the past but now the data I need to consume is more complicated (but not VERY complicated). I am assuming that I am simply describing my data incorrectly.
I have tried several things.... but the description below is the only way so far that I could consume the data at all.
I think my biggest problem is that I am trying to use the wiz-bang "Paste Special -> Paste JSON as Classes" without really understanding how to form my classes for serialization/deserialization.
Here is a simple example of the JSON I am trying to consume:
[
{
"version": "1.0b",
"sub_version": "x.y.barf"
},
{
"somestring": "I am a string",
"isCool": false,
"a_cool_array": [
"bob",
"jill",
"pete"
]
}
]
If I use the whiz-bang "Paste Special" tool, I get the following generated for me.
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string version { get; set; }//<-- I need these to remain in their own object
public string sub_version { get; set; }//<-- I need these to remain in their own object
public string somestring { get; set; }
public bool isCool { get; set; }
public string[] a_cool_array { get; set; }
}
Here is the problem that I have.
The whiz-bang tool put my first object (with one version strings) and second (more complicated) object into the same object.
If I use a call like this:
var deserializedJSON = JsonSerializer.Deserialize<List<Class1>>(myJSONTextHere);
I end up with two objects in the list.
The first one has the versions filled out, the second one only has the other fields filled out.
This all makes sense to me but I don't know how to get around the problem.
I need these objects to model the JSON and I need them to save back in the same format when I re-serailize the modified classes elsewhere. This isn't my exact problem as I have simplified it for the question.
I have found one way around this problem.
It is ugly but seems to work. I hate that my code has to know about the data it is manipulating.
I used the actual JSON DOM to split the two disparate classes into individual JSON objects, then used the class de-serializer to load the individual objects into their given types.
In the following example, I am not checking anything.. I happen to know the order of the objects. I could check the raw JSON to make sure it was what I was looking for. In this case, I don't need to.
So, instead of taking the class structure as pasted by the super spiffy "Paste Classes from JSON" thingamajigger.. I split the classes myself.
Like this:
public class VersionClass
{
public string version { get; set; }
public string sub_version { get; set; }
}
public class DataClass
{
public string somestring { get; set; }
public bool isCool { get; set; }
public string[] a_cool_array { get; set; }
}
Then, I can load the JSON into the objects I need like this:
using var jsonDoc = JsonDocument.Parse(jsonText);
var versionClass = jsonDoc.RootElement[0].Deserialize<VersionClass>();
var dataClass = jsonDoc.RootElement[1].Deserialize<DataClass>();
I hope this helps someone having the same problem.
Your json needs to look like this:
{
"class1": [
//more json
],
"class2": [
//more json
]
}
Then you will have:
public class RootObject
{
// class1 and 2 in here
}
public class Class1
{
}
public class Class2
{
}

Convert json to C# classes with generic property

I have json data as below:
{
status: "success",
data: {
custid1: 723,
custid2: 670,
custid3: 430
}
}
As per https://json2csharp.com/, C# classes should be like below:
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Data {
public int custid1 { get; set; }
public int custid2 { get; set; }
public int custid3 { get; set; }
}
public class Root {
public string status { get; set; }
public Data data { get; set; }
}
But I dont like Data class above, it has custid1, custid2 as hard coded. I know here json data is like that so classes are generated accordingly but can we make some generic design which can parse below line?
var result = JsonConvert.DeserializeObject<Root>(json);
I feel that tools like Json2CSharp.com are only intended for scaffolding and prototyping rather than for directly-usable C# code. So go ahead and use it to quickly create initial code for your project, but you likely will need to tweak it for production use - in this case one of those tweaks you need to make is to change data: entry in the Root DTO class from having its own class Data to being a Dictionary<String,Int32> instead so that it can accommodate the dynamic nature of the data: property in production JSON data.
Side-note: You should use PascalCase for all class properties in your C# code - but you can configure your JSON serializer to automatically map the camelCase properties in the JSON.
If you're using Newtonsoft.Json then use CamelCaseNamingStrategy or set an explicit [JsonProperty( "camelCaseName" )]. You don't even have to do this manually because JSON2CSharp.com can do it automatically for you:
It's in the Options menu next to the Convert button:

Deserialize first property not matching any target object's properties into specific property [duplicate]

This question already has answers here:
Deserialize json with known and unknown fields
(5 answers)
Closed 6 years ago.
I'm doing some web API integration with Newtonsoft.Json, and as always, I have to do dumb stunts to properly deserialize what they're sending back.
In this case, the API will send responses resembling this kind of structure:
{ "contacts": [ ... ], "has-more": true, "offset": 38817 }
The "has-more" and "offset" properties are pretty much constant on the different method responses, and have been defined accordingly on the response object that I'm deserializing into. The response object looks something like this:
public class APIResponse {
public JContainer Result { get; set; }
[JsonProperty("has-more")]
public bool HasMore { get; set; }
[JsonProperty("offset")]
public int Offset { get; set; }
}
That first "contacts" property is what can vary; for some methods, I might get "contacts", some might get "companies", and others might get who-knows-what. I also don't have any way to be certain that every response will have such a "variable" property, nor that it will be the first one, positionally speaking.
For this example, what I would like to happen is the deserializer looks at the Json and says, "Let's see, I don't see anything mapping to 'contacts', so we'll put that into 'Result', and then I can see from the JsonProperty attributes that 'has-more' and 'offset' go into HasMore and Offset. Okay, all set, here's your object."
I suspect this involves some tricks with a custom JsonConverter or IContractResolver, but I'm just not connecting the dots here. I tried doing a simple custom contract resolver, but it appears to use contract resolvers to resolve object property names into property names to look for in the JSON text, not vice-versa.
You can use a base class + derivations for each response type.
public class APIResponseBase {
[JsonProperty("has-more")]
public bool HasMore { get; set; }
[JsonProperty("offset")]
public int Offset { get; set; }
}
public class ContactsResponse : APIResponseBase {
public IEnumerable<Contact> Contacts { get; set; }
}
public class CompaniesResponse : APIResponseBase {
public IEnumerable<Company> Companies { get; set; }
}
var contactsResponse = JsonConvert.Deserialize<ContactsResponse>(json);
IEnumerable<Contact> contacts = contactsResponse.Contacts

Deserializing of Google's Translate API result in C#

I'm trying to deserialize Google's Translate API JSON response into an C# object using JavaScriptSerializer. However, it always says Type 'TranslateAPI.Models.Translations' is not supported for deserialization of an array.. I double checked whether I have correctly created models for this object and it seems right. Here are my models:
TranslateResult
public TranslateData data { get; set; }
TranslateData
public Translations translations { get; set; }
Translations
public TranslatedText[] translatedText { get; set; } // I have also tried List<TranslatedText> which also doesn't work
TranslatedText
public string translatedText { get; set; }
The json returned from Google looks like this:
{data: {
translations: [
{translatedText: "Hello world"}
]
}
Any idea what I'm doing wrong?
Thanks
PS. It could be useful to mention, that I'm deserializing it like so: TranslateResult translateResult = js.Deserialize <TranslateResult>(json);
I suspect you don't need the Translations class at all. You've got:
An object containing a data property
The data property value is an object containing a translations property
The translations property value is an array
Each element of the array is an object with a translatedText property
So that sounds to me like your TranslateData class should be:
TranslateData
public Translation[] translations { get; set; }
Translation // Renamed from TranslatedText
public string translatedText { get; set }
(I'd also recommend that you rename the properties to follow normal C# naming conventions, and then apply attributes to help with the JSON conversion if you need to. I haven't used JavaScriptSerializer for a while, but I'm sure it's feasible. You shouldn't need to work with nasty property names in your C# code.)

Deserializing a JSON with variable name/value pairs into object in C#

I am using C# .NET 4.0 to parse a JSON into a custom object. I am using JavaScriptSerializer.Deserialize to map it to a class that I wrote. Problem is, the JSON's name/value pairs are not static and vary depending on the argument isChain, as seen in this JSON fragment (better link at bottom):
{
"STATE_WALK_LEFT":{
"isChain":"1",
"x":"1"
},
"STATE_WALK_LEFT_0":{
"x":"0"
},
"STATE_WALK_LEFT_1":{
"x":"40"
},
"STATE_WALK_LEFT_2":{
"x":"80"
},
"STATE_WALK_RIGHT":{
"isChain":"0"
},
"STATE_RUN_LEFT":{
"isChain":"0"
}
}
The chains can have anywhere from _STATE_0 to _STATE_25 entries in the chains. Is there some way to store this data so I don't have to write 12*26 empty classes like so:
public StateWalkLeft0 STATE_WALK_LEFT { get; set; }
public StateWalkLeft0 STATE_WALK_LEFT_0 { get; set; }
public StateWalkLeft1 STATE_WALK_LEFT_1 { get; set; }
public StateWalkLeft2 STATE_WALK_LEFT_2 { get; set; }
public StateWalkLeft3 STATE_WALK_LEFT_3 { get; set; }
Is there a library or some other way I could use to partially parse only the STATE_0, STATE_1, etc fields? Could you maybe suggest a way to add these recently added JSON pairs?
Edited to clarify:
To get an idea of what I'm working with, here is the Class derived from the JSONs:
Check out my full Class to get an idea of what the JSONs contain
Basically, I just need a way to store these recently implemented chains in this class somehow for processing. All of those classes/properties are generated from these JSONs.
Use Newtonsoft Json.NET and as example following code
internal struct ChainX
{
public int x { get; set; }
public int isChain { get; set; }
}
static string json =
#"{
""STATE_WALK_LEFT"":{
""isChain"":""1"",
""x"":""1""
},
""STATE_WALK_LEFT_0"":{
""x"":""0""
},
""STATE_WALK_LEFT_1"":{
""x"":""40""
},
""STATE_WALK_LEFT_2"":{
""x"":""80""
},
""STATE_WALK_RIGHT"":{
""isChain"":""0""
},
""STATE_RUN_LEFT"":{
""isChain"":""0""
}
}";
and a line of code to deserialize to Dictionary:
var values = JsonConvert.DeserializeObject<Dictionary<string, ChainX>>(json);
after that you can simple access values by dictionary key:
ChainX valueWalkLeft1 = values["STATE_WALK_LEFT_1"];

Categories

Resources