This question already has answers here:
running a transformation on a Json DeserializeObject for a property
(2 answers)
Closed 3 years ago.
I have the following JSON:
{
"lastOcurrences":[
{
"myString":"16726354"
},
{
"myString":"66728744"
},
{
"myString":"91135422"
}
]
}
and I have a class to deserialize it on:
public class JsonObject
{
public List<LastOcurrence> LastOcurrences { get; set; }
}
public class LastOcurrence
{
public string MyString { get; set; }
}
Upon deserializing it with JsonConvert.DeserializeObject<T>(json), I'd like to be able to format the string myString, to store 167-263-54, instead of 16726354.
What solution would please my soul: Using attributes on the properties, something of the likes of JsonConverter, but...
What i'd like to avoid doing: I would not like to use reflection to iterate through every property, only to then read the attribute and apply the formatting. Is there any way of doing this 'automatically' with JsonConvert?
One possible solution is to use custom getters and setters for this and when it is deserialized you keep the raw data stored. This will do JIT formatting. Depending on the usage of this data this could be much quicker however if there are a lot of repeated reads of the same data then this may be a bit slower.
public class LastOcurrence
{
private string _myString;
public string MyString
{
get { return Regex.Replace(_myString, #"^(.{ 3})(.{ 3})(.{ 2})$", "$1-$2-$3"); }
set { _myString = value; }
}
}
Related
This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 5 years ago.
I'm trying to create a custom revision quiz program in Unity C# which allows users to load questions into the program using JSON files, structured as below:
{
"question": [
{
"title": "What wave characteristic is measured on the vertical axis?",
"answers": {
"correct": "Amplitude",
"wrong": [
"Frequency",
"Period",
"Speed"
]
}
},
{
"title": "Which of these is a vector quantity?",
"answers": {
"correct": "Velocity",
"wrong": [
"Speed",
"Time",
"Mass"
]
}
}
]
}
I've managed to get my program reading from a file using a StreamReader, but am having a lot of trouble trying to get it into a single data structure.
I have seen other solutions using classes and manually defining structures for their solutions, but I don't know how to go about implementing this for a) as complex a structure as this and b) a structure that can have an arbritrary number of items in it (I'd like to support any number of questions). If the best way is to define these classes, how do I go about referencing items inside them? In the past I've parsed JSON using Python 3.6's json library's json.loads() function, and that worked perfectly, creating a single multidimensional array / dictionary structure that I could work with easily.
To put it simply, I currently have a string that I've read from a file with JSON data in it. How do I synthesise this into a single array that I can easily access using, eg, questions[question][0]["title"], which would return "What wave characteristic is measured on the vertical axis?" in the above case?
Use this site and generate your model.
public class Answers
{
public string correct { get; set; }
public List<string> wrong { get; set; }
}
public class Question
{
public string title { get; set; }
public Answers answers { get; set; }
}
public class RootObject
{
public List<Question> question { get; set; }
}
var model = JsonConvert.DeserializeObject<RootObject>(jsonstring);
That is all
BTW: You can also access to those properties dynamically without declaring any model
var model = JObject.Parse(jsonstring);
var title0 = (string)model["question"][0]["title"];
PS: I used Json.net
I think one way you can create a single data structure in your application by using the JSON given above is using the "paste special feature" of visual studio.Once you select it from the edit menu you have option to create class from JSON by just pasting any valid JSON.
I get the following class after pasting your JSON related to Questions:-
public class Rootobject
{
public Question[] question { get; set; }
}
public class Question
{
public string title { get; set; }
public Answers answers { get; set; }
}
public class Answers
{
public string correct { get; set; }
public string[] wrong { get; set; }
}
Single Rootobject class consists of the Question array.There different classes automatically created by visual studio related to Question and Answers.
You can deserialize the JSON values into your RootObject using JSON.NET desrialization:
var questions= JsonConvert.DeserializeObject<RootObject>(jsonString);
This question already has answers here:
How do I get json.net to serialize members of a class deriving from List<T>?
(3 answers)
Closed 5 years ago.
Consider the following program: (.NET Fiddle Link)
public class Program
{
public static void Main()
{
var carsa = new ListOfCarsA();
carsa.Cars.Add("Toyota");
carsa.Cars.Add("Lexus");
Console.WriteLine(JsonConvert.SerializeObject(carsa, Formatting.Indented));
var carsb = new ListOfCarsB();
carsb.Add("Nissan");
carsb.Add("Infiniti");
Console.WriteLine(JsonConvert.SerializeObject(carsb, Formatting.Indented));
}
}
public class ListOfCarsA
{
public string CollectionName { get { return "CarsA"; } }
public List<string> Cars { get; set; }
public ListOfCarsA()
{
Cars = new List<string>();
}
}
public class ListOfCarsB : List<string>
{
public string CollectionName { get { return "CarsB"; } }
}
This then outputs the following:
{
"CollectionName": "CarsA",
"Cars": [
"Toyota",
"Lexus"
]
}
And
[
"Nissan",
"Infiniti"
]
Why does the property CollectionName not get serialised and output CarsB, but the same property on the ListOfCarsA results in CarsA being serialised?
What is the solution to this problem - How could I have a class similar to ListOfCarsB but still have any extra members serialised? I have tried using the attributes [JsonProperty("CollectionName"] and [JsonRequired] but these seem to do nothing.
This is because your second example IS a list, whilst the first example only contains one. Json.Net knows how to create json from lists and so is ignoring the rest of your custom code. Not much you can do about this except write a custom formatter
There are a number of great ways to auto-generate C# code from JSON, such as here and here.
However, the resulting code doesn't include property initializers. For example, the following JSON:
{
"Name" : "Blastoise"
}
gets deserialized to this:
public class RootObject
{
public string Name { get; set; }
}
Presumably this is by design, since the values used in the JSON will probably be overridden anyways, so adding initializers might just annoy people who don't want them.
But what if I want that? Short of manually adding every value by hand, is there a way to deserialize JSON to the following?
public class RootObject
{
public string Name { get; set; } = "Blastoise";
}
Obviously in this case a manual edit is easy, but manual editing becomes tedious for larger JSON objects.
is there a way to deserialize JSON to the following?
Using the source code of the converter you mentioned.
A quick change at the line 204
sw.WriteLine(prefix + "public {0} {1} {{ get; set; }} = {2};", field.Type.GetTypeName(), field.MemberName, field.GetExamplesText());
gives me the result similar to what you described
internal class SampleResponse1
{
[JsonProperty("Name")]
public string Name { get; set; } = "Blastoise";
}
This question already has answers here:
JavaScriptSerializer - JSON serialization of enum as string
(31 answers)
Closed 8 years ago.
I created a ASP.NET MVC 4 Web application. Within this application i implemented several rest webservices and here comes my question: Is it possible to force the object serialization to use the enum entity names instead of their values?
This is my enum:
public enum ReturnCode { OK, InvalidParameter }
This is what I get:
{
"returnCode": 0,
"data": null
}
But this is what I want:
{
"returnCode": OK,
"data": null
}
Is there a way to achieve this?
You can use a JsonConverter.
There is a native one for JSON.Net StringEnumConverter mentioned in this question JSON serialization of enum as string
Either anotate your property:
[JsonConverter(typeof(StringEnumConverter))]
public enum ReturnCode { OK, InvalidParameter }
Or use the config examples in WebApi Json.NET custom date handling to register in the global serialiser settings.
Difficult to make a suggestion without better understanding of your usage patterns...but none the less.
Make the enum a private field.
Built a public string property with a getter which returns the entity name of the private enum field and a setter which uses Enum.Parse to set the private field value
Yes you can do that. You need to declare additional string property and use it when serializing/deserializing.
Example:
[DataContract]
public class MyResource
{
[DataMember]
public string Data { get; set; }
public ReturnCode Code { get; set; }
[DataMember(Name = "returnCode")]
string ReturnCodeString
{
get { return this.Code.ToString(); }
set
{
ReturnCode r;
this.Code = Enum.TryParse(value, true, out r) ? r : ReturnCode.OK;
}
}
}
So now you can pass the value of enum as a string (in both direction from server and from client) i.e.:
{
"returnCode": "OK",
"data": null
}
or
{
"returnCode": "InvalidParameter",
"data": null
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Using Json.net - partial custom serialization of a c# object
I have a class that I successfully get to serialize in json.net when using asp.net MVC 4 WebAPI. The class has a property that is a list of strings.
public class FruitBasket {
[DataMember]
public List<string> FruitList { get; set; }
public int FruitCount {
get {
return FruitList.Count();
}
}
}
In my Get method the serialization happens ok and I get an empty array i.e. [] for the FruitList property in my JSON. If I use the same json in a PUT request's body I get an error in the FruitCount property during deserialization because FruitList is null.
I want the FruitList property (basically my get only properties) to serialize but not deserialize. Is it possible with a setting or other wise with json.net?
I realize this does not answer your question, but addresses the error being generated so might make worrying about custom serialization irrelevant
use a private variable for FruitList, return it in the get and in set, if value is null then set the private variable equal to a new list.
public class FruitBasket
{
private List<string> _fruitList;
[DataMember]
public List<string> FruitList
{
get
{
return _fruitList;
}
set
{
if (value == null)
{
_fruitList = new List<string>();
}
else
{
_fruitList = value;
}
}
}
public int FruitCount
{
get
{
return FruitList.Count();
}
}
}