I have the following model structure.
public class ReferenceData
{
public string Version { get; set; }
public List<DataItem> Data { get; set; }
}
public class DataItem
{
public Dictionary<string, string> Item { get; set; }
}
In the dictionary i'm adding the key value pair and serializing with KeyValuePairConverter
setting.
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
Converters = new List<JsonConverter>() { new KeyValuePairConverter() }
};
var object = Newtonsoft.Json.JsonConvert.SerializeObject(
referenceData,
Formatting.None,
settings
);
And the output is,
{
"data":[
{
"item":{
"ShortDescription":"Lorem ipssumm",
"Title":"some text",
"PlanType":"ZEROP",
}
},
{
"item":{
"ShortDescription":"Lorem ipssumm",
"Title":"some text",
"PlanType":"ZEROP",
}
},
{
"item":{
"ShortDescription":"Lorem ipssumm",
"Title":"some text",
"PlanType":"ZEROP",
}
}
]
}
If we don't want item
to be showed in the serialized string, what setting needs to be done in JsonSerializerSettings
or is there any other way to do that.
Please note that i can not change the model structure as it is required.
output should be :
{
"data":[
{
"ShortDescription":"Lorem ipssumm",
"Title":"some text",
"PlanType":"ZEROP"
},
{
"ShortDescription":"Lorem ipssumm",
"Title":"some text",
"PlanType":"ZEROP"
},
{
"ShortDescription":"Lorem ipssumm",
"Title":"some text",
"PlanType":"ZEROP"
}
]
}
You do not need nested generic collections if you use Json.NET 5.0 release 5 or later version. You can use JsonExtensionDataAttribute
so that Item
dictionary's keys and values will be serialized as a part of parent object.
public class ReferenceData
{
public string version { get; set; }
public List<DataItem> data { get; set; }
}
public class DataItem
{
[JsonExtensionData]
public IDictionary<string, object> item { get; set; }
}
// ...
var referenceData = new ReferenceData {
version = "1.0",
data = new List<DataItem> {
new DataItem {
item = new Dictionary<string, object> {
{"1", "2"},
{"3", "4"}
}
},
new DataItem {
item = new Dictionary<string, object> {
{"5", "8"},
{"6", "7"}
}
}
}
};
Console.WriteLine(JsonConvert.SerializeObject(referenceData));
Pay attention that you need Dictionary<string, object>
instead of Dictionary<string, string>
.
Here is the result I get:
{
"version": "1.0",
"data": [
{
"1": "2",
"3": "4"
},
{
"5": "8",
"6": "7"
}
]
}
Obviously, you can remove Version
property to get the expected result.
Read more here: http://james.newtonking.com/archive/2013/05/08/json-net-5-0-release-5-defaultsettings-and-extension-data
If you change like this result will be what you expected;
public class ReferenceData
{
public string Version { get; set; }
public List<Dictionary<string, string>> Data { get; set; }
}
possible other solution is;
ReferenceData r = new ReferenceData();
r.Data = new List<DataItem>();
r.Data.Add(new DataItem { Item = new Dictionary<string, string>() { { "1", "2" }, { "3", "4" } } });
var anon = new
{
data = r.Data.ToList().Select(x =>
{
dynamic data = new ExpandoObject();
IDictionary<string, object> dictionary = (IDictionary<string, object>)data;
foreach (var key in x.Item.Keys)
dictionary.Add(key, x.Item[key]);
return dictionary;
}
)
};
var result = JsonConvert.SerializeObject(anon);
result :
{
"data": [
{
"1": "2",
"3": "4"
}
]
}
If you can't change the C# can use you a View model and use an appropriate structure. It's probably simpler than changing JSON settings, easier to return to and more explicit:
public class ReferenceData
{
public string Version { get; set; }
public List<Dictionary<string, string>> Data { get; set; }
}
Should serialise as you require.
You could implement a custom behaviour as follows:
class Program {
static void Main(string[] args) {
var referenceData = new ReferenceData() {
Data = new List<DataItem>() {
new DataItem(){
Item = new Dictionary<string,string>() {
{"ShortDescription", "Lorem ipssumm"},
{"Title", "some text"},
{"PlanType", "ZEROP"},
}
},
new DataItem(){
Item = new Dictionary<string,string>() {
{"ShortDescription", "Lorem ipssumm"},
{"Title", "some text"},
{"PlanType", "ZEROP"},
}
},
new DataItem(){
Item = new Dictionary<string,string>() {
{"ShortDescription", "Lorem ipssumm"},
{"Title", "some text"},
{"PlanType", "ZEROP"},
}
}
}
};
var settings = new JsonSerializerSettings {
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
Converters = new List<JsonConverter>() { new KeyValuePairConverter(), new CustomJsonSerializableConverter() }
};
File.WriteAllText("hello.json", Newtonsoft.Json.JsonConvert.SerializeObject(
referenceData,
Formatting.Indented,
settings
));
}
}
public class ReferenceData {
public string Version { get; set; }
public List<DataItem> Data { get; set; }
}
[CustomJsonSerializable]
public class DataItem {
public Dictionary<string, string> Item { get; set; }
public static void WriteJson(JsonWriter writer, DataItem value, JsonSerializer serializer) {
serializer.Serialize(writer, value.Item);
}
public static DataItem ReadJson(JsonReader reader, DataItem existingValue, JsonSerializer serializer) {
DataItem result = new DataItem();
result.Item = serializer.Deserialize<Dictionary<string, string>>(reader);
return result;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class CustomJsonSerializableAttribute : Attribute {
public readonly string Read;
public readonly string Write;
public CustomJsonSerializableAttribute()
: this(null, null) {
}
public CustomJsonSerializableAttribute(string read, string write) {
this.Read = read;
this.Write = write;
}
}
public class CustomJsonSerializableConverter : JsonConverter {
public override bool CanConvert(Type objectType) {
return objectType.GetCustomAttribute(typeof(CustomJsonSerializableAttribute), false) != null;
}
public override bool CanWrite {
get {
return true;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
if(value != null) {
var t = value.GetType();
var attr = (CustomJsonSerializableAttribute)t.GetCustomAttribute(typeof(CustomJsonSerializableAttribute), false);
var @delegate = t.GetMethod(attr.Write ?? "WriteJson", new Type[] { typeof(JsonWriter), t, typeof(JsonSerializer) });
@delegate.Invoke(null, new object[] { writer, value, serializer });
} else {
serializer.Serialize(writer, null);
}
}
public override bool CanRead {
get {
return true;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
var t = existingValue.GetType();
var attr = (CustomJsonSerializableAttribute)t.GetCustomAttribute(typeof(CustomJsonSerializableAttribute), false);
var @delegate = t.GetMethod(attr.Read ?? "ReadJson", new Type[] { typeof(JsonReader), t, typeof(JsonSerializer) });
return @delegate.Invoke(null, new object[] { reader, existingValue, serializer });
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.