(转载)Net 下采用GET/POST/SOAP方式动态调用WebService C#实现

转自http://www.cnblogs.com/splendidme/archive/2011/10/05/2199501.html

一直以来,我们都为动态调用WebService方法而烦恼。在.Net环境下,最常用的方法就是采用代理类来调用WebService,可以通过改变代理类的Url属性来实现动态调用,但当xmlns改变时就会出错,似乎要重新绑定Webservice并重新编译后才能再次运行。我无意中通过百度搜索找了一个采用GET/POST/SOAP方式动态调用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);
       
}
    }

时间: 2024-08-01 06:28:09

(转载)Net 下采用GET/POST/SOAP方式动态调用WebService C#实现的相关文章

[转]Net 下采用GET/POST/SOAP方式动态调用WebService C#实现

本文转自:http://www.cnblogs.com/splendidme/archive/2011/10/05/2199501.html 一直以来,我们都为动态调用WebService方法而烦恼.在.Net环境下,最常用的方法就是采用代理类来调用WebService,可以通过改变代理类的Url属性来实现动态调用,但当xmlns改变时就会出错,似乎要重新绑定Webservice并重新编译后才能再次运行.我无意中通过百度搜索找了一个采用GET/POST/SOAP方式动态调用WebService的

动态调用WebService接口的几种方式

一.什么是WebService? 这里就不再赘述了,想要了解的====>传送门 二.为什么要动态调用WebService接口? 一般在C#开发中调用webService服务中的接口都是通过引用过来就行调用的,步骤如下: 1.找到引用,右击添加服务引用,找到高级,添加web引用,添加之后就可以直接调用里面的方法. 以上这种方法是最简单粗暴的一种方式.当然在开发中总是不那么如意,以上方式是在本机直接可以访问服务的地址,假如在本机不能直接访问WebService,那么就会有些蛋疼. 这种方式就不可取了

C# .NET 动态调用webservice的三种方式

转载自 百度文库 http://wenku.baidu.com/link?url=Q2q50wohf5W6UX44zqotXFEe_XOMaib4UtI3BigaNwipOHKNETloMF4ax4W4iPZcjAW6q8vu45QOjK6DSUon1R10ePVlqG6nwussbbXE6jm 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我们可能需要在程序运行期间动态调用一个未知的服务.在 .NET Framework

Atitit 动态调用webservice与客户端代理方式调用

方式1: 使用call.invoke  直接调用WSDL,缺点:麻烦,不推荐--特别是JAVA调用.NET的WS时,会有不少的问题需要解决. 方式2: 生成测试STUB--此种方法更快捷.如果用.NET开发WS客户端,就是用的这种方式-- 客户端调用web service方法首先要使用cxf的wsdl2java命令工具生成服务代理类,如:wsdl2java -p com.charles.client http://localhost:8080/queryUser?wsdl具体命令格式可使用wsd

记录:Web无引用无配置方式动态调用WCF服务

这几年一直用WebApi较多,最近项目中有个需求比较适合使用WCF,以前也用过JQuery直接调用Wcf的,但是说实话真的忘了… 所以这次解决完还是花几分钟记录一下 WCF服务端:宿主在现有Win服务中,在服务启动时添加代码 ,服务代码就不用写了,接口和实现按照契约实现即可 private ServiceHost serviceHost = null; //服务宿主 //启动WCF服务 if (serviceHost != null) { serviceHost.Close(); } servi

C# 调用WebService的3种方式 :直接调用、根据wsdl生成webservice的.cs文件及生成dll C#调用、动态调用

1.直接调用 已知webservice路径,则可以直接 添加服务引用--高级--添加web引用 直接输入webservice URL.这个比较常见也很简单 即有完整的webservice文件目录如下图所示, 也可以在本地IIS根据webservice文件目录新发布一个webservice,然后程序动态调用,修改Url public new string Url { set; get; } 2.根据wsdl文件生成webservice 的.cs文件 及 生成dll C#调用   有时没有这么多文件

C# 调用webservice 几种办法(转载)

原文地址: http://www.cnblogs.com/eagle1986/archive/2012/09/03/2669699.html //================================================================================================= 动态调用示例: 方法一: 看到很多动态调用WebService都只是动态调用地址而已,下面发一个不光是根据地址调用,方法名也可以自己指定的,主要原理是根据指定

【Java EE 学习第80天】【调用WebService服务的四种方式】

不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jdk命令wsimport生成调用源代码 package com.kdyzm.ws; import javax.jws.WebService; import javax.xml.ws.Endpoint; @WebService public class MyWsServer { public Strin

Linux下gcc编译生成动态链接库*.so文件并调用它 是转载的

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助.1.动态库的编译 下面通过一个例子来介绍如何生成一个动态库.这里有一个头文件:so_test.h,三个.c文件:test_a.c.test_b.c.test_c.c,我们将这几个文件编译成一个动态库:libtest.so. //so_test.h:#include "stdio.h"