ExpandoObject
実装IConnection<KeyValuePair>
とIEnumerable<KeyValuePair>
:
public sealed class ExpandoObject :
IDynamicMetaObjectProvider,
IDictionary<string, object>,
ICollection<KeyValuePair<string, object>>,
IEnumerable<KeyValuePair<string, object>>,
IEnumerable, INotifyPropertyChanged
私の推測では、ServiceStack シリアライザーは内部的に をExpandoObject
として扱っているIEnumerable<KeyValuePair>
ため、キーと値のペアの JSON 配列にシリアル化されます。
.NET は実際にデータの実際の (匿名) クラスを構築するため、これは最初の (作業中の) コード スニペットとは異なります。
public class SomeNameTheCompilerMakesUp {
internal int Value { get; set; }
internal string Product { get; set; }
}
そのため、シリアライザーに送信されると、実際のプロパティを持つ実際のクラスで動作しますが、は内部ExpandoObject
で実際にサポートされています。object[]
ちなみに、MicrosoftSystem.Web.Helpers.Json
も同じように動作します。このテストは合格します:
[TestMethod]
public void ExpandoObjectSerializesToJsonArray()
{
dynamic anonType = new { Value = 10, Product = "Apples" };
dynamic expando = new ExpandoObject();
expando.Value = 10;
expando.Product = "Apples";
var anonResult = System.Web.Helpers.Json.Encode(anonType);
var expandoResult = System.Web.Helpers.Json.Encode(expando);
Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", anonResult);
Assert.AreEqual("[{\"Key\":\"Value\",\"Value\":10},{\"Key\":\"Product\",\"Value\":\"Apples\"}]", expandoResult);
}
最後の編集:
ExpandoObject
を に変換することで、これを好きなように機能させることができますDictionary<string, object>
。このコードの注意点は、データをディクショナリに複製するため、メモリに 2 つのコピーがあることです (技術的には文字列がインターンされる可能性があるため、それよりわずかに少なくなります)。
[TestMethod]
public void TestMethod1()
{
dynamic expando = new ExpandoObject();
expando.Value = 10;
expando.Product = "Apples";
// copy expando properties to dictionary
var dictionary = ((ExpandoObject)expando).ToDictionary(x => x.Key, x => x.Value);
var expandoResult = System.Web.Helpers.Json.Encode(expando);
var dictionaryResult = System.Web.Helpers.Json.Encode(dictionary);
Assert.AreEqual("[{\"Key\":\"Value\",\"Value\":10},{\"Key\":\"Product\",\"Value\":\"Apples\"}]", expandoResult);
Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", dictionaryResult);
}
ただし、後でこれに遭遇し、実際に を使用している人にとっては、次のようSystem.Web.Helpers.Json
にラップするだけの方がよいでしょう:ExpandoObject
DynamicJsonObject
[TestMethod]
public void TestMethod1()
{
dynamic expando = new ExpandoObject();
expando.Value = 10;
expando.Product = "Apples";
var dictionaryResult = System.Web.Helpers.Json.Encode(new DynamicJsonObject(expando));
Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", dictionaryResult);
}
私がそれを処理した後、ここで同様の質問を見つけました: How to flatten an ExpandoObject returned via JsonResult in asp.net mvc?