2012-02-21 13 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