序列化 IEnumerable<IDictionary<string, object>> 不适用于 DefaultNamingStrategy
Serialize IEnumerable<IDictionary<string, object>> doesn't work with DefaultNamingStrategy
默认情况下,我在项目中使用 CamelCasePropertyNamesContractResolver 序列化为 json。但是我想为一个 属性.
改变这个策略
public class ViewTable
{
public int Id { get; set; }
[JsonProperty(NamingStrategyType = typeof(DefaultNamingStrategy), ItemTypeNameHandling = TypeNameHandling.None, TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<IDictionary<string, object>> Rows { get; set; }
}
所以当我序列化这个对象时,我希望得到这样的 json:
"result": {
"id": 15,
"rows": [
{
"SessionData_Department": "",
"SystemData_SerialNumber": "1"
}
]
}
但我得到了:
"result": {
"id": 15,
"Rows": [ //There must be a lowercase!!!
{
"sessionData_Department": "", //There must be a uppercase!!!
"systemData_SerialNumber": "1"
}
]
}
我的项目中有这样的 json 设置:
var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.TypeNameHandling = TypeNameHandling.Auto;
如何告诉 json 序列化程序对 IDictionary 使用 DefaultNamingStrategy?
您必须延长 DefaultNamingStrategy
:
public class CamelCaseDictionaryKeyNamingStrategy : DefaultNamingStrategy
{
public CamelCaseDictionaryKeyNamingStrategy() : base() { this.ProcessDictionaryKeys = true; }
public override string GetDictionaryKey(string key)
{
if (ProcessDictionaryKeys && !string.IsNullOrEmpty(key))
{
if (char.ToUpperInvariant(key[0]) != key[0])
{
var builder = new StringBuilder(key) { [0] = char.ToUpperInvariant(key[0]) };
return builder.ToString();
}
}
return key;
}
}
然后像这样使用它:
IDictionary<string, object> idict = new Dictionary<string, object>();
idict.Add("sessionData_Department", "1");
idict.Add("systemData_SerialNumber", "1");
IEnumerable<IDictionary<string, object>> row = new List<IDictionary<string, object>> { idict };
var val = new ViewTable
{
Id = 15,
Rows = row
};
var cc = new CamelCasePropertyNamesContractResolver
{
NamingStrategy = new CamelCaseDictionaryKeyNamingStrategy()
};
JsonSerializerSettings config = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = cc,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto
};
string js = JsonConvert.SerializeObject(val, config);
输出:
我已将 Rows
更新为:
public class ViewTable
{
public int Id { get; set; }
[JsonProperty(PropertyName = "rows", NamingStrategyType = typeof(DefaultNamingStrategy), ItemTypeNameHandling = TypeNameHandling.None, TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<IDictionary<string, object>> Rows { get; set; }
}
我不确定 out-of-the 框中是否有设置。但是您可以通过扩展 JsonConverter
并使用 DefaultContractResolver
:
来实现
public class RowsConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var settings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
};
writer.WriteRawValue(JsonConvert.SerializeObject(value, settings));
}
}
然后将Rows
属性改为:
[JsonProperty(ItemConverterType = typeof(RowsConverter))]
public IEnumerable<IDictionary<string, object>> Rows { get; set; }
默认情况下,我在项目中使用 CamelCasePropertyNamesContractResolver 序列化为 json。但是我想为一个 属性.
改变这个策略public class ViewTable
{
public int Id { get; set; }
[JsonProperty(NamingStrategyType = typeof(DefaultNamingStrategy), ItemTypeNameHandling = TypeNameHandling.None, TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<IDictionary<string, object>> Rows { get; set; }
}
所以当我序列化这个对象时,我希望得到这样的 json:
"result": {
"id": 15,
"rows": [
{
"SessionData_Department": "",
"SystemData_SerialNumber": "1"
}
]
}
但我得到了:
"result": {
"id": 15,
"Rows": [ //There must be a lowercase!!!
{
"sessionData_Department": "", //There must be a uppercase!!!
"systemData_SerialNumber": "1"
}
]
}
我的项目中有这样的 json 设置:
var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.TypeNameHandling = TypeNameHandling.Auto;
如何告诉 json 序列化程序对 IDictionary 使用 DefaultNamingStrategy?
您必须延长 DefaultNamingStrategy
:
public class CamelCaseDictionaryKeyNamingStrategy : DefaultNamingStrategy
{
public CamelCaseDictionaryKeyNamingStrategy() : base() { this.ProcessDictionaryKeys = true; }
public override string GetDictionaryKey(string key)
{
if (ProcessDictionaryKeys && !string.IsNullOrEmpty(key))
{
if (char.ToUpperInvariant(key[0]) != key[0])
{
var builder = new StringBuilder(key) { [0] = char.ToUpperInvariant(key[0]) };
return builder.ToString();
}
}
return key;
}
}
然后像这样使用它:
IDictionary<string, object> idict = new Dictionary<string, object>();
idict.Add("sessionData_Department", "1");
idict.Add("systemData_SerialNumber", "1");
IEnumerable<IDictionary<string, object>> row = new List<IDictionary<string, object>> { idict };
var val = new ViewTable
{
Id = 15,
Rows = row
};
var cc = new CamelCasePropertyNamesContractResolver
{
NamingStrategy = new CamelCaseDictionaryKeyNamingStrategy()
};
JsonSerializerSettings config = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = cc,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto
};
string js = JsonConvert.SerializeObject(val, config);
输出:
我已将 Rows
更新为:
public class ViewTable
{
public int Id { get; set; }
[JsonProperty(PropertyName = "rows", NamingStrategyType = typeof(DefaultNamingStrategy), ItemTypeNameHandling = TypeNameHandling.None, TypeNameHandling = TypeNameHandling.None)]
public IEnumerable<IDictionary<string, object>> Rows { get; set; }
}
我不确定 out-of-the 框中是否有设置。但是您可以通过扩展 JsonConverter
并使用 DefaultContractResolver
:
public class RowsConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var settings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
};
writer.WriteRawValue(JsonConvert.SerializeObject(value, settings));
}
}
然后将Rows
属性改为:
[JsonProperty(ItemConverterType = typeof(RowsConverter))]
public IEnumerable<IDictionary<string, object>> Rows { get; set; }