Conditionally serialize object members - c#

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.

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;

How do I define an attribute for a class based on obtained JSON object?

I am able to get a JSON object with a list of surveys having a set of attributes for each of them. I have a class defined for surveys where I am defining all the survey attributes based on the obtained JSON object. I am facing an error while defining question.id attribute. Please suggest me the best way to solve this problem.
JSON Data:
"surveys":
{
"id": 20128672,
"trueFalse": false,
"question": "Any accidents on site today?",
"question.id": 1097329,
"question.tag": 0,
"images": [],
"videos": []
},
Survey class:
public class survey
{
public string id { get; set; }
public Nullable<bool> trueFalse { get; set; }
public string question { get; set; }
public string question.id { get; set; } //error in writing the question id attribute
public string desc { get; set; }
//public bool trueFalse { get; set; }
public string FormattedAnswer
{
get
{
if (trueFalse == null) return "NA";
return trueFalse == true ? "YES" : "NO";
}
}
}
I'm not sure what json lib you're using here but assuming it's json.net you can resolve this with a simple annotation mapping the json fields name to the C# property, the name you're giving that property in C# is not valid which is why you're getting the error, no periods in field names.
[JsonProperty("question.id")]
public int id { get; set; }
Also, I modified your type because it was wrong too, the json value is an int, not a string. If you're not using json.net, I'm sure you'll find similar features in the lib you are using, google json annotation or something along those lines with the packages name to find appropriate docs.

Mapping object with properties names and values

I have class
public class Foo
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
I want to convert the object to a generic object
{
"properties": {
"id" : "1234",
"name": "John Doe",
"email" : "john.doe#mail.com"
}
}
I want to convert the class instance to the structure where the properties would be dynamic depending on the class. Is this possible with Automapper?
Seems you want to serialize/deserialize to/from JSON. In this case you can reference to Newtonsoft.Json and use the JsonConvert.SerializeObject/JsonConvert.DeserializeObject generic method which does not depend on any specific class:
Deserializing (From String to Class Instance):
var foo = JsonConvert.DeserializeObject<Foo>(jsonString);
Serializing (From Class Instance to String):
var stringValue = JsonConvert.SerializeObject(foo)
One More Point (Mapping)
Also you may want to decorate your class with some attributes to specify the mapping:
[DataContract]
public class Foo
{
[DataMember(Name = "id")]
public string Id {get;set;}
[DataMember(Name = "name")]
public string Name {get;set;}
[DataMember(Name = "email")]
public string Email {get;set;}
}
Partially AutoMapper cannot map to dictionary or ExpandoObject, so no.
The following solution was posted before I was aware that by mapping to an ExpandoObject Automapper will simply leave you with an empty object.
The simplest solution would be this I think (assuming you want an ExpandoObject as a result):
public ExpandoObject Map<TInput>(TInput inputObject)
{
dynamic result = new ExpandoObject();
result.properties = Mapper.DynamicMap<TInput, ExpandoObject>(inputObject);
return (ExpandoObject)result;
}
As far as I know you can't delegate all members as child properties to another field using automapper, but it's simple to do this yourself. AutoMapper is completely useless here.
edit: seems that automapper struggles with ExpandoObject... Actually it seems like AutoMapper cannot do this at all, so you're left with reflection.
You would then write a reflection object that can create or populate a dictionary with the objects properties.

Deserializing JSON collection in C#

This is a JSON message I get from server (which I can't change). There might be many more objects (time / value) returned, but in this case there is only one. The format stays the same regardless.
{
"data": [
{
"time": "2014-12-12T13:52:43",
"value": 255.0
}
]
}
I'm trying to deserialize the JSON to a very simple C# object.
public class Dataentry {
public float Value { get; set; }
public DateTime Time { get; set; }
}
I've tried deserialization with Newtonsoft's JSON.Net and RestSharp libraries with no success. The following code doesn't work, but neither does anything else I've tried :-) I get no error -- just an empty object with default initial values.
var myObject = JsonConvert.DeserializeObject<Dataentry> (jsonString);
Since those libraries are not very intuitive or well documented in this kind of case, I'm lost. Is this kind of JSON impossible to deserialize? I really would like to use a ready-made library, so any help would be appreciated.
This is not working because your JSON is specifying a collection and you are trying to deseralize into one object. There are plenty of json to c# class generators you can paste json into to get an appropriate class definition(s) one such generator is located here
A more appropriate definition would be
public class Datum
{
public string time { get; set; }
public double value { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
}
Then deseralize as
var myObject = JsonConvert.DeserializeObject<RootObject> (jsonString);
I'd like add some extra explanetion to your question...
You write I'm trying to deserialize the JSON to a very simple C# object. - unfortunatelly this is not the complete truth. What you are trying is to deserialize a collection of a very simple C# objects. The indicator for this are the square brackets in your json:
{
"data": [
{
"time": "2014-12-12T13:52:43",
"value": 255.0
}
]
}
It means that there is a class with a property named data (it can ba mapped to some other name but for the sake of simplicity let's stick to this name) and that this property is a collection type. It can be one of any types that support the IEnumerable interface.
public class DataCollection
{
public DataItem[] data { get; set; }
//public List<DataItem> data { get; set; } // This would also work.
//public HashSet<DataItem> data { get; set; } // This would work too.
}
public class DataItem
{
public float value { get; set; }
public DateTime time { get; set; } // This would work because the time is in an ISO format I believe so json.net can parse it into DateTime.
}
The next step is to tell Json.Net how to deserialize it. Now when you know it's a complex data type you can use the type that describes the json structure for deserialization:
var dataCollection = JsonConvert.DeserializeObject<DataCollection>(jsonString);
If you didn't have the data property in you json string but something like this:
[
{
"time": "2014-12-12T13:52:43",
"value": 255.0
},
{
"time": "2016-12-12T13:52:43",
"value": 25.0
},
]
you could directly deserialize it as a collection:
var dataItems = JsonConvert.DeserializeObject<List<DataItem>>(jsonString);
or
var dataItems = JsonConvert.DeserializeObject<DataItem[]>(jsonString);
change your DateEntry binding Definition
public class ArrayData{
public DataEntry data {set; get;}
}
public class DataEntry {
public float Value { get; set; }
public DateTime Time { get; set; }
}
in your method now you can received an ArraData Object
be careful with datetime string values sent for correct binding

How do I remap names to object properties when deserializing, using Json.Net in C#

Case:
I receive a JSON string from third-party server, containing a list of objects.
e.g.
[{"foo": "bar", "someotherfield": "somevalue"}, {etc}, {etc}]
I have a C# class like,
public class MyObject
{
public string A { get; set; }
public string B { get; set; }
}
Now, I want to use JsonConvert.DeserializeObject, but so that it maps "foo" to A and so forth. How would I go about doing this?
You can use the JsonProperty attribute.
[JsonProperty("foo")]
public string A { get; set; }
You can use the JsonPropertyAttribute decorated on the property, giving it the name of the parameter it should find in the JSON message. You can also use a custom JsonConverter, if you do not wish to use an attribute.

Categories

Resources