How to delete header name of Json data in C# - c#

I am trying to delete this header "vendor": and { } branch from Json formated output.
The reason to delete is to map these three fields names ("RECORDNO".."NAME") to SQL table.
Bottom is expected output:
Bottom is C# code that iterates thru each ones and populates the result, and later uses JsonCovert to format output in Json format.
public static string Run(ILogger logger)
{
OnlineClient client = Bootstrap.Client(logger);
ReadByQuery query = new ReadByQuery()
{
ObjectName = "VENDOR",
PageSize = 600,
Fields =
{
"RECORDNO",
"VENDORID",
"NAME"
}
};
logger.LogInformation("Executing query to Intacct API");
Task<OnlineResponse> task = client.Execute(query);
task.Wait();
OnlineResponse response = task.Result;
Result result = response.Results[0];
LogManager.Flush();
int i = 1;
while (result.NumRemaining > 0 && i <= 1 && !string.IsNullOrEmpty(result.ResultId))
{
i++;
ReadMore more = new ReadMore()
{
ResultId = result.ResultId
};
Task<OnlineResponse> taskMore = client.Execute(more);
taskMore.Wait();
OnlineResponse responseMore = taskMore.Result;
Result resultMore = responseMore.Results[0];
dynamic resultJson =
JsonConvert.DeserializeObject(JsonConvert.SerializeObject(result.Data));
string resultJsonString = resultJson.ToString();
return resultJsonString;
}
return "";
}
I am not fluent in C# so I am not sure how to express to delete the "vendor:" portion from 'query'.
I am sure there are a lot of unnecessary lines from this C# code which could be deleted (to clean up).
What is expression to delete "vendor": and { } branch?
This is updated code based on the comment from #Serge.
int i = 1;
while (result.NumRemaining > 0 && i <= 1 && !string.IsNullOrEmpty(result.ResultId))
{
i++;
dynamic resultJson =
JsonConvert.DeserializeObject(JsonConvert.SerializeObject(result.Data));
string resultJsonString = resultJson.ToString();
var jsonArray = JArray.Parse(resultJsonString);
var newJsonArray = jsonArray.SelectTokens("$..VENDOR");
var result1 = JsonConvert.SerializeObject(newJsonArray, Newtonsoft.Json.Formatting.Indented);
return result1;
}
When I modified like this way, I got no data output (as shown below).
[ ]
What is proper way (area) to put the bottom code?
var jsonArray=JArray.Parse(json);
var newJsonArray = jsonArray.SelectTokens("$..VENDOR");
var result= JsonConvert.SerializeObject(newJsonArray, Newtonsoft.Json.Formatting.Indented);

You could create a new JObject assigning to it the JObject value available at the "vendor" field.
You could do something like this:
JObject changed = jobj["vendor"].Value<JObject>();
Here is an example:
JObject toChange = new JObject();
toChange["vendor"] = new JObject();
toChange["vendor"]["fieldA"] = "value";
toChange["vendor"]["fieldB"] = "value";
JObject changed = toChange["vendor"].Value<JObject>();
Console.WriteLine(toChange.ToString());
Console.WriteLine(changed.ToString());
FROM THIS:
{
"vendor": {
"fieldA": "value",
"fieldB": "value"
}
}
YOU'D GET THIS:
{
"fieldA": "value",
"fieldB": "value"
}

try this using Newtonsoft.Json
using Newtonsoft.Json;
....
var json="[{\"VENDOR\":{\"RECORDNO\":\"1\",\"VENDORID\":\"ID1\",\"NAME\":\"Name1\"}},{\"VENDOR\":{\"RECORDNO\":\"2\",\"VENDORID\":\"ID2\",\"NAME\":\"Name2\"}},{\"VENDOR\":{\"RECORDNO\":\"3\",\"VENDORID\":\"ID3\",\"NAME\":\"Name3\"}}]"
var jsonArray=JArray.Parse(json);
var newJsonArray = jsonArray.SelectTokens("$..VENDOR");
var result= JsonConvert.SerializeObject(newJsonArray, Newtonsoft.Json.Formatting.Indented);
result
[ {
"RECORDNO": "1",
"VENDORID": "ID1",
"NAME": "Name1"
},
{
"RECORDNO": "2",
"VENDORID": "ID2",
"NAME": "Name2"
},
{
"RECORDNO": "3",
"VENDORID": "ID3",
"NAME": "Name3"
} ]
or you can create classes and have typed c# list
var jsonDeserialized=JsonConvert.DeserializeObject<VendorRoot[]>(json);
List<VENDOR> newJsonList = jsonDeserialized.Select(d => d.VENDOR ).ToList();
var result= JsonConvert.SerializeObject(newJsonList, Newtonsoft.Json.Formatting.Indented);
classes
public class VendorRoot
{
public VENDOR VENDOR { get; set; }
}
public class VENDOR
{
public string RECORDNO { get; set; }
public string VENDORID { get; set; }
public string NAME { get; set; }
}

Related

Consider missing object keys as null in JSON.net with JSON Path

My JSON looks like this sometime, which has name key missing in 2nd object. It may be any key in thousands of JSON file I read dynamically to extract fields required using JSON Path queries.
void Main()
{
string jsonText = #"[
{
'rank': 1,
'name': 'name 1',
'year': '1991'
},
{
'rank': 2,
'year': '1992'
},
{
'rank': 3,
'name': 'name 3',
'year': '1993'
}
]";
JToken json = JToken.Parse(jsonText);
List<Fields> fields = new List<Fields>
{
new Fields
{
name = "rank",
path = "$.[*].rank",
result = new List<string>()
},
new Fields
{
name = "name",
path = "$.[*].name",
result = new List<string>()
},
new Fields
{
name = "year",
path = "$.[*].year",
result = new List<string>()
}
};
foreach(var field in fields)
{
var result = json.SelectTokens(field.path);
foreach (var token in result)
{
if (token is JObject || token is JArray)
{
field.result.Add(token.ToString(Newtonsoft.Json.Formatting.None));
}
else
{
field.result.Add(token.ToString());
}
}
}
fields.Dump();
}
public class Fields
{
public string name { get; set; }
public string path { get; set; }
public List<string> result {get; set;}
}
Which results in below incorrect table as the "name 3" moved one row up on 2nd row. While it should be on 3rd row and the 2nd row should have null value.
Here is one way (Updated to fix trailing missing fields):
void Main()
{
string jsonText = #"[
{
'rank': 1,
'name': 'name 1',
'year': '1991'
},
{
'rank': 2,
'year': '1992'
},
{
'rank': 3,
'name': 'name 3',
}
]";
JToken json = JToken.Parse(jsonText);
List<Fields> fields = new List<Fields>
{
new Fields
{
name = "rank",
path = "$.[*].rank",
result = new List<string>()
},
new Fields
{
name = "name",
path = "$.[*].name",
result = new List<string>()
},
new Fields
{
name = "year",
path = "$.[*].year",
result = new List<string>()
}
};
var max = json.SelectTokens("$.[*]").Count().Dump();
foreach (var field in fields)
{
var result = json.SelectTokens(field.path);
var index = 0;
foreach (var token in result)
{
while(!token.Path.StartsWith($"[{index++}]"))
field.result.Add(null);
if (token is JObject || token is JArray)
{
field.result.Add(token.ToString(Newtonsoft.Json.Formatting.None));
}
else
{
field.result.Add(token.ToString());
}
}
field.result.AddRange(Enumerable.Range(0,max-result.Count()).Select(z=>(string)null));
}
fields.Dump();
}
public class Fields
{
public string name { get; set; }
public string path { get; set; }
public List<string> result { get; set; }
}

How can I create a JsonPatchDocument from comparing two c# objects?

Given I have two c# objects of the same type, I want to compare them to create a JsonPatchDocument.
I have a StyleDetail class defined like this:
public class StyleDetail
{
public string Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public decimal OriginalPrice { get; set; }
public decimal Price { get; set; }
public string Notes { get; set; }
public string ImageUrl { get; set; }
public bool Wishlist { get; set; }
public List<string> Attributes { get; set; }
public ColourList Colours { get; set; }
public SizeList Sizes { get; set; }
public ResultPage<Style> Related { get; set; }
public ResultPage<Style> Similar { get; set; }
public List<Promotion> Promotions { get; set; }
public int StoreStock { get; set; }
public StyleDetail()
{
Attributes = new List<string>();
Colours = new ColourList();
Sizes = new SizeList();
Promotions = new List<Promotion>();
}
}
if I have two StyleDetail objects
StyleDetail styleNew = db.GetStyle(123);
StyleDetail styleOld = db.GetStyle(456);
I now want to create a JsonPatchDocument so I can send the differences to my REST API... How to do this??
JsonPatchDocument patch = new JsonPatchDocument();
// Now I want to populate patch with the differences between styleNew and styleOld - how?
in javascript, there is a library to do this https://www.npmjs.com/package/rfc6902
Calculate diff between two objects:
rfc6902.createPatch({first: 'Chris'}, {first: 'Chris', last:
'Brown'});
[ { op: 'add', path: '/last', value: 'Brown' } ]
but I am looking for a c# implementation
Let's abuse the fact that your classes are serializable to JSON!
Here's a first attempt at a patch creator that doesn't care about your actual object, only about the JSON representation of that object.
public static JsonPatchDocument CreatePatch(object originalObject, object modifiedObject)
{
var original = JObject.FromObject(originalObject);
var modified = JObject.FromObject(modifiedObject);
var patch = new JsonPatchDocument();
FillPatchForObject(original, modified, patch, "/");
return patch;
}
static void FillPatchForObject(JObject orig, JObject mod, JsonPatchDocument patch, string path)
{
var origNames = orig.Properties().Select(x => x.Name).ToArray();
var modNames = mod.Properties().Select(x => x.Name).ToArray();
// Names removed in modified
foreach (var k in origNames.Except(modNames))
{
var prop = orig.Property(k);
patch.Remove(path + prop.Name);
}
// Names added in modified
foreach (var k in modNames.Except(origNames))
{
var prop = mod.Property(k);
patch.Add(path + prop.Name, prop.Value);
}
// Present in both
foreach (var k in origNames.Intersect(modNames))
{
var origProp = orig.Property(k);
var modProp = mod.Property(k);
if (origProp.Value.Type != modProp.Value.Type)
{
patch.Replace(path + modProp.Name, modProp.Value);
}
else if (!string.Equals(
origProp.Value.ToString(Newtonsoft.Json.Formatting.None),
modProp.Value.ToString(Newtonsoft.Json.Formatting.None)))
{
if (origProp.Value.Type == JTokenType.Object)
{
// Recurse into objects
FillPatchForObject(origProp.Value as JObject, modProp.Value as JObject, patch, path + modProp.Name +"/");
}
else
{
// Replace values directly
patch.Replace(path + modProp.Name, modProp.Value);
}
}
}
}
Usage:
var patch = CreatePatch(
new { Unchanged = new[] { 1, 2, 3, 4, 5 }, Changed = "1", Removed = "1" },
new { Unchanged = new[] { 1, 2, 3, 4, 5 }, Changed = "2", Added = new { x = "1" } });
// Result of JsonConvert.SerializeObject(patch)
[
{
"path": "/Removed",
"op": "remove"
},
{
"value": {
"x": "1"
},
"path": "/Added",
"op": "add"
},
{
"value": "2",
"path": "/Changed",
"op": "replace"
}
]
You could use my DiffAnalyzer. It's based on reflection and you can configure the depth you want to analyze.
https://github.com/rcarubbi/Carubbi.DiffAnalyzer
var before = new User { Id = 1, Name="foo"};
var after= new User { Id = 2, Name="bar"};
var analyzer = new DiffAnalyzer();
var results = analyzer.Compare(before, after);
You can use this
You can install using NuGet, see SimpleHelpers.ObjectDiffPatch at NuGet.org
PM> Install-Package SimpleHelpers.ObjectDiffPatch
Use:
StyleDetail styleNew = new StyleDetail() { Id = "12", Code = "first" };
StyleDetail styleOld = new StyleDetail() { Id = "23", Code = "second" };
var diff = ObjectDiffPatch.GenerateDiff (styleOld , styleNew );
// original properties values
Console.WriteLine (diff.OldValues.ToString());
// updated properties values
Console.WriteLine (diff.NewValues.ToString());

Json using Newtonsoft.Json in C# - Object serialized to Property. JObject instance expected

I receive the error "Object serialized to Property. JObject instance expected." when trying to use the following:
SortedList<string,string> results = new SortedList<string,string>();
results.Add("BOBB", "Bob Brattwurst");
results.Add("DANG", "Dan Germany");
results.Add("KON", "Konrad Plith");
JObject output = JObject.FromObject(
new JProperty("suggestions",
new JArray(
from r in results
orderby r.Value
select new JObject(
new JProperty("value", r.Key),
new JProperty("data", r.Value)
)
)
)
);
The error occurs when setting the output variable.
This is placed in a Web service, and the expected Json result should look like:
{
"suggestions": [
{ "value": "BOBB", "data": "Bob Brattwurst" },
{ "value": "DANG", "data": "Dan Germany" },
{ "value": "KON", "data": "Konraid Plith" }
]
}
I've checked against an example i found here: http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm
However i don't quite see the issue.
you could read your data into a custom data structure (or anonymous types if you prefer), which represents your json:
public class JsonContainer
{
[JsonProperty("suggestions")]
public List<JsonData> Suggestions { get;set; }
}
public class JsonData
{
[JsonProperty("value")]
public string Value { get; set; }
[JsonProperty("data")]
public string Data { get; set; }
}
// ...
var results = new SortedList<string, string>();
results.Add("BOBB", "Bob Brattwurst");
results.Add("DANG", "Dan Germany");
results.Add("KON", "Konrad Plith");
var container = new JsonDataContainer();
container.Suggestions = results.Select(r => new JsonData
{
Value = r.Key,
Data = r.Value
}).ToList();
var json = JsonConvert.SerializeObject(container);
A solution maybe to read the data into an anoymous object, following a similar take to heinzbeinz.
SortedList<string, string> results = new SortedList<string, string>();
results.Add("BOBB", "Bob Brattwurst");
results.Add("DANG", "Dan Germany");
results.Add("KON", "Konrad Plith");
var obj = new
{
Suggestions = results.Select(x => new { Value = x.Key, Data = x.Value }).ToList()
};
var jsonString = JsonConvert.SerializeObject(obj);

How to deserialize JSON text?

I have project which uses Json data, I try deserialize a Json data like this:
[{"232":{"id":"232","reference":"022222","name":"Poire","content_title":"","content":"","pv_ttc":"230","picture_1":"","picture_2":"","picture_3":"","picture_4":"","picture_5":""}}]
If I correctly understand Json, at the beginning we have an index, then a sub-board with the name the reference the price etc.
Well, how to deserialize this text to object?
Knowing that I have my class as this:
public class productClass
{
public string id {get;set;}
public string reference { get; set; }
public string name { get; set; }
public string content_title{ get; set; }
public string content { get; set; }
public float pv_ttc{get;set;}
public string picture_1{get;set;}
public string picture_2{get;set;}
public string picture_3{get;set;}
public string picture_4{get;set;}
public string picture_5{get;set;}
public List<productClass> urlResult;
public productClass ( )
{
}
public productClass (string _id, string _reference, string _name, string _content_title, string _content, float _pv_ttc, string _picture_1, string _picture_2, string _picture_3, string _picture_4, string _picture_5)
{
id = _id;
reference = _reference;
name = _name;
content_title = _content_title;
content = _content;
pv_ttc = _pv_ttc;
picture_1 = _picture_1;
picture_2 = _picture_2;
picture_3 = _picture_3;
picture_4 = _picture_4;
picture_5 = _picture_5;
urlResult = new List<productClass> ( );
}
public void addUrl ( List<productClass> urlResult )
{
foreach ( productClass _url in urlResult )
{
urlResult.Add ( _url );
}
}
}
Thanks for help.
#sachou have you considered using JSON.Net? It is a really nice framework for .Net and you can easily de-serialize JSON strings into your C# objects. You can have a look in the documentation, but here is a simple example from the website:
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
I hope this helps.
I'd suggest you use a JSON Framework like
Newtonsoft JSON.NET
You can very easily serialize and deserialize JSON objects like this:
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
Take a closer look at Serializing/Deserializing JSON with JSON.net
Here is my example. I am using google map api as an example
I create following class corresponding to google maps
public class AddressComponent
{
public string long_name { get; set; }
public string short_name { get; set; }
public List<string> types { get; set; }
}
public class Result
{
public List<AddressComponent> address_components { get; set; }
public List<string> types { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
public string status { get; set; }
}
Then I created this method
public string GetZipCodeBasedonCoordinates()
{
string zip = "";
string url2 = #"https://maps.googleapis.com/maps/api/geocode/json?latlng=37.423021, -122.083739&sensor=false";
System.Net.WebClient web = new System.Net.WebClient();
var result = web.DownloadString(url2);
RootObject root = JsonConvert.DeserializeObject<RootObject>(result);
var allresults = root.results;
foreach (var res in allresults)
{
foreach (var add in res.address_components)
{
var type = add.types;
if (type[0] == "postal_code")
{
zip = add.long_name;
}
}
}
return zip;
}
You can go here to see the resulting json that I have parsed
https://maps.googleapis.com/maps/api/geocode/json?latlng=37.423021,%20-122.083739&sensor=false
For more informations, see my deserialize's method :
public IEnumerator loadProducts (int cat)
{
List <int> catNoTri = new List<int> ();
catNoTri.Add (0);
gm.totalPriceItem.Clear();
isLoading = true;
WWW www = new WWW ( urlProduct );
yield return www;
Debug.Log(www.text);
string json = www.text.ToString ( );
IndexPrductClass myJson = JsonReader.Deserialize<IndexPrductClass> ( json );
foreach (productClass item in products)
{
for (int i = 0; i < products.Length; i++)
{
Debug.Log("product.productValue[i] = " + products[i].name);
}
if (firstLoad || gm.catId == 0)
{
Debug.Log ("here1");
nameProduct.Add (item.name);
Debug.Log("item.name = " + item.name);
idProduct.Add (item.id);
prixItem.Add (item.pv_ttc);
Debug.Log("item.pv_ttc = " + item.pv_ttc);
gm.totalPriceItem.Add (0);
gm.qte = new int [gm.totalPriceItem.Count];
descriptifProduct.Add (item.content);
Debug.Log(" item.content = " +item.content);
}
else if (!firstLoad)
{
Debug.Log ("here2");
nameProduct.Add (item.name);
idProduct.Add (item.id);
prixItem.Add (item.pv_ttc);
gm.totalPriceItem.Add (0);
gm.qte = new int [gm.totalPriceItem.Count];
descriptifProduct.Add (item.content);
}
}
gm.canLoad = true;
}

Json.NET serialize object with root name

In my web app I'm using Newtonsoft.Json and I have following object
[Newtonsoft.Json.JsonObject(Title = "MyCar")]
public class Car
{
[Newtonsoft.Json.JsonProperty(PropertyName = "name")]
public string Name{get;set;}
[Newtonsoft.Json.JsonProperty(PropertyName = "owner")]
public string Owner{get;set;}
}
and I want serialize them with root name (class name). This is desired format using
{'MyCar':
{
'name': 'Ford',
'owner': 'John Smith'
}
}
I know that I can do that with anonymous object, but is any property or another way in Newtonsoft.Json library?
Use anonymous class
Shape your model the way you want using anonymous classes:
var root = new
{
car = new
{
name = "Ford",
owner = "Henry"
}
};
string json = JsonConvert.SerializeObject(root);
I found an easy way to render this out... simply declare a dynamic object and assign the first item within the dynamic object to be your collection class...This example assumes you're using Newtonsoft.Json
private class YourModelClass
{
public string firstName { get; set; }
public string lastName { get; set; }
}
var collection = new List<YourModelClass>();
var collectionWrapper = new {
myRoot = collection
};
var output = JsonConvert.SerializeObject(collectionWrapper);
What you should end up with is something like this:
{"myRoot":[{"firstName":"John", "lastName": "Citizen"}, {...}]}
You can easily create your own serializer
var car = new Car() { Name = "Ford", Owner = "John Smith" };
string json = Serialize(car);
string Serialize<T>(T o)
{
var attr = o.GetType().GetCustomAttribute(typeof(JsonObjectAttribute)) as JsonObjectAttribute;
var jv = JValue.FromObject(o);
return new JObject(new JProperty(attr.Title, jv)).ToString();
}
Sorry, my english is not that good. But i like to improve the upvoted answers.
I think that using Dictionary is more simple and clean.
class Program
{
static void Main(string[] args)
{
agencia ag1 = new agencia()
{
name = "Iquique",
data = new object[] { new object[] {"Lucas", 20 }, new object[] {"Fernando", 15 } }
};
agencia ag2 = new agencia()
{
name = "Valparaiso",
data = new object[] { new object[] { "Rems", 20 }, new object[] { "Perex", 15 } }
};
agencia agn = new agencia()
{
name = "Santiago",
data = new object[] { new object[] { "Jhon", 20 }, new object[] { "Karma", 15 } }
};
Dictionary<string, agencia> dic = new Dictionary<string, agencia>
{
{ "Iquique", ag1 },
{ "Valparaiso", ag2 },
{ "Santiago", agn }
};
string da = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
Console.WriteLine(da);
Console.ReadLine();
}
}
public class agencia
{
public string name { get; set; }
public object[] data { get; set; }
}
This code generate the following json (This is desired format)
{
"Iquique":{
"name":"Iquique",
"data":[
[
"Lucas",
20
],
[
"Fernando",
15
]
]
},
"Valparaiso":{
"name":"Valparaiso",
"data":[
[
"Rems",
20
],
[
"Perex",
15
]
]
},
"Santiago":{
"name":"Santiago",
"data":[
[
"Jhon",
20
],
[
"Karma",
15
]
]
}
}
string Json = JsonConvert.SerializeObject(new Car { Name = "Ford", Owner = "John Smith" }, Formatting.None);
for the root element use GlobalConfiguration.
A very simple approach for me is just to create 2 classes.
public class ClassB
{
public string id{ get; set; }
public string name{ get; set; }
public int status { get; set; }
public DateTime? updated_at { get; set; }
}
public class ClassAList
{
public IList<ClassB> root_name{ get; set; }
}
And when you going to do serialization:
var classAList = new ClassAList();
//...
//assign some value
//...
var jsonString = JsonConvert.SerializeObject(classAList)
Lastly, you will see your desired result as the following:
{
"root_name": [
{
"id": "1001",
"name": "1000001",
"status": 1010,
"updated_at": "2016-09-28 16:10:48"
},
{
"id": "1002",
"name": "1000002",
"status": 1050,
"updated_at": "2016-09-28 16:55:55"
}
]
}
Hope this helps!
Well, you can at least tell Json.NET to include the type name: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm . Newtonsoft.Json.JsonSerializer jser = new Newtonsoft.Json.JsonSerializer();
jser.TypeNameHandling = TypeNameHandling.Objects;
The type will be included at the beginning in the "$type" property of the object.
This is not exactly what you are looking for, but it was good enough for me when facing a similiar problem.
Writing a custom JsonConverter is another approach mentioned in similar questions. However, due to nature of how JsonConverter is designed, using that approach for this question is tricky, as you need to be careful with the WriteJson implementation to avoid getting into infinite recursion: JSON.Net throws StackOverflowException when using [JsonConvert()].
One possible implementation:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//JToken t = JToken.FromObject(value); // do not use this! leads to stack overflow
JsonObjectContract contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());
writer.WriteStartObject();
writer.WritePropertyName(value.GetType().Name);
writer.WriteStartObject();
foreach (var property in contract.Properties)
{
// this removes any property with null value
var propertyValue = property.ValueProvider.GetValue(value);
if (propertyValue == null) continue;
writer.WritePropertyName(property.PropertyName);
serializer.Serialize(writer, propertyValue);
//writer.WriteValue(JsonConvert.SerializeObject(property.ValueProvider.GetValue(value))); // this adds escaped quotes
}
writer.WriteEndObject();
writer.WriteEndObject();
}
I hope this help.
//Sample of Data Contract:
[DataContract(Name="customer")]
internal class Customer {
[DataMember(Name="email")] internal string Email { get; set; }
[DataMember(Name="name")] internal string Name { get; set; }
}
//This is an extension method useful for your case:
public static string JsonSerialize<T>(this T o)
{
MemoryStream jsonStream = new MemoryStream();
var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
serializer.WriteObject(jsonStream, o);
var jsonString = System.Text.Encoding.ASCII.GetString(jsonStream.ToArray());
var props = o.GetType().GetCustomAttributes(false);
var rootName = string.Empty;
foreach (var prop in props)
{
if (!(prop is DataContractAttribute)) continue;
rootName = ((DataContractAttribute)prop).Name;
break;
}
jsonStream.Close();
jsonStream.Dispose();
if (!string.IsNullOrEmpty(rootName)) jsonString = string.Format("{{ \"{0}\": {1} }}", rootName, jsonString);
return jsonString;
}
//Sample of usage
var customer = new customer {
Name="John",
Email="john#domain.com"
};
var serializedObject = customer.JsonSerialize();
[Newtonsoft.Json.JsonObject(Title = "root")]
public class TestMain
this is the only attrib you need to add to get your code working.

Categories