http://xxx.net/api.php?source=test&user=6666&pass=1234&agent_user=1000&function=version
拿到这么一个url,被骗说这是一个webservice,要我访问这个ws并取返回值。
因为是外部url,开发环境无法访问,只有部署的环境才能访问,所以调用ws不能直接添加web引用。
偶焦头烂额的在网上找了半天如何不使用添加webreference的方法调用这个ws,我还去博问... - =
可是找到快吐血试验代码的时候,偶才忽然意识到...这是毛webservice啊!连个方法名都没有!这不就是一普通url的网页么..... orz
于是转头调查访问web url的返回值...... (┬_┬)
最后解决方案:
using System.IO;
String url = " http://xxxx.net/api.php?source=test&user=6666&pass=1234&agent_user=1000&function=version " ;
HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();
Stream stream = webreponse.GetResponseStream();
byte [] rsByte = new Byte[webreponse.ContentLength]; // save data in the stream
try
{
stream.Read(rsByte, 0 , ( int )webreponse.ContentLength);
return System.Text.Encoding.UTF8.GetString(rsByte, 0 , rsByte.Length).ToString();
}
catch (Exception exp)
{
return exp.ToString();
}
用HttpWebRequest/HttpWebResponse 顺利得到... 感谢下面两篇博文~ T T
http://blog.csdn.net/gaoyunpeng/archive/2007/02/28/1517151.aspx
http://www.cnblogs.com/fgq841103/articles/1280664.html
以下资料都是网上搜到的,未经尝试不晓得具体情况...................................... = =
本来想尝试一下这个,结果没用上~ 有时间试试....
【转】不添加web引用,动态调用webservice的方法(.net)
我做了这样一个项目,一个解决方案里有三个网站,其中有一个管理站、一个国外站模板、一个国内站模板,另外还有数据库访问项目和缓存管理项目。当管 理站点击缓存管理的时候,其他两个站的缓存必须更新。我是用webservice做的,但这样做有个问题。一旦项目上传,国外站和国内站都可以传N个,这 样,就无法提前获知到底要传几个站,也就是说,无法通过事先添加web引用来调用webservice了。因此只能动态调用。我是这么做的:
1、在两个模板站分别建一个webservice,我的是WebServiceUpdateCache.asmx,需要调用的方法名为UpdateCache(),返回值为string类型,用来返回success或者failed。
2、在管理站里添加一个类Service1.cs,代码如下:
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
namespace WebService
{
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute( " code " )]
[System.Web.Services.WebServiceBindingAttribute(Name = " Service1Soap " , Namespace = " http://tempuri.org/ " )]
public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol
{
/// <remarks/>
public Service1( string url)
{
this .Url = url;
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute( " http://tempuri.org/UpdateCache " , RequestNamespace = " http://tempuri.org/ " , ResponseNamespace = " http://tempuri.org/ " , Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string UpdateCache()
{
object [] results = this .Invoke( " UpdateCache " , new object [ 0 ]);
return (( string )(results[ 0 ]));
}
}
}
3、调用的时候实例化这个类,而后调用方法。我的设计是把各个站点的域名存入Dropdownlist里,此Dropdownlist的Id为“ddlUrl”,则有:
string res = ss.UpdateCache();
此res就是webservice输出值。
测试的时候,把中间的域名换成localhost什么的就OK了。
此方法我测试过,一定能通过,如果不能……你见鬼了。其实我一开始也见鬼了,明明调适都通过了,结果res等于null,我的领导一口咬定我没走到底,可这种错误我怎么可能犯
http://hi.baidu.com/soviet1991/blog/item/b9f428184c74080e34fa415e.html
动态调用WebService方法
好像很多人做WebService的时候都是直接添加引用的方式,然后调用服务端的方法.这样就个问题,就是每次我服务端添加了方法或者修改了方法 后都要更新Web引用,这样比较麻烦.下面给一个不用添加引用的方式调用服务端的方法.只是一个简单的测试,不是很规范,用得着的人可以自己封装一下,然 后直接传服务端的方法名进去,Type.GetMethod获取方法,然后method.Invoke返回结果
高手些多多包函,主要是给用得着的人参考一下,互相学习.代码主要是用了 System.Web.Services.Description里的东西
新建一个WebService项目,添加以下代码:
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
namespace TestWebService
{
/// <summary>
/// Service1 的摘要说明
/// </summary>
[WebService(Namespace = " http://tempuri.org/ " ,Description = " 我的Web服务 " )]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem( false )]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class TestWebService : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return " 测试Hello World " ;
}
[WebMethod]
public string Test()
{
return " 测试Test " ;
}
[WebMethod(CacheDuration = 60 ,Description = " 测试 " )]
public List < String > GetPersons()
{
List < String > list = new List < string > ();
list.Add( " 测试一 " );
list.Add( " 测试二 " );
list.Add( " 测试三 " );
return list;
}
}
}
下面是客户端:
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Web;
using System.Net;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Text;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
WebClient client = new WebClient();
String url = " http://localhost:3182/Service1.asmx?WSDL " ; // 这个地址可以写在Config文件里面,这里取出来就行了.在原地址后面加上: ?WSDL
Stream stream = client.OpenRead(url);
ServiceDescription description = ServiceDescription.Read(stream);
ServiceDescriptionImporter importer = new ServiceDescriptionImporter(); // 创建客户端代理代理类。
importer.ProtocolName = " Soap " ; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null , null ); // 添加WSDL文档。
CodeNamespace nmspace = new CodeNamespace(); // 命名空间
nmspace.Name = " TestWebService " ;
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider( " CSharp " );
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false ;
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);
if (result.Errors.HasErrors)
{
// 显示编译错误信息
}
Assembly asm = Assembly.LoadFrom( " MyTest.dll " ); // 加载前面生成的程序集
Type t = asm.GetType( " TestWebService.TestWebService " );
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod( " GetPersons " ); // GetPersons是服务端的方法名称,你想调用服务端的什么方法都可以在这里改,最好封装一下
String[] item = (String[])method.Invoke(o, null );
// 注:method.Invoke(o, null)返回的是一个Object,如果你服务端返回的是DataSet,这里也是用(DataSet)method.Invoke(o, null)转一下就行了
foreach ( string str in item)
Console.WriteLine(str);
// 上面是根据WebService地址,模似生成一个代理类,如果你想看看生成的代码文件是什么样子,可以用以下代码保存下来,默认是保存在bin目录下面
TextWriter writer = File.CreateText( " MyTest.cs " );
provider.GenerateCodeFromCompileUnit(unit, writer, null );
writer.Flush();
writer.Close();
}
}
}
http://zhidao.123doing.com/55419.html
动态调用 WebService
多数时候我们通过 "添加 Web 引用" 创建客户端代理类的方式调用WebService,但在某些情况下我们可能需要在程序运行期间动态调用一个未知的服务。在 .NET Framework 的 System.Web.Services.Description 命名空间中有我们需要的东西。
具体步骤:
1. 从目标 URL 下载 WSDL 数据。
2. 使用 ServiceDescription 创建和格式化 WSDL 文档文件。
3. 使用 ServiceDescriptionImporter 创建客户端代理类。
4. 使用 CodeDom 动态创建客户端代理类程序集。
5. 利用反射调用相关 WebService 方法。
OK,看看具体的例子。
我们要调用的目标 WebService,其 URL 是 http://localhost:60436/Learn.WEB/WebService.asmx
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
[WebMethod]
public string HelloWorld()
{
return " Hello Wolrd! " ;
}
}
1. 动态调用 WebService
客户端动态调用代码
using System.Net;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream = web.OpenRead( " http://localhost:60436/Learn.WEB/WebService.asmx?WSDL " );
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = " Soap " ; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null , null ); // 添加 WSDL 文档。
// 4. 使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider( " CSharp " );
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false ;
parameter.GenerateInMemory = true ;
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);
// 5. 使用 Reflection 调用 WebService。
if ( ! result.Errors.HasErrors)
{
Assembly asm = result.CompiledAssembly;
Type t = asm.GetType( " WebService " ); // 如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod( " HelloWorld " );
Console.WriteLine(method.Invoke(o, null ));
}
2. 生成客户端代理程序集文件
上 面的代码通过在内存中创建动态程序集的方式完成了动态调用过程。如果我们希望将客户端代理类生成程序集文件保存到硬盘,则可以进行如下修改。生成程序集文 件后,我们可以通过 Assembly.LoadFrom() 载入并进行反射调用。对于需要多次调用的系统,要比每次生成动态程序集效率高出很多。
using System.Net;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream = web.OpenRead( " http://localhost:60436/Learn.WEB/WebService.asmx?WSDL " );
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = " Soap " ; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null , null ); // 添加 WSDL 文档。
// 4. 使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider( " CSharp " );
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false ;
parameter.OutputAssembly = " test.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);
if (result.Errors.HasErrors)
{
// 显示编译错误信息
}
调用程序集文件演示
Assembly asm = Assembly.LoadFrom( " test.dll " );
Type t = asm.GetType( " WebService " );
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod( " HelloWorld " );
Console.WriteLine(method.Invoke(o, null ));
3 . 获取客户端代理类源代码
还有一种情形,就是我们需要获得客户端代理类的 C# 源代码。
using System.IO;
using System.Net;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream = web.OpenRead( " http://localhost:60436/Learn.WEB/WebService.asmx?WSDL " );
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = " Soap " ; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null , null ); // 添加 WSDL 文档。
// 4. 使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider( " CSharp " );
// 5. 保存源代码到文件。当然,你也可以直接保存到内存字符串中。
TextWriter writer = File.CreateText( " test.cs " ); // 指定你所需的源代码文件名。
provider.GenerateCodeFromCompileUnit(unit, writer, null );
writer.Flush();
writer.Close();
如果你调用时触发 "WebException: 请求因 HTTP 状态 415 失败: Unsupported Media Type。" 这样的异常,那么恭喜你和我一样郁闷 ,赶紧把服务器端的 WSE 关掉吧。在必须使用 WSE 的情况下,需要对客户端进行调整,至于代码需要你自己去写了。呵呵~~~~
http://www.dezai.cn/Channel/Web/ArticleShow.Aspx?AI=66320 来历不明的文章 = =
[转]关于.NET中动态调用Web Service服务的方法心得
介绍.NET中动态调用Web Service的相关技术文章。在.NET中调用Web Service服务(WSDL)有两种可行的方法:
1、通过Web 服务引用,在本地生成所要调用服务的类;(静态方法)
2、通过给定的WSDL服务地址,动态生成Web Service服务类进行服务调用;(动态方法)
由于1中的方法大部分人都会经常用到,因此暂不讨论。
对于2,实现上较为复杂,主要的过程为:
(1)读取WSDL内容到内存中;
(2)根据WSDL内容,动态生成Web Service服务代码;
(3)使用动态编译技术将生成的Web Service服务代码编译为DLL;
(4)通过反射机制实现动态调用。
_________________________________________________________
有关这类技术请参考如下网站:
1、《动态调用 WebService》
地址: http://www.rainsts.net/article.asp?id=304/
2、《DynWsLib》
地址: http://www.thinktecture.com/Resources/Software/DynWsLib/default.html/
说明:
欧洲一家名位Thinktecture公司发布的开源项目,实现了比较完整的动态调用Web Service的方法,最新版本为1.6,支持.NET 2.0。最可贵的是这是一个完全开源的项目,我们可以下载下来根据实际情况进行一些修改,以适应不同的需求。
3、WSE
地址: http://msdn2.microsoft.com/en-us/webservices/aa740663.aspx/
说明:
微软发布的支持Web Service的工具包。目前最新版本为3.0。
_________________________________________________________
Java 与 .NET的互调用
这是本文重点要讨论的话题。
由于项目需要,我们必须为客户提供一个.NET的动态调用Web Service包,以实现对Oracle的BPEL服务器上发布的Web Service进行动态调用。
在使用动态DynWSLib生成的对象进行调用的时候,发现只能够发送一次SOAP,当第二次发送之后,.NET程序会抛出链接已被断开的异常。
这样的错误十分诡异,在网上搜索了之后,发现问题在于BPEL服务器与Microsoft的IIS之间是有区别的,看来微软还是很喜欢搞垄断。
下面说说个人分析的结论,共大家参考:
问 题的出现可能和微软的地层支持有关,本人猜测,微软生成的Web Service对象在发送SOAP请求时,建立的HTTP链接在请求发送完成之后,会长时间保持链接状态(即链接没有立即断开),而对于Oracle的 Web服务器,当相应SOAP请求之后,会主动断开HTTP链接,这也许就是为什么用微软的东西发送SOAP消息给Oracle服务器,第一次能够成功, 第二次就会报链接已断开,发送失败的错误。后面的解决方案中也部分支持了我的这个观点。
________________________________________________________
解决方案:
WSE + HTTP
1、使用WSE构造SOAP请求消息;
2、使用HTTP发送SOAP消息。
下面给出部分参考代码:
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace My.Web.WebService
{
internal class SoapHttpClient
{
private string url = null ;
public SoapHttpClient( string url)
{
this .url = url;
}
public string RequestResponse( string methodName, string envelope)
{
// 用于支持SSL
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(OnCheckRemoteCallback);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = CredentialCache.DefaultCredentials;
// 必须设置该值为flase,否则出错
request.KeepAlive = false ;
request.Method = " POST " ;
request.ContentType = " text/xml " ;
request.Headers.Add( " SOAPAction " , methodName);
UTF8Encoding encoding = new UTF8Encoding();
byte [] bodyBytes = encoding.GetBytes(envelope);
request.ContentLength = bodyBytes.Length;
using (Stream serviceRequestBodyStream = request.GetRequestStream())
{
serviceRequestBodyStream.Write(bodyBytes, 0 , bodyBytes.Length);
serviceRequestBodyStream.Close();
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8))
{
string result = reader.ReadToEnd();
return result;
}
}
}
}
/// <summary>
/// Using untrusted SSL certificates
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
private static bool OnCheckRemoteCallback( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true ;
}
}
}
________________________________________________________
最后讨论一下有关DynWSLib动态调用的问题。
使用DynWSLib在调用Web Service服务的时候,需要对传入的参数进行适当的处理。
1、获取所调用的方法的参数类型。
/// 获取参数类型。该方法只获取第一个参数的类型。
/// </summary>
/// <returns></returns>
private Type GetParameterType()
{
Type t = wsp.Instance.GetType();
MethodInfo methodInfo = t.GetMethod(wsp.MethodName);
// 获得方法的参数类型
ParameterInfo[] param = methodInfo.GetParameters();
if (param.Length < 1 )
return null ;
// 实例化参数类型
Type objType = param[ 0 ].ParameterType;
return objType;
}
2、添加参数到调用方法中。
// For SOAP Body Parameters.
private IDictionary paramsTable = new Hashtable();
public void AddParameter( string name, object value)
{
Type objType = GetParameterType();
// 处理字符串类型
if (objType == "" .GetType())
{
wsp.AddParameter(value);
}
else // 处理对象类型
{
object obj = Activator.CreateInstance(objType);
FieldInfo field = obj.GetType().GetField(name);
Type filedType = field.FieldType;
// 对基本类型和泛型区别处理
object valueObj = null ;
if (filedType.IsGenericType)
{
Type[] typeParameters = filedType.GetGenericArguments();
Type valueType = Type.GetType(typeParameters[ 0 ].FullName);
valueObj = Convert.ChangeType(value, valueType);
}
else
{
valueObj = Convert.ChangeType(value, filedType);
}
field.SetValue(obj, valueObj);
wsp.AddParameter(obj);
}
}
通过HttpWebRequest在后台对WebService进行调用
http://www.cnblogs.com/macroxu-1982/archive/2009/12/23/1630415.html
如何动态调用WebService?
http://www.chenjiliang.com/Article/View.aspx?ArticleID=3277