どうやら、オブジェクトIDictionary<string,object>
の配列としてシリアル化されKeyValuePair
ます (例: [{Key:"foo", Value:"bar"}, ...]
)。代わりにオブジェクトとしてシリアル化することは可能ですか (例: {foo:"bar"}
)?
5 に答える
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)\/"}
お役に立てれば!
いいえ、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"}}
Linq Select を使用して JavaScriptSerializer で解決できました。
var dictionary = new Dictionary<int, string>();
var jsonOutput = new JavaScriptSerializer().Serialize(dictionary.Select(x => new { Id = x.Key, DisplayText = x.Value }));
これは、トーマスの回答からの改良版だと思います。魅力のように機能します。ScriptIgnore 属性のチェックを追加することもできますが、自分自身をノックアウトしてください。
ところで、私が JavaScriptSerializer を選んだのは、ほとんどの場合、サード パーティのソリューションが知名度が低く、インストールに時間がかかり、前提条件が忘れられており、著作権の状態がぼやけており、ビジネスで配布するのが危険であると考えているためです。
PS: インスタンスと辞書としてのインスタンスの両方に逆シリアル化しようとしている理由がわからなかったので、その部分を取り除きました。
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) });
}
}
}