以前学习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
}
}
希望对需要的人不要绕弯路了。