C#获取对象属性值

syb1045 2011-04-01 09:09:39
用动态调用WEBSERVICE获取到一个对象,本地用object接受数据, 调试的时候可以看到对象内的值,以及对象是什么类型的(如userinfo)。我怎么才能取出其中的属性值呢。
用Type types=obj.GetType();
System.Reflection.PropertyInfo[] ps = types.GetProperties();
取得的ps长度是0.

我自己本地测试,新建个userinfo类型,然后给属性赋值。再赋给一个object对象objuser 用
Type types=objuser.GetType();
System.Reflection.PropertyInfo[] ps = types.GetProperties();
可以取得属性值,。。 为什么远程获取的对象取不到呢。。
求指点。。。

...全文
1389 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
hch126163 2011-04-01
  • 打赏
  • 举报
回复
.Net下采用GET/POST/SOAP方式动态调用WebService的简易灵活方法(C#) [轉]Redfox
一直以来,我都为动态调用WebService方法而烦恼。在.Net环境下,最常用的方法就是采用代理类来调用WebService,可以通过改变代理类的Url属性来实现动态调用,但当xmlns改变时就会出错,似乎要重新绑定Webservice并重新编译后才能再次运行。我还试过网上的一种动态编译并动态调用WebService的方式,这种方法效率低,而且需要有较高的权限,否则编译失败。我曾在Sql Server 2005的CLR存储过程中用此方法调用WebService时,浪费了大半天时间,无论怎么试它就是不能成功编译。于是我便不断思考其他的方法,今天晚上终于写了一个类用于动态调用WebService,只需传入WebService地址、需调用的方法及其参数,就可以随时动态调用了。现分享给大家,代码如下:

using System;
using System.Web;
using System.Xml;
using System.Collections;
using System.Net;
using System.Text;
using System.IO;
using System.Xml.Serialization;

//By huangz 2008-3-19

/**//// <summary>
/// 利用WebRequest/WebResponse进行WebService调用的类,By 同济黄正 http://hz932.ys168.com 2008-3-19
/// </summary>
public class WebSvcCaller
{
//<webServices>
// <protocols>
// <add name="HttpGet"/>
// <add name="HttpPost"/>
// </protocols>
//</webServices>

private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace

/**//// <summary>
/// 需要WebService支持Post调用
/// </summary>
public static XmlDocument QueryPostWebService(String URL , String MethodName , Hashtable Pars)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
SetWebRequest(request);
byte[] data = EncodePars(Pars);
WriteRequestData(request , data);

return ReadXmlResponse(request.GetResponse());
}
/**//// <summary>
/// 需要WebService支持Get调用
/// </summary>
public static XmlDocument QueryGetWebService(String URL , String MethodName , Hashtable Pars)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName + "?" + ParsToString(Pars));
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
SetWebRequest(request);
return ReadXmlResponse(request.GetResponse());
}


/**//// <summary>
/// 通用WebService调用(Soap),参数Pars为String类型的参数名、参数值
/// </summary>
public static XmlDocument QuerySoapWebService(String URL , String MethodName , Hashtable Pars)
{
if (_xmlNamespaces.ContainsKey(URL))
{
return QuerySoapWebService(URL , MethodName , Pars , _xmlNamespaces[URL].ToString());
}
else
{
return QuerySoapWebService(URL , MethodName , Pars ,GetNamespace(URL));
}
}

private static XmlDocument QuerySoapWebService(String URL , String MethodName , Hashtable Pars , string XmlNs)
{ //By 同济黄正 http://hz932.ys168.com 2008-3-19
_xmlNamespaces[URL] = XmlNs;//加入缓存,提高效率
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "text/xml; charset=utf-8";
request.Headers.Add("SOAPAction" , "\"" + XmlNs + (XmlNs.EndsWith("/") ? "" : "/") + MethodName + "\"");
SetWebRequest(request);
byte[] data = EncodeParsToSoap(Pars , XmlNs , MethodName);
WriteRequestData(request , data);
XmlDocument doc = new XmlDocument() , doc2 = new XmlDocument();
doc = ReadXmlResponse(request.GetResponse());

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("soap" , "http://schemas.xmlsoap.org/soap/envelope/");
String RetXml = doc.SelectSingleNode("//soap:Body/*/*" , mgr).InnerXml;
doc2.LoadXml("<root>" + RetXml + "</root>");
AddDelaration(doc2);
return doc2;
}
private static string GetNamespace(String URL)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");
SetWebRequest(request);
WebResponse response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream() , Encoding.UTF8);
XmlDocument doc = new XmlDocument();
doc.LoadXml(sr.ReadToEnd());
sr.Close();
return doc.SelectSingleNode("//@targetNamespace").Value;
}
private static byte[] EncodeParsToSoap(Hashtable Pars , String XmlNs , String MethodName)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"></soap:Envelope>");
AddDelaration(doc);
XmlElement soapBody = doc.CreateElement("soap" , "Body" , "http://schemas.xmlsoap.org/soap/envelope/");
XmlElement soapMethod = doc.CreateElement(MethodName);
soapMethod.SetAttribute("xmlns" , XmlNs);
foreach (string k in Pars.Keys)
{
XmlElement soapPar = doc.CreateElement(k);
soapPar.InnerXml = ObjectToSoapXml(Pars[k]);
soapMethod.AppendChild(soapPar);
}
soapBody.AppendChild(soapMethod);
doc.DocumentElement.AppendChild(soapBody);
return Encoding.UTF8.GetBytes(doc.OuterXml);
}
private static string ObjectToSoapXml(object o)
{
XmlSerializer mySerializer = new XmlSerializer(o.GetType());
MemoryStream ms=new MemoryStream();
mySerializer.Serialize(ms,o);
XmlDocument doc=new XmlDocument();
doc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));
if(doc.DocumentElement !=null)
{
return doc.DocumentElement.InnerXml ;
}
else
{
return o.ToString();
}
}
private static void SetWebRequest(HttpWebRequest request)
{
request.Credentials = CredentialCache.DefaultCredentials;
request.Timeout = 10000;
}

private static void WriteRequestData(HttpWebRequest request , byte[] data)
{
request.ContentLength = data.Length;
Stream writer = request.GetRequestStream();
writer.Write(data , 0 , data.Length);
writer.Close();
}

private static byte[] EncodePars(Hashtable Pars)
{
return Encoding.UTF8.GetBytes(ParsToString(Pars));
}

private static String ParsToString(Hashtable Pars)
{
StringBuilder sb = new StringBuilder();
foreach (string k in Pars.Keys)
{
if (sb.Length > 0)
{
sb.Append("&");
}
sb.Append(HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(Pars[k].ToString()));
}
return sb.ToString();
}

private static XmlDocument ReadXmlResponse(WebResponse response)
{
StreamReader sr = new StreamReader(response.GetResponseStream() , Encoding.UTF8);
String retXml = sr.ReadToEnd();
sr.Close();
XmlDocument doc = new XmlDocument();
doc.LoadXml(retXml);
return doc;
}

private static void AddDelaration(XmlDocument doc)
{
XmlDeclaration decl = doc.CreateXmlDeclaration("1.0" , "utf-8" , null);
doc.InsertBefore(decl , doc.DocumentElement);
}
}



这个类有三个公用的方法:QuerySoapWebService为通用的采用Soap方式调用WebService,QueryGetWebService采用GET方式调用,QueryPostWebService采用POST方式调用,后两个方法需要WebService服务器支持相应的调用方式。三个方法的参数和返回值相同:URL为Webservice的Url地址(以.asmx结尾的);MethodName为要调用的方法名称;Pars为参数表,它的Key为参数名称,Value为要传递的参数的值,Value可为任意对象,前提是这个对象可以被xml序列化。注意方法名称、参数名称、参数个数必须完全匹配才能正确调用。第一次以Soap方式调用时,因为需要查询WSDL获取xmlns,因此需要时间相对长些,第二次调用不用再读WSDL,直接从缓存读取。这三个方法的返回值均为XmlDocument对象,这个返回的对象可以进行各种灵活的操作。最常用的一个SelectSingleNode方法,可以让你一步定位到Xml的任何节点,再读取它的文本或属性。也可以直接调用Save保存到磁盘。采用Soap方式调用时,根结点名称固定为root。

这个类主要是利用了WebRequest/WebResponse来完成各种网络查询操作。为了精简明了,这个类中没有添加错误处理,需要在调用的地方设置异常捕获。

下面是一个调用实例:

protected void Page_Load(object sender , EventArgs e)
{
try
{
Hashtable pars = new Hashtable();
String Url = "http://www.260dns.cn/Services/Weather.asmx";
pars["city"] = "上海";
pars["wdate"]="2008-3-19";
XmlDocument doc = WebSvcCaller.QuerySoapWebService(Url , "GetWeather" , pars);
Response.Write(doc.OuterXml);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}

pan1001 2011-04-01
  • 打赏
  • 举报
回复
obj.GetType().FullName 會回傳完整的 類型名稱.

再用 此完整的名稱 寫 轉型 的 Code .
机器人 2011-04-01
  • 打赏
  • 举报
回复
是 GetFields() 不是 GetProperties()
机器人 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 syb1045 的回复:]
晕 。。 难道获取到的对象中,不能取出里面的属性(字段)值来吗?
求 给力
[/Quote]

已经给出回答了,不仔细看怪谁呢?
生成 public Fields 了。(不是Property)

foreach (var p in type.GetFields()) Console.WriteLine("{0}:{1}", p.Name, p.GetValue(obj));
pan1001 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 syb1045 的回复:]

(类型)obj 报错。。
用as 转,得到的是空的
[/Quote]

那是你用 錯了 類型 吧 !

由 "區域變數" 的 畫面中 可以 看到 obj 實際的 類型.
syb1045 2011-04-01
  • 打赏
  • 举报
回复
晕 。。 难道获取到的对象中,不能取出里面的属性(字段)值来吗?
求 给力
pan1001 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 syb1045 的回复:]

我也想这么操作啊 ,, 接口是对方提供的, 我只拿到接口说明文档 。 目前在测试接口调用中。。
本地添加WEB应用失败。。 直接访问对方的WEBSERIVE, 显示空白页, 没有XML数据放回。
自己可以用 soap 或者 http 直接请求
soap直接请求怎么弄。 求指点。。
我用的http 直接请求,返回空白。
[/Quote]

看你 提出的 Code. 感覺上 對方是 使用 .NET Remoting 技術 或者是 WCF 的特殊功能.

所以 , 才會 無法是用 一般 WebService 的 呼叫方式.
syb1045 2011-04-01
  • 打赏
  • 举报
回复
能不玩,我也不想玩啊, 我是被逼的。。
直接引用不出来的。。直接访问对方提供的接口也是空白的,
所以才找了这种方使用, 能得到返回结果,却卡在取属性值上了。
  • 打赏
  • 举报
回复
别胡乱玩什么“动态调用”。正常地使用web service编程吧。
syb1045 2011-04-01
  • 打赏
  • 举报
回复
(类型)obj 报错。。
用as 转,得到的是空的
pan1001 2011-04-01
  • 打赏
  • 举报
回复
不要糾結在 type.GetProperties()

你都已經知道 實際的 類型 , 所 將 OBJ 轉型 為 實際 的 類型 不就可以了.
syb1045 2011-04-01
  • 打赏
  • 举报
回复
foreach (var p in type.GetProperties())

这个GetProperties()获取不到值啊
机器人 2011-04-01
  • 打赏
  • 举报
回复
var obj = InvokeWebservice("http://localhost:3850/Service1.asmx", "", "Service1", "GetUser", null);
var type = obj.GetType();
foreach (var p in type.GetProperties())
Console.WriteLine("{0}:{1}", p.Name, p.GetValue(obj, null));
foreach (var p in type.GetFields())
Console.WriteLine("{0}:{1}", p.Name, p.GetValue(obj));
Console.Read();


生成 public Fields 了。(不是Property)
syb1045 2011-04-01
  • 打赏
  • 举报
回复
我也想这么操作啊 ,, 接口是对方提供的, 我只拿到接口说明文档 。 目前在测试接口调用中。。
本地添加WEB应用失败。。 直接访问对方的WEBSERIVE, 显示空白页, 没有XML数据放回。
自己可以用 soap 或者 http 直接请求
soap直接请求怎么弄。 求指点。。
我用的http 直接请求,返回空白。
hch126163 2011-04-01
  • 打赏
  • 举报
回复
直接 添加web 引用。调用是返回的就是本地对象!

webservice 通常返回的是xml!

自己可以用 soap 或者 http 直接请求
自己处理返回的xml 就可以了
syb1045 2011-04-01
  • 打赏
  • 举报
回复
/// 根据指定的信息,调用远程WebService方法

/// </summary>

/// <param name="url">WebService的http形式的地址</param>

/// <param name="namespace">欲调用的WebService的命名空间</param>

/// <param name="classname">欲调用的WebService的类名(不包括命名空间前缀)</param>

/// <param name="methodname">欲调用的WebService的方法名</param>

/// <param name="args">参数列表</param>

/// <returns>WebService的执行结果</returns>
public static object InvokeWebservice(string url, string @namespace, string classname, string methodname, object[] args)
{
try
{
System.Net.WebClient wc = new System.Net.WebClient();
System.IO.Stream stream = wc.OpenRead(url + "?WSDL");
System.Web.Services.Description.ServiceDescription sd = System.Web.Services.Description.ServiceDescription.Read(stream);
System.Web.Services.Description.ServiceDescriptionImporter sdi = new System.Web.Services.Description.ServiceDescriptionImporter();
sdi.AddServiceDescription(sd, "", "");
System.CodeDom.CodeNamespace cn = new System.CodeDom.CodeNamespace(@namespace);
System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);

Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.ICodeCompiler icc = csc.CreateCompiler();

System.CodeDom.Compiler.CompilerParameters cplist = new System.CodeDom.Compiler.CompilerParameters();
cplist.GenerateExecutable = false;
cplist.GenerateInMemory = true;
cplist.ReferencedAssemblies.Add("System.dll");
cplist.ReferencedAssemblies.Add("System.XML.dll");
cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
cplist.ReferencedAssemblies.Add("System.Data.dll");

System.CodeDom.Compiler.CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
if (true == cr.Errors.HasErrors)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
}
throw new Exception(sb.ToString());
}
//System.Reflection.Assembly assembly = cr.CompiledAssembly;
assembly = cr.CompiledAssembly;
Type t = assembly.GetType(@namespace + "." + classname, true, true);
object obj = Activator.CreateInstance(t);
System.Reflection.MethodInfo mi = t.GetMethod(methodname);
return mi.Invoke(obj, args);

}
catch (Exception ex)
{
return ex.Message;
}
}

obj =DoMenthod.InvokeWebservice("http://IP/CenterWS.asmx","","类名", "方法名", args);
Type types=obj.GetType();
System.Reflection.PropertyInfo[] ps = types.GetProperties();
小童 2011-04-01
  • 打赏
  • 举报
回复
webservice返回用json把
机器人 2011-04-01
  • 打赏
  • 举报
回复
匿名对象也应该可以通过反射获得属性才是厄。。。代码贴出来看看?
haojuntu 2011-04-01
  • 打赏
  • 举报
回复
等待高手解答!
syb1045 2011-04-01
  • 打赏
  • 举报
回复
谢谢老胡同志顶力找了个SOAP方式的调用了。
经测试, 也是可以用的,,
谢谢大家了 圆满结贴,完事!!
加载更多回复(1)

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧