.net 调用java webservie
以前学习webservice只知道soap协议,xml标准传输数据,项目里直接引用服务就可以了,再深一点就是服务做口令,或者数字证书认证。
可是最近在做项目的时候,需要在用友u8 nc 上架桥,传输数据,知道u8是C#写的,所以可以直接引用调试服务,可是nc是java开发的,一开始在潜意识里认为引用下就可以了,
后来网上搜索了一下,发现不行,nc5.6以下的产品,webservice都不可以网页访问。
后来找到方法,可以通过get post方式访问webservice,可是调用不成功,看来服务不支持这样调用(nc数据交换平台好像支持http传送数据,我们是自己做的服务),
在网上搜索的代码如下:
using System; using System.Web; using System.Xml; using System.Collections; using System.Net; using System.Text; using System.IO; using System.Xml.Serialization; /// <summary> /// 利用WebRequest/WebResponse进行WebService调用的类 /// </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) { _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); } }
里面也有soap方法,可是调用nc里面的方法成功,可是传进去的参数,好像有些问题,我也没有时间深究。
没办法继续搜索,因为只要符合soap协议,webservice是可以访问了,这时候想到到了vs的wsdl.exe功能。
wsdl.exe /l:cs /out:D:\Proxy_UpdateService.cs http://localhost:1101/UpdateService.asmx?wsdl
把生成的代理类,cs文件复制到项目,调用,看看,果然可以了。
这里介绍一个工具,soapui (因为这个工具测试成功,可是C#调用的时候聚会有问题)百度下载,测试webservice的。
附加一段代码,也是网上搜索的,u8 nc数据交换都是标准的xml格式,就是对象转换成xml,list转换成xml:
namespace XmlHelper { /// <summary> /// 实体转Xml,Xml转实体类 /// </summary> /// <typeparam name="T"></typeparam> public class XmlHelper<T> where T : new() { #region 实体类转成Xml /// <summary> /// 对象实例转成xml /// </summary> /// <param name="item">对象实例</param> /// <returns></returns> public static string EntityToXml(T item,string rootname) { IList<T> items = new List<T>(); items.Add(item); //创建XmlDocument文档 XmlDocument doc = new XmlDocument(); //创建根元素 XmlElement root = doc.CreateElement(rootname); EntityToXml(doc, root, item, rootname); //向XmlDocument文档添加根元素 //doc.AppendChild(root); return root.InnerXml; } /// <summary> /// 对象实例集转成xml /// </summary> /// <param name="items">对象实例集</param> /// <returns></returns> public static string EntityToXml(IList<T> items, string rootname,string cellname) { //创建XmlDocument文档 XmlDocument doc = new XmlDocument(); //创建根元素 XmlElement root = doc.CreateElement(rootname); //添加根元素的子元素集 foreach (T item in items) { EntityToXml(doc, root, item, cellname); } //向XmlDocument文档添加根元素 //doc.AppendChild(root); XmlElement roottemp = doc.CreateElement(rootname); roottemp.AppendChild(root); return roottemp.InnerXml; } private static void EntityToXml(XmlDocument doc, XmlElement root, T item,string RootName) { //创建元素 XmlElement xmlItem = doc.CreateElement(RootName); //对象的属性集 System.Reflection.PropertyInfo[] propertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (System.Reflection.PropertyInfo pinfo in propertyInfo) { if (pinfo != null) { //对象属性名称 string name = pinfo.Name; //对象属性值 string value = String.Empty; XmlElement tempxmlItem=doc.CreateElement(name); if (pinfo.GetValue(item, null) != null) tempxmlItem.InnerText = pinfo.GetValue(item, null).ToString();//获取对象属性值 else tempxmlItem.InnerText = ""; //设置元素的属性值 xmlItem.AppendChild(tempxmlItem); } } //向根添加子元素 root.AppendChild(xmlItem); } #endregion #region Xml转成实体类 /// <summary> /// Xml转成对象实例 /// </summary> /// <param name="xml">xml</param> /// <returns></returns> public static T XmlToEntity(string xml) { IList<T> items = XmlToEntityList(xml); if (items != null && items.Count > 0) return items[0]; else return default(T); } /// <summary> /// Xml转成对象实例集 /// </summary> /// <param name="xml">xml</param> /// <returns></returns> public static IList<T> XmlToEntityList(string xml) { XmlDocument doc = new XmlDocument(); try { doc.LoadXml(xml); } catch { return null; } if (doc.ChildNodes.Count != 1) return null; if (doc.ChildNodes[0].Name.ToLower() != typeof(T).Name.ToLower() + "s") return null; XmlNode node = doc.ChildNodes[0]; IList<T> items = new List<T>(); foreach (XmlNode child in node.ChildNodes) { if (child.Name.ToLower() == typeof(T).Name.ToLower()) items.Add(XmlNodeToEntity(child)); } return items; } private static T XmlNodeToEntity(XmlNode node) { T item = new T(); if (node.NodeType == XmlNodeType.Element) { XmlElement element = (XmlElement)node; System.Reflection.PropertyInfo[] propertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (XmlAttribute attr in element.Attributes) { string attrName = attr.Name.ToLower(); string attrValue = attr.Value.ToString(); foreach (System.Reflection.PropertyInfo pinfo in propertyInfo) { if (pinfo != null) { string name = pinfo.Name.ToLower(); Type dbType = pinfo.PropertyType; if (name == attrName) { if (String.IsNullOrEmpty(attrValue)) continue; switch (dbType.ToString()) { case "System.Int32": pinfo.SetValue(item, Convert.ToInt32(attrValue), null); break; case "System.Boolean": pinfo.SetValue(item, Convert.ToBoolean(attrValue), null); break; case "System.DateTime": pinfo.SetValue(item, Convert.ToDateTime(attrValue), null); break; case "System.Decimal": pinfo.SetValue(item, Convert.ToDecimal(attrValue), null); break; case "System.Double": pinfo.SetValue(item, Convert.ToDouble(attrValue), null); break; default: pinfo.SetValue(item, attrValue, null); break; } continue; } } } } } return item; } #endregion } }
希望对需要的人不要绕弯路了。
有错误的地方欢迎大家拍砖,希望交流和共享。