WebService是以独立于平台的方式,通过标准的Web协议,可以由程序访问的应用程序逻辑单元。
(1)应用程序逻辑单元:web服务包括一些应用程序逻辑单元或者代码。这些代码可以完成运算任务,可以完成数据库查询,可以完成计算机程序能够完成的任何工作。
(2)可由程序访问:当前大多是web站点都是通过浏览器由人工访问的,web服务可以由计算机程序来访问。
(3)标准的we协议:Web服务的所有协议都是基于一组标准的Web协议,如HTTP、XML、SOAP、WSDl、UDDI等
(4)平台独立性:web服务可以在任何平台上实现。因为标准协议不是由单个供应商专用的,它由大多数主要供应商支持。
SOAP(Simple Object Access Protocol,简单对象访问协议)协议:是用于交换XML编码信息的轻量级协议,SOAP协议是HTTP和XML协议的组合。
WSDL(Web Service Description Language,Web服务描述语言)是用XML文档来描述Web服务的标准,是Web服务的接口定义语言。
第一种方法:直接在项目引用->添加服务引用->输入webservice的地址->确定
ServiceReference1.WebService1SoapClient web = new ServiceReference1.WebService1SoapClient();
web.HelloWebService();
第二种方法:调用方法一模拟生成一个代理类,通过反射来调用里面的方法
string @namespace = "WebServers";
string classname = "WebService1";
string methodname = "HelloWebService";
//获取WSDL
WebClient client = new WebClient();//可以方便的创建Http请求并获取返回内容
string url = "http://localhost:24244/WebService1.asmx?WSDL";//这个地址可以写在Config文件里面,这里取出来就行了.在原地址后面加上: ?WSDL
Stream stream = client.OpenRead(url);
ServiceDescription description = ServiceDescription.Read(stream);
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//创建客户端代理类
importer.AddServiceDescription(description, null, null);
CodeNamespace nmspace = new CodeNamespace();//new CodeNamespace(@namespace);//命名空间
//生成客户端代理
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
importer.ProtocolName = "Soap";//指定访问协议
importer.Style = ServiceDescriptionImportStyle.Client;//生成客户端代理
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateOldAsync;
nmspace.Name = @namespace;
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);//产生的警告类型
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
//设定编译参数
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false;//是否生成可执行文件
parameter.GenerateInMemory = true;
//parameter.OutputAssembly = "MyTest.dll";//输出程序集的名称
parameter.ReferencedAssemblies.Add("System.dll");//获取当前项目引用的程序集
parameter.ReferencedAssemblies.Add("System.XML.dll");
parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
parameter.ReferencedAssemblies.Add("System.Data.dll");
//编译代理类
CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); //icc.CompileAssemblyFromDom(parameter, unit);
if (result.Errors.HasErrors)
{
//显示编译错误
StringBuilder builder = new StringBuilder();
foreach (CompilerError ce in result.Errors)
{
builder.Append(ce.ToString());
builder.Append(System.Environment.NewLine);//获取当前环境定义的换行字符
}
}
//生成代理实例,并调用方法
Assembly asm = result.CompiledAssembly; //Assembly.LoadFrom("MyTest.dll");//加载前面生成的程序集
Type t = asm.GetType(@namespace + "." + classname, true, true);//反射
object o = Activator.CreateInstance(t);
//反射获取方法
MethodInfo method = t.GetMethod(methodname);//methodname是WebService的方法名
//method.Invoke(o,null)返回的是一个Object,如果你服务端返回的是DataSet,这里也可以强转(DataSet)
//method.Invoke(o,null)这里null可以传递调用方法的参数,string[]形式
object obj = method.Invoke(o, null);//调用方法
第三种方法:利用 wsdl.exe生成webservice代理类
//利用 wsdl.exe生成webservice代理类:
//根据提供的wsdl生成webservice代理类,然后在代码里引用这个类文件。
/*步骤:1、在开始菜单找到 Microsoft Visual Studio 2010 下面的Visual Studio Tools , 点击Visual Studio 命令提示(2010),打开命令行。
2、 在命令行中输入: wsdl /language:c# /n:TestDemo /out:d:/Temp/TestService.cs http://jm1.services.gmcc.net/ad/Services/AD.asmx?wsdl
这句命令行的意思是:对最后面的服务地址进行编译,在D盘temp 目录下生成testservice文件。
3、 把上面命令编译后的cs文件,复制到我们项目中,在项目代码中可以直接new 一个出来后,可以进行调用。*/
第四种方法:利用http 协议的get 和post
//webServices 应该支持Get和Post调用,在web.config应该增加以下代码
//<webServices>
// <protocols>
// <add name="HttpGet"/>
// <add name="HttpPost"/>
// </protocols>
//</webServices>
Hashtable ht = new Hashtable();
ht.Add("str", "test");
ht.Add("b", "true");
XmlDocument xx = QueryPostWebService("http://localhost:24244/WebService1.asmx", "HelloWebService",null);
封装的方法
/// <summary>
/// 需要WebService支持Post调用
/// </summary>
/// <param name="URL"></param>
/// <param name="MethodName"></param>
/// <param name="Pars"></param>
/// <returns></returns>
public static XmlDocument QueryPostWebService(string URL, string MethodName, Hashtable Pars)
{
HttpWebRequest requset = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);
requset.Method = "POST";
requset.ContentType = "application/x-www-form-urlencoded";
SetWebRequest(requset);
byte[] data = EncodePars(Pars);
WriteRequestData(requset, data);
return ReadXmlResponse(requset.GetResponse());
}
public static XmlDocument QueryGetWebService(string URL, string MethodName, Hashtable Pars)
{
HttpWebRequest requset = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);
requset.Method = "GET";
requset.ContentType = "application/x-www-form-urlencoded";
SetWebRequest(requset);
return ReadXmlResponse(requset.GetResponse());
}
public static XmlDocument QuerySoapWebService(string URL, string MethodName, Hashtable Pars)
{
if (_xmlNamespaces.ContainsKey(URL))
{
return QuerySoapWebService(URL, MethodName, Pars);
}
else
return QuerySoapWebService(URL, MethodName, Pars);
}
public static XmlDocument QuerySoapWebService(string URL, string MethodName, Hashtable Pars, string XmlNs)
{
_xmlNamespaces[URL] = XmlNs;//加入缓存,提高效率
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);
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/*/*").InnerXml;
doc2.LoadXml("<root>" + RetXml + "</root>");
AddDelaration(doc2);
return doc2;
}
public 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);
}
/// <summary>
/// 将对象转换成xml
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public static string ObjectToSoapXml(object o)
{
XmlSerializer mySerializer = new XmlSerializer(o.GetType());//序列化为XML文档
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();
}
/// <summary>
/// 设置凭证与超时时间
/// </summary>
/// <param name="request"></param>
public static void SetWebRequest(HttpWebRequest request)
{
request.Credentials = CredentialCache.DefaultCredentials;
request.Timeout = 10000;
}
/// <summary>
/// 将字符串中所有的字符编码成一个字节序列
/// </summary>
/// <param name="Pars"></param>
/// <returns></returns>
public static byte[] EncodePars(Hashtable Pars)
{
return Encoding.UTF8.GetBytes(ParsToString(Pars));
}
/// <summary>
/// Hashtable转换成字符串
/// </summary>
/// <param name="Pars"></param>
/// <returns></returns>
public static string ParsToString(Hashtable Pars)
{
StringBuilder builder = new StringBuilder();
if (Pars != null)
{
foreach (string k in Pars.Keys)
{
builder.Append("&");
}
}
return builder.ToString();
}
/// <summary>
/// 把得到的数据写入流
/// </summary>
/// <param name="request"></param>
/// <param name="data"></param>
private static void WriteRequestData(HttpWebRequest request, byte[] data)
{
request.ContentLength = data.Length;
Stream writer = request.GetRequestStream();
writer.Write(data, 0, data.Length);
writer.Flush();
writer.Close();
}
/// <summary>
/// 返回的数据流写入到xml中
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 创建一个节点
/// </summary>
/// <param name="doc"></param>
private static void AddDelaration(XmlDocument doc)
{
XmlDeclaration decl = doc.CreateXmlDeclaration("1.0","utf-8",null);
doc.InsertBefore(decl,doc.DocumentElement);
}
private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace