显然,IDictionary<string,object>
被序列化为 KeyValuePair
对象的数组(例如,[{Key:"foo", Value:"bar"}, ...]
)。是否可以将其序列化为对象而不是数组(例如,{foo:"bar"}
)?
显然,IDictionary<string,object>
被序列化为 KeyValuePair
对象的数组(例如,[{Key:"foo", Value:"bar"}, ...]
)。是否可以将其序列化为对象而不是数组(例如,{foo:"bar"}
)?
虽然我同意JavaScriptSerializer是垃圾,Json.Net是更好的选择,但有一种方式可以让JavaScriptSerializer按照你想要的方式进行序列化。 你需要注册一个转换器,并使用类似于以下代码重写Serialize方法:
public class KeyValuePairJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
var instance = Activator.CreateInstance(type);
foreach (var p in instance.GetType().GetPublicProperties())
{
instance.GetType().GetProperty(p.Name).SetValue(instance, dictionary[p.Name], null);
dictionary.Remove(p.Name);
}
foreach (var item in dictionary)
(instance).Add(item.Key, item.Value);
return instance;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var result = new Dictionary<string, object>();
var dictionary = obj as IDictionary<string, object>;
foreach (var item in dictionary)
result.Add(item.Key, item.Value);
return result;
}
public override IEnumerable<Type> SupportedTypes
{
get
{
return new ReadOnlyCollection<Type>(new Type[] { typeof(your_type) });
}
}
}
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() });
jsonOfTest = javaScriptSerializer.Serialize(test);
// {"x":"xvalue","y":"\/Date(1314108923000)\/"}
希望这能有所帮助!instance
变量没有添加方法。 - artifex_somnia不,使用JavaScriptSerializer是不可能的。可以使用Json.NET实现:
public class Bar
{
public Bar()
{
Foos = new Dictionary<string, string>
{
{ "foo", "bar" }
};
}
public Dictionary<string, string> Foos { get; set; }
}
var bar = new Bar();
string json = JsonConvert.SerializeObject(bar, new KeyValuePairConverter());
会产生所需的结果:
{"Foos":{"foo":"bar"}}
JavaScriptSerializer
相比,Json.NET就像糖一样甜。所以如果你在使用Json.NET时遇到问题,我不知道该说什么关于替代方案的事情了 :-) 至于你的另一个问题,那是完全正常的行为。你向序列化程序指示的只是一个字符串和对象的字典。因此,在你的代码中,你正在使用弱类型字典,你期望得到什么回报呢?当然,你只能得到弱类型的JObjects。使用强类型字典:Dictionary<string, SomeModel>
,会有所不同。 - Darin DimitrovDictionary
和 IDictionary
之间的区别--明白了。谢谢。 - Danielvar dictionary = new Dictionary<int, string>();
var jsonOutput = new JavaScriptSerializer().Serialize(dictionary.Select(x => new { Id = x.Key, DisplayText = x.Value }));
.Serialize(dictionary)
,它也能正常工作。它比JsonConvert更简单,可以直接使用。我希望我能给这个答案+2。 - Bernardo Dal Cornopublic class KeyValuePairJsonConverter : JavaScriptConverter {
public override object Deserialize(IDictionary<string, object> dictionary
, Type type
, JavaScriptSerializer serializer) {
throw new InvalidOperationException("Sorry, I do serializations only.");
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) {
Dictionary<string, object> result = new Dictionary<string, object>();
Dictionary<string, MyClass> dictionaryInput = obj as Dictionary<string, MyClass>;
if (dictionaryInput == null) {
throw new InvalidOperationException("Object must be of Dictionary<string, MyClass> type.");
}
foreach (KeyValuePair<string, MyClass> pair in dictionaryInput)
result.Add(pair.Key, pair.Value);
return result;
}
public override IEnumerable<Type> SupportedTypes {
get {
return new ReadOnlyCollection<Type>(new Type[] { typeof(Dictionary<string, MyClass>) });
}
}
}
这是如何使用它的:
JavaScriptSerializer js = new JavaScriptSerializer();
js.RegisterConverters(new JavaScriptConverter[] { new KeyValuePairJsonConverter() });
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.Write(js.Serialize(myObject));
public class KeyValuePairJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> deserializedJSObjectDictionary, Type targetType, JavaScriptSerializer javaScriptSerializer)
{
Object targetTypeInstance = Activator.CreateInstance(targetType);
FieldInfo[] targetTypeFields = targetType.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo fieldInfo in targetTypeFields)
fieldInfo.SetValue(targetTypeInstance, deserializedJSObjectDictionary[fieldInfo.Name]);
return targetTypeInstance;
}
public override IDictionary<string, object> Serialize(Object objectToSerialize, JavaScriptSerializer javaScriptSerializer)
{
IDictionary<string, object> serializedObjectDictionary = new Dictionary<string, object>();
FieldInfo[] objectToSerializeTypeFields = objectToSerialize.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo fieldInfo in objectToSerializeTypeFields)
serializedObjectDictionary.Add(fieldInfo.Name, fieldInfo.GetValue(objectToSerialize));
return serializedObjectDictionary;
}
public override IEnumerable<Type> SupportedTypes
{
get
{
return new ReadOnlyCollection<Type>(new Type[] { typeof(YOURCLASSNAME) });
}
}
}