Serializing objects to JSON - dynamic property serialization [duplicate] - c#

This question already has answers here:
NewtonSoft add JSONIGNORE at runTime
(7 answers)
Closed 5 years ago.
I have a class of which I serialize objects to JSON using json.net. The class has some property that I usually didn't want serialized, so I marked it with JsonIgnore.
public class SomeClass
{
[JsonIgnore]
public int ID { get; set; }
public int SecondID { get; set; }
public string Name { get; set; }
}
Now, in a different context, I wish to export objects of the same class, but here I wish to also export the ID (that I have flagged to be ignored in the first context).
Is it possible to dynamically flag a property to be ignored before serializing to JSON or do I have to write a custom serializer to achieve this?
How can I achieve the desired behavior in the simplest possible way?

Here you can make a list of properties you want to ignore :
[JsonIgnore]
public List<Something> Somethings { get; set; }
//Ignore by default
public List<Something> Somethings { get; set; }
JsonConvert.SerializeObject(myObject,
Newtonsoft.Json.Formatting.None,
new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
});

Related

JSON Key name with spaces [duplicate]

This question already has answers here:
RestSharp - deserialize json response with invalid key name (contains a period )
(2 answers)
Closed 1 year ago.
{
"odata.metadata": "sometext",
"odata.nextLink": "sometext",
"value": [{
"odata.type": "SP.Data.RegionsListItem",
"odata.id": "07404daa-61b5-4947-af9f-38f29822f775",
"odata.etag": "\"3\"",
"odata.editLink": "Web/Lists(guid'65dc896b-df87-4145-98d9-57c7ea619e66')/Items(3)",
"FileSystemObjectType": 0,
"Id": 3,
"ServerRedirectedEmbedUri": null,
}]
}
this is an example of my Json string i cant change its key names any sugestion? thanks in advance.
Depending on the library you are using for deserialization you can mark model fields with corresponding attributes - for example JsonPropertyNameAttribute for System.Text.Json or JsonPropertyAttribute for Newtonsoft.Json.
Newtonsoft.Json:
public class Root
{
[JsonProperty("odata.metadata")]
public string OdataMetadata { get; set; }
[JsonProperty("odata.nextLink")]
public string OdataNextLink { get; set; }
[JsonProperty("value")]
public List<Value> Value { get; set; } // do the same for Value type
}
var result = JsonConvert.DeserializeObject<Root>(json);
System.Text.Json:
public class Root
{
[JsonPropertyName("odata.metadata")]
public string OdataMetadata { get; set; }
[JsonPropertyName("odata.nextLink")]
public string OdataNextLink { get; set; }
[JsonPropertyName("value")]
public List<Value> Value { get; set; }
}
var result = JsonSerializer.Deserialize<Root>(json);
When you create a class for your data, you can use annotations for the class members. For instance when using Newtonsoft.Json it works this way:
class MyData {
[JsonProperty("odata.metadata")]
public string Metadata {get;set;}
[JsonProperty("odata.nextlink")]
public string NextLink {get;set;}
...
}
With other libraries, the annotations may be named differently. Also make sure, you are importing the correct namespace and use the correct annotations for the library you are using. Ie for instance the System.Text.Json.JsonPropertyName annotation won't have any effect, when deserializing with Newtonsoft.Json and vice versa.
Then you can deserialize
var data = JsonConvert.DeserializeObject<MyData>(thejsonstring);
and access the property with its .NET name
var metadata = data.Metadata;

Creating a C# class for JSON deserialization [duplicate]

This question already has answers here:
Deserializing JSON with dynamic keys
(4 answers)
Complicated Json to C# Object Deserialize with classes
(2 answers)
Using JSON.NET to read a dynamic property name
(1 answer)
Closed 10 months ago.
I'm having an issue with JSON that I'm getting back for a hotel booking API. Essentially I'm taking the output and trying to create a class so that I can put it into an object. The problem is this: The JSON is returning objects and we can't readily use this format to make a C# class because of how it's formatted:
Example of how the JSON is formatted
Here is a snippet of it. Attributes is the highest level, then "pets" is next. The values we need for this are id: 5058 and name: Service Animals are allowed, however they are creating this "5058" and "5059" and "2050" object which is making it difficult to create a class and properly deserialize it.
I'm fairly new at C# (formerly long-time C programmer), so trying to understand the best way to make a class for something like this where the "5058" is not actually created as a class ... I would prefer if we could ingest that level into an array or list perhaps?
This is what something like json2csharp.com outputs...
public class Pets
{
public _5058 _5058 { get; set; }
public _5059 _5059 { get; set; }
public _2050 _2050 { get; set; }
}
And then
public class _5059
{
public string id { get; set; }
public string name { get; set; }
}
5059 should not be a class... That appears to be the name of the object; I want to ignore that because the ID: in the object is 5059
This wont work since there are thousands of IDs, and we're not looking to create a separate class for each ID -
I would like to make a class more like this
public class Pets
{
public string id { get; set; }
public string name {get; set; }
}
This is how I'm receiving the JSON
{
"pets":{
"5058":{
"id":"5058",
"name":"Service animals are allowed"
},
"5059":{
"id":"5059",
"name":"Service animals are exempt from fees/restrictions"
},
...
}
}
(This is a small snippet)
Again, here, they have "5059":{"id":"5059","name":"Service animals...."
So, what's the best way to ingest this with a class in C# without creating classes for the ID, the way a JSON to C# class creator would do?
Thanks for you help
That looks like a Dictionary<string, Pet> where those 5058, 5059, etc. are the keys.
public class Data
{
public Dictionary<string, Pet> pets { get; set; }
}
public class Pet
{
public string id { get; set; }
public string name { get; set; }
}
Deserialize the json as below
var data = JsonSerializer.Deserialize<Data>(json);
or if you're using Newtonsoft.Json
var data = JsonConvert.DeserializeObject<Data>(json);

Dynamically ignore property on sealed class when serializing JSON with System.Text.Json [duplicate]

This question already has answers here:
How to exclude a property from being serialized in System.Text.Json.JsonSerializer.Serialize() using a JsonConverter
(5 answers)
System.Text.Json API is there something like IContractResolver
(2 answers)
Closed 2 years ago.
Question
Can I dynamically ignore a property from a sealed class using System.Text.Json.JsonSerializer?
Example Code
Example class from another library:
public sealed class FrozenClass
{
// [JsonIgnore] <- cannot apply because I don't own this class
public int InternalId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Default Serialization:
var person = new FrozenClass() { InternalId = 3, FirstName = "Dorothy", LastName = "Vaughan" };
var jsonString = System.Text.Json.JsonSerializer.Serialize(person);
Actual Outcome:
{ "InternalId": 3, "FirstName": "Dorothy", "LastName": "Vaughan" }
Expected Outcome:
{ "FirstName": "Dorothy", "LastName": "Vaughan" }
Alternatives that don't work
There are two other questions on how to add JsonIgnore at RunTime & add dynamic property name for serialization, but both are targeted at Newtonsoft's Json.NET - and often reference this extension method
There are several ways to modify the way a class is serialized with the native JsonSerializer, but all seem to rely on modifying the underlying class:
You can exclude properties from serialization by adding the [JsonIgnore] attribute to the original class
You can register a JsonConverter on a property by adding the [JsonConverter] attribute to the original class
However, in my case, the class is from another library and cannot be extended
Workarounds
A possible workaround is to create another exportable class and setup a mapper between them
public class MyFrozenClass
{
public MyFrozenClass(FrozenClass frozen)
{
this.FirstName = frozen.FirstName;
this.LastName = frozen.LastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
var jsonString = System.Text.Json.JsonSerializer.Serialize(new MyFrozenClass(person));

Conditionally serialize object members

To serialize object to json we do as given below -
var json = new JavaScriptSerializer().Serialize(question);
then it returns given json data :-
{"que_desc":"devQuestion","qtype":3,"number_of_answer":3,"answers":[{"answer":"answer1","Question":null},{"answer":"answer2","Question":null},{"answer":"answer3","Question":null}]}
but I want to ignore "Question" property and need data as given below-
{
"que_desc": "This is Question details",
"qtype" : "1",
"number_of_answer" : "3",
"answers": [{"answer": "A", "is_default": "true"}, {"answer": "B"}, {"answer": "C"}]}
I want to ignore "Question" property while converting into json.
so how we will conditionally serialize object members at run time??
You can use the Json.NET nuget and the [JsonIgnore] atribute at the que_desc property.
If you need more functionality, you can implemente de serialize methods by your self using Json.NET.
More Info
You could decorate the Question property with the [ScriptIgnore] attribute.
For further info, please have a look here.
Supposing that Answer has a definition like the below:
public class Answer
{
public string Answer { get; set; }
public Question Question { get; set; }
// rest
}
If you change it to the following:
public class Answer
{
public string Answer { get; set; }
[ScriptIgnore]
public Question Question { get; set; }
// rest
}
You will get that you want.

Custom json serialization for each item in IEnumerable [duplicate]

This question already has answers here:
How do you serialize an enum array to a Json array of strings? [duplicate]
(2 answers)
Closed 6 years ago.
I'm using Json.NET to serialize an object that has an IEnumerable of an enum and DateTime. It's something like:
class Chart
{
// ...
public IEnumerable<int> YAxis { get; set; }
public IEnumerable<State> Data { get; set; }
public IEnumerable<DateTime> XAxis { get; set; }
}
But I need a custom JsonConverter to make the enum serialize as string and to change the DateTime string format.
I've tried using the JsonConverter attribute as mentioned here for enum and a custom IsoDateTimeConverter as done here:
[JsonConverter(typeof(StringEnumConverter))]
public IEnumerable<State> Data { get; set; }
[JsonConverter(typeof(MyDateTimeConverter))]
public IEnumerable<DateTime> XAxis { get; set; }
I was hoping it would work for an IEnumerable too, but unsurprisingly it doesn't:
Unable to cast object of type 'WhereSelectArrayIterator`2[System.Int32,Model.State]' to type 'System.Enum'.
Is there any way to say that the JsonConverterAttribute applies to each item and not on the enumerable itself?
Turns out that for enumerables you have to use the JsonPropertyAttribute and the ItemConverterType property as follows:
[JsonProperty(ItemConverterType = typeof(StringEnumConverter))]
public IEnumerable<State> Data { get; set; }
[JsonProperty(ItemConverterType = typeof(MyDateTimeConverter))]
public IEnumerable<DateTime> XAxis { get; set; }
This is mentioned in the documentation as:
To apply a JsonConverter to the items in a collection, use either JsonArrayAttribute, JsonDictionaryAttribute or JsonPropertyAttribute and set the ItemConverterType property to the converter type you want to use.
You might be confused with JsonArrayAttribute, but it
cannot target a property.

Categories

Resources