用於有同樣的問題。我創建了一個簡單的擴展方法,將L2E對象「扁平化」爲一個IDictionary。一個IDictionary由JavaScriptSerializer正確序列化。生成的Json與直接序列化對象相同。
由於我限制了序列化的級別,所以避免了循環引用。它也不包括1-> n鏈接表(Entitysets)。
private static IDictionary<string, object> JsonFlatten(object data, int maxLevel, int currLevel) {
var result = new Dictionary<string, object>();
var myType = data.GetType();
var myAssembly = myType.Assembly;
var props = myType.GetProperties();
foreach (var prop in props) {
// Remove EntityKey etc.
if (prop.Name.StartsWith("Entity")) {
continue;
}
if (prop.Name.EndsWith("Reference")) {
continue;
}
// Do not include lookups to linked tables
Type typeOfProp = prop.PropertyType;
if (typeOfProp.Name.StartsWith("EntityCollection")) {
continue;
}
// If the type is from my assembly == custom type
// include it, but flattened
if (typeOfProp.Assembly == myAssembly) {
if (currLevel < maxLevel) {
result.Add(prop.Name, JsonFlatten(prop.GetValue(data, null), maxLevel, currLevel + 1));
}
} else {
result.Add(prop.Name, prop.GetValue(data, null));
}
}
return result;
}
public static IDictionary<string, object> JsonFlatten(this Controller controller, object data, int maxLevel = 2) {
return JsonFlatten(data, maxLevel, 1);
}
我的行動方法是這樣的:
public JsonResult AsJson(int id) {
var data = Find(id);
var result = this.JsonFlatten(data);
return Json(result, JsonRequestBehavior.AllowGet);
}
來源
2010-09-08 09:54:04
GvS
我將不得不提供一個鏡頭,但不幸的是這是來自一個域/核心對象,我不確定我想引入對該項目的System.Web.Script.Serialization的引用。我將這些核心對象封裝在一個模型中,我想我可以使用'ScriptIgnore',但在那時我可以刪除循環引用。此解決方案似乎提供了類似的解決方案,以匿名類型http://stackoverflow.com/questions/372955/best-way-to-filter-domain-objects-for-json-output-in-an-asp-net -mvc-application/372977#372977 – ahsteele 2010-01-05 01:46:35
也可以。你應該對你的問題/評論有具體的說明 - 說你不能/不會刪除循環引用不同於說模型中你不能/不會改變任何東西。我經常將匿名類型傳遞給'Json',我在這裏看到的唯一問題是,如果您有多個方法返回JSON'ed'Machine',則需要記住每次「過濾」它。我眼中的巧克力與香草 - 它們都是不錯的選擇。 – Aaronaught 2010-01-05 02:25:01
@Aaron瞭解。不確定我不能/不會確定它*感覺*是否正確地將引用添加到核心/域項目,以便爲特定的UI情況提供此解決方案。我喜歡使用NonSerializedAttribute作爲System名稱空間中的解決方案。這似乎是JavaScriptSerializer忽略它的一個缺點。 – ahsteele 2010-01-05 02:48:23