今天跟同事閑聊時, 談到動態web Service返回類和list對象處理問題, 開始以為和靜態調用一樣的,先建立一個跟服務器端返回類型相同字段的類(因為是動態調用的,所以沒有在本地生成代理類, 無法使用服務器端類型.), 然后將返回的object類型強制轉換為需要的類型就行了, 誰知道實行起來還不是那回事了,不論如何轉換返回的都是null, 如下圖:
上網google了下,發現很多人也碰到過同樣的問題,但都沒有得到解決,既然網上找不到答案,只有靠自己慢慢找了。
而object對象又不能直接訪問原始映射類的屬性, 並且只有一個GetType方法可用,猜想或許利用Type反射可以讀取出來吧,但Type類有很多屬性,到底是哪一個呢? GetMembers(), GetPropertys(), GetMethods()…
一個個試了,沒有一個適合訪的,大部分返回的都是null, 最后發現有個GetFileds()方法,而這個方法返回的是FieldInfo數組,用斷點調試看了一下,發現這個數組的長度剛好是返回字段的長度,其 Name屬性就是服務器端返回類型的一個字段名稱,再繼續看FieldInfo類,FieldInfo類有個GetValue()方法,根據字面意思理 解, 應該是用來獲取這個字段的值,可是需要一個object參數,而這個object參數就是Type類的那個對象。 編寫代碼試了一下, 發現還真的可以獲取數據了。
對於處理返回單個對象的功能是實現了, 要是返回數組呢?
第一感覺也是依照前面那樣處理就行了, 於是乎,將代碼復制下來, 結果出乎意外了, GetFields()返回長度為0, 折騰了好一會,還是慢慢看Type類了,發現其IsArray是true, 還有一個GetElementType()方法,既然Type不行,我想那應訪是ElementType吧:
Type tp = o.GetType();
tp = tp.GetElementType();
FiledInfo[] fi = tp.GetFields();
這會fi有值了,先前一樣,只可惜只有一個對象的字段值,心想可能是這樣的了,但接下來又納悶了, 用FieldInfo的GetValue值時提示傳入的對象錯誤。Type及FieldInfo說明翻遍了也沒新的發現,后來一想,WebService 返回數組對象跟利用反射返回數組不一樣的嗎? Web Service中沒人碰到過這樣的問題,也許在反射應用中有人解決了呢? 於是google “C# 反射返回數組”, 看到有人說直接將object強制轉換object數組,自己雖覺得這樣可能不行, 但沒辦法下還是試試吧!還真不明白,這樣子竟然真的可以!!最終完整代碼如下:
View Code
上網google了下,發現很多人也碰到過同樣的問題,但都沒有得到解決,既然網上找不到答案,只有靠自己慢慢找了。
而object對象又不能直接訪問原始映射類的屬性, 並且只有一個GetType方法可用,猜想或許利用Type反射可以讀取出來吧,但Type類有很多屬性,到底是哪一個呢? GetMembers(), GetPropertys(), GetMethods()…
一個個試了,沒有一個適合訪的,大部分返回的都是null, 最后發現有個GetFileds()方法,而這個方法返回的是FieldInfo數組,用斷點調試看了一下,發現這個數組的長度剛好是返回字段的長度,其 Name屬性就是服務器端返回類型的一個字段名稱,再繼續看FieldInfo類,FieldInfo類有個GetValue()方法,根據字面意思理 解, 應該是用來獲取這個字段的值,可是需要一個object參數,而這個object參數就是Type類的那個對象。 編寫代碼試了一下, 發現還真的可以獲取數據了。
對於處理返回單個對象的功能是實現了, 要是返回數組呢?
第一感覺也是依照前面那樣處理就行了, 於是乎,將代碼復制下來, 結果出乎意外了, GetFields()返回長度為0, 折騰了好一會,還是慢慢看Type類了,發現其IsArray是true, 還有一個GetElementType()方法,既然Type不行,我想那應訪是ElementType吧:
Type tp = o.GetType();
tp = tp.GetElementType();
FiledInfo[] fi = tp.GetFields();
這會fi有值了,先前一樣,只可惜只有一個對象的字段值,心想可能是這樣的了,但接下來又納悶了, 用FieldInfo的GetValue值時提示傳入的對象錯誤。Type及FieldInfo說明翻遍了也沒新的發現,后來一想,WebService 返回數組對象跟利用反射返回數組不一樣的嗎? Web Service中沒人碰到過這樣的問題,也許在反射應用中有人解決了呢? 於是google “C# 反射返回數組”, 看到有人說直接將object強制轉換object數組,自己雖覺得這樣可能不行, 但沒辦法下還是試試吧!還真不明白,這樣子竟然真的可以!!最終完整代碼如下:

protected
void Page_Load(
object sender, EventArgs e)
{
object user = WebServiceHelper.InvokeWebService( " http://localhost/Service.asmx ", " Service ",
" GetObject ", null);
PrintData(user);
object lst = WebServiceHelper.InvokeWebService( " http://localhost/Service.asmx ", " Service ",
" GetList ", null);
Type Tp = lst.GetType();
if (Tp.IsArray)
{
object[] users = lst as object[];
for ( int i = 0; i < users.Length; i++)
{
PrintData(users[i]);
}
}
else
{
PrintData(lst);
}
}
public void PrintData( object o)
{
Type Tp = o.GetType();
FieldInfo[] fields = Tp.GetFields();
Response.Write( " Fields:<br/> ");
for ( int i = 0; i < fields.Length; ++i)
{
FieldInfo filed = fields.GetValue(i) as FieldInfo;
string str = String.Format( " Field Name:{0}/tField Value:{1} ", filed.Name, filed.GetValue(o));
Response.Write(str + " <br/> ");
}
Response.Write( " <br/> ");
}
{
object user = WebServiceHelper.InvokeWebService( " http://localhost/Service.asmx ", " Service ",
" GetObject ", null);
PrintData(user);
object lst = WebServiceHelper.InvokeWebService( " http://localhost/Service.asmx ", " Service ",
" GetList ", null);
Type Tp = lst.GetType();
if (Tp.IsArray)
{
object[] users = lst as object[];
for ( int i = 0; i < users.Length; i++)
{
PrintData(users[i]);
}
}
else
{
PrintData(lst);
}
}
public void PrintData( object o)
{
Type Tp = o.GetType();
FieldInfo[] fields = Tp.GetFields();
Response.Write( " Fields:<br/> ");
for ( int i = 0; i < fields.Length; ++i)
{
FieldInfo filed = fields.GetValue(i) as FieldInfo;
string str = String.Format( " Field Name:{0}/tField Value:{1} ", filed.Name, filed.GetValue(o));
Response.Write(str + " <br/> ");
}
Response.Write( " <br/> ");
}