2012-02-21 14 views
5

我有一個WebMethod,看起來像這樣被用來填充的jqGrid如何讓我的WebMethods序列ExpandoObject

[System.Web.Script.Services.ScriptService] 
public class MyWebService: System.Web.Services.WebService 
{ 
    [WebMethod] 
    [Authorize(Roles = "Admin")] 
    public object GetPeople(bool _search, double nd, int rows, int page, string sidx, string sord) 
    { 
     var tbl = new DynamicModel("ConnStr", tableName: "Person", primaryKeyField: "ID"); 
     var results = tbl.Paged(orderBy: sidx + " " + sord, currentPage: page, pageSize: rows); 
     return results; 
    } 

} 

「結果」與性質的項目,總頁數,總記錄一個System.Dynamic.ExpandoObject

的JSON我坐回從WebService看起來像這樣

{ 
"d": [{ 
    "Key": "TotalRecords", 
    "Value": 1 
}, { 
    "Key": "TotalPages", 
    "Value": 1 
}, { 
    "Key": "Items", 
    "Value": [ 
     [{ 
      "Key": "Row", 
      "Value": 1 
     }, { 
      "Key": "ID", 
      "Value": 1 
     }, { 
      "Key": "Name", 
      "Value": "Test Template" 
     }] 
    ] 
}] 
} 
} // Don't know why firebug put this extra bracket 

理想我寧願它回來沒有所有的鍵和值的業務,因爲它漲大不必要地使用json,並且不能很好地與jqGrid一起玩。

有沒有辦法改變ASP.NET處理ExpandoObject序列化的方式?

+0

朋友推薦這種方法http://stackoverflow.com/questions/5156664/how-to-flatten-an-expandoobject-returned-via-jsonresult-in-asp -net-mvc但我不知道如何註冊JavaScriptConverter與我們的JavaScriptSerializer bmethod使用。 – 2012-02-21 23:23:05

+0

該死的,我在這裏找到的答案在這裏http://msdn.microsoft.com/en-us/library/bb763183.aspx大約一半下來 – 2012-02-21 23:52:00

+0

很高興知道你學到了新的東西:) – Jull 2012-02-22 00:03:33

回答

4

這聽起來像你已經想通了這一點,但這裏的something I threw together a while back來做到這一點:

public class ExpandoObjectConverter : JavaScriptConverter { 
    public override IEnumerable<Type> SupportedTypes { 
    get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(ExpandoObject) })); } 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) { 
    ExpandoObject expando = (ExpandoObject)obj; 

    if (expando != null) { 
     // Create the representation. 
     Dictionary<string, object> result = new Dictionary<string, object>(); 

     foreach (KeyValuePair<string, object> item in expando) { 
     if (item.Value.GetType() == typeof(DateTime)) 
      result.Add(item.Key, ((DateTime)item.Value).ToShortDateString()); 
     else 
      result.Add(item.Key, item.Value.ToString()); 
     } 

     return result; 
    } 
    return new Dictionary<string, object>(); 
    } 

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) { 
    return null; 
    } 
} 

然後,你只需將它添加到<converters>部分在你的web.config,如圖所示MSDN文章中您鏈接到:

<configuration> 
    <system.web.extensions> 
    <scripting> 
     <webServices> 
     <jsonSerialization> 
      <converters> 
      <add name="ExpandoObjectConverter" type="ExpandoObjectConverter"/> 
      </converters> 
     </jsonSerialization> 
     </webServices> 
    </scripting> 
    </system.web.extensions> 
</configuration> 
+0

是的,希望這可以幫助某人其他。儘管MSDN上的應該是 shame。感謝您的快速回復Dave,熱愛工作,熱愛tekpub vids – 2012-02-22 01:13:31

+0

@SeanTomlins:Ack,這就是我盲目信任MSDN的理由!感謝您指出了這一點。我編輯了我的答案,並在MS上打了一個人,希望能糾正這個錯誤。 – 2012-02-22 01:48:44

+0

工程很好,除非值爲空。增加了一個支票,並且工作正常。 '的foreach(KeyValuePair <串,對象>在的expando項) { 如果(item.Value == NULL) result.Add(item.Key,的String.Empty); (Item.Value.GetType()== typeof(DateTime)) result.Add(item.Key,((DateTime)item.Value).ToShortDateString()); else result.Add(item.Key,item.Value.ToString()); }' – sarme 2015-04-23 21:58:21