ExpandoObject
thực hiện IConnection<KeyValuePair>
và IEnumerable<KeyValuePair>
:
public sealed class ExpandoObject :
IDynamicMetaObjectProvider,
IDictionary<string, object>,
ICollection<KeyValuePair<string, object>>,
IEnumerable<KeyValuePair<string, object>>,
IEnumerable, INotifyPropertyChanged
tôi đoán là trong nội bộ, serializer ServiceStack được điều trị các ExpandoObject
như một IEnumerable<KeyValuePair>
, và vì vậy nó serializes đến một mảng JSON của cặp/giá trị then chốt.
Điều này khác với lần đầu tiên đoạn mã (làm việc) của bạn bởi vì .NET thực sự xây dựng một lớp học thực tế (giấu tên) cho dữ liệu của bạn, về cơ bản nó làm cho:
public class SomeNameTheCompilerMakesUp {
internal int Value { get; set; }
internal string Product { get; set; }
}
cho bạn tự động, vì vậy khi nó được gửi đến serializer, nó đang làm việc với một lớp thực với các thuộc tính thực, trong khi ExpandoObject
thực sự được hỗ trợ bởi một object[]
nội bộ.
Trên mặt lưu ý, System.Web.Helpers.Json
của Microsoft cũng hoạt động tương tự. Xét nghiệm này đi:
[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);
}
Một chỉnh sửa cuối cùng:
Bạn có thể làm cho công việc này theo cách bạn muốn bằng cách chuyển ExpandoObject
của bạn thành một Dictionary<string, object>
. Thông báo trước cho mã này là nó sao chép dữ liệu vào một từ điển, do đó bạn có 2 bản sao trong bộ nhớ (hoặc hơi ít hơn, vì về mặt kỹ thuật các chuỗi có thể được thực hiện).
[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);
}
Mặc dù, cho bất cứ ai đi qua sau này, và đang thực sự sử dụng System.Web.Helpers.Json
, điều tốt hơn để làm là chỉ cần quấn bạn ExpandoObject
trong một DynamicJsonObject
như thế này:
[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);
}
Ans một lần tôi làm việc thông qua đó, tôi đã tìm thấy một câu hỏi tương tự ở đây: How to flatten an ExpandoObject returned via JsonResult in asp.net mvc?
Dường như bộ nối tiếp hiểu sai cấu trúc dữ liệu của bạn ... bạn có thể đăng cấu trúc không? –
Nếu bạn cài đặt ServiceStack.Text, bạn sẽ có thể chạy mã của tôi ở trên (lặp lại các câu lệnh sử dụng). –