动态创建webservice的方法

做现在的引擎,需要支持COM+/.NET/WebService/Application,WebService的还没有搞定。需求很简单,提供一个WebService的连接,提供一堆参数,然后引擎对它实例化、运行之。

代码应该类似于这样:
string assembly = @“c:\temp\salesorder_service.dll“;
string url = “http://www.langchao.com/WebService/SalesOrder/GetOrderCount.asmx”;
Engine.CreateAndRunWebService(assembly,url,new object[]{10,”hello”});

我们都知道,WebService需要add web reference到project中,然后会在“本地”产生一个类型为System.Web.Services.Protocols.SoapHttpClientProtocol的代理类。然后在“本地”使用这个代理类。

那么,我上面engine的代码中,是否需要生成一个proxy?
到google上看看,或者搜艘msdn。结果陆续放在下面。

posted on 2004-08-30 15:06 鞠强 阅读(6059) 评论(14)  编辑 收藏 所属分类: .NET CLR研究

评论

#1楼  2004-08-30 15:32 juqiang      

找到了一个,自己用System.NET搞一下看看先。

Is there an easy way to test invoking SOAP-based Web Services?

A You must issue an HTTP POST request to test a SOAP-based Web Service. The HttpGet protocol makes it easy to do quick browser-based tests, but the only way to test the SOAP protocol is through an explicit SOAP POST. You can either write the code to programmatically issue the request (see System.Net) or you can use a utility that provides the functionality. I've always used a simple JScript® utility called post.js for this kind of testing; it requires MSXML 3.0 and provides the following functionality:

usage: post uri [options]
  -f inputFile
  -s inputString
  -o outputFile
  -h headerName headerValue

Notice that it allows you to specify arbitrary HTTP headers on the command line and you can post either a string or the contents of an entire file. This command line invokes an .asmx endpoint:

C:\temp>post http://localhost/geo/geometryservice.asmx 
       -h Content-Type "text/xml"
       -h SOAPAction "urn:geometry#CalcDistance" 
       -f req.xml

The req.xml file contains the appropriate SOAP request message for the given operation. Note that when you're testing .asmx endpoints, you must supply the correct SOAPAction header along with a Content-Type header of text/xml. You can download post.js with the sample code for this column or from my Web site.
  回复  引用  查看    

#2楼  2004-08-30 18:27 juqiang      

搞定了,呵呵。明天把代码paste上来。需要四个参数:
url/namespace/methodname/arglist

主要思路是先得到wsdl,然后利用CodeDom在内存中搞定一个assembly,然后GetType,Invoke即可。   回复  引用  查看    

#3楼  2004-08-30 20:04 吕震宇      

期待...   回复  引用  查看    

#4楼  2004-08-31 09:29 鞠强      

方法如下,不过,是5个参数,还有一个是ClassName,呵呵
使用该方法前,请先把System.Web.Services进行Add Reference。

        /// <summary>
        
/// 根据指定的信息,调用远程WebService方法
        
/// </summary>
        
/// <param name="url">WebService的http形式的地址</param>
        
/// <param name="namespace">欲调用的WebService的命名空间</param>
        
/// <param name="classname">欲调用的WebService的类名(不包括命名空间前缀)</param>
        
/// <param name="methodname">欲调用的WebService的方法名</param>
        
/// <param name="args">参数列表</param>
        
/// <returns>WebService的执行结果</returns>
        
/// <remarks>
        
/// 如果调用失败,将会抛出Exception。请调用的时候,适当截获异常。
        
/// 异常信息可能会发生在两个地方:
        
/// 1、动态构造WebService的时候,CompileAssembly失败。
        
/// 2、WebService本身执行失败。
        
/// </remarks>
        
/// <example>
        
/// <code>
        
/// object obj = InvokeWebservice("http://localhost/GSP_WorkflowWebservice/common.asmx","Genersoft.Platform.Service.Workflow","Common","GetToolType",new object[]{"1"});
        
/// </code>
        
/// </example>

        public static object InvokeWebservice(string url, string @namespacestring classname, string methodname, object[] args)
        
{        
            
try
            
{
                System.Net.WebClient wc 
= new System.Net.WebClient();
                System.IO.Stream stream 
= wc.OpenRead(url+"?WSDL");
                System.Web.Services.Description.ServiceDescription sd 
= System.Web.Services.Description.ServiceDescription.Read(stream);
                System.Web.Services.Description.ServiceDescriptionImporter sdi 
= new System.Web.Services.Description.ServiceDescriptionImporter();
                sdi.AddServiceDescription(sd,
"","");
                System.CodeDom.CodeNamespace cn 
= new System.CodeDom.CodeNamespace(@namespace);
                System.CodeDom.CodeCompileUnit ccu 
= new System.CodeDom.CodeCompileUnit();
                ccu.Namespaces.Add(cn);
                sdi.Import(cn,ccu);

                Microsoft.CSharp.CSharpCodeProvider csc 
= new Microsoft.CSharp.CSharpCodeProvider();
                System.CodeDom.Compiler.ICodeCompiler icc 
= csc.CreateCompiler();

                System.CodeDom.Compiler.CompilerParameters cplist 
= new System.CodeDom.Compiler.CompilerParameters();
                cplist.GenerateExecutable 
= false;
                cplist.GenerateInMemory 
= true;
                cplist.ReferencedAssemblies.Add(
"System.dll");
                cplist.ReferencedAssemblies.Add(
"System.XML.dll");
                cplist.ReferencedAssemblies.Add(
"System.Web.Services.dll");
                cplist.ReferencedAssemblies.Add(
"System.Data.dll");

                System.CodeDom.Compiler.CompilerResults cr 
= icc.CompileAssemblyFromDom(cplist, ccu);
                
if(true == cr.Errors.HasErrors)
                
{
                    System.Text.StringBuilder sb 
= new System.Text.StringBuilder();
                    
foreach(System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                    
{
                        sb.Append(ce.ToString());
                        sb.Append(System.Environment.NewLine);
                    }

                    
throw new Exception(sb.ToString());
                }

                System.Reflection.Assembly assembly 
= cr.CompiledAssembly;
                Type t 
= assembly.GetType(@namespace+"."+classname,true,true);
                
object obj = Activator.CreateInstance(t);
                System.Reflection.MethodInfo mi 
= t.GetMethod(methodname);
                
return mi.Invoke(obj,args);
            }

            
catch(Exception ex)
            
{
                
throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace));
            }

        }

  回复  引用  查看    

#5楼  2004-08-31 09:30 juqiang      

源代码是VB.NET的,一个老外写的,不过他的代码在UI中会发生异常。不知道他最后解决了没有?

网页没有保留,所以抱歉不能把原贴放上来了。   回复  引用  查看    

#6楼  2004-09-01 15:34 juqiang      

优化问题,昨天简单的考虑了一下。
按照上面的代码,我想主要是在Compile的时候着手。

昨天尝试了一下,可以分析wsdl文件,和本地的进行比较。如果文件相同,那么就不对dll动态进行编译,codedom也不做。如果不相同,那么比较某个目录下的dll,如果也相同,那么codedom也不做。否则,就做一次。

这种方式,据我的了解,和asp.net的dll缓存是一致的。但是asp.net是每当aspnet_wp重启之后,原来的缓存就失效了。我这种方式,可以保证只要webservice接口不变,那么缓存的dll proxy也不变。

不过,实现的时候,有点问题。呵呵   回复  引用  查看    

#7楼  2004-09-16 15:32 jqw [未注册用户]

如果只是简单的动态调用WebService的话,不用这么复杂,

把生成的代理类 修改一下就可以了!   回复  引用    

#8楼  2004-10-20 17:52 hefq [未注册用户]

return mi.Invoke(obj,args)

报错,未将对象引用设置到对象的实例   回复  引用    

#9楼  2005-02-06 10:38 5 [未注册用户]

ThreadPool   回复  引用    

#10楼  2005-07-19 14:05 小庄 [未注册用户]

上面的代码使用的时候出现错误,请问怎么解决?
未将对象引用设置到对象的实例:
catch(Exception ex)
行 110: {
行 111: throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace));
行 112: }
行 113: }


源文件: c:\inetpub\wwwroot\webapplication2\webform1.aspx.cs 行: 111
  回复  引用    

#11楼  2005-08-05 13:59 Yan [未注册用户]

//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.1.4322.2300
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

//
// 此源代码是由 Microsoft.VSDesigner 1.1.4322.2300 版自动生成。

//
namespace WebDisp.WebEml {
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;


/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="SvcSoap", Namespace="http://tempuri.org/")]
public class Svc : System.Web.Services.Protocols.SoapHttpClientProtocol {

public Svc(string url) {
//this.Url = "http://192.168.0.3/WebService/Svc.asmx";
this.Url = url;//重写客户端代理类的构造方法
}

  回复  引用    

#12楼 [楼主] 2005-08-09 15:32 鞠强      

楼上的,你的代码只是如何修改proxy类的hostname,我的代码的意思是,传递你一个webservice的url,如何来dynamic的execute。因为你的方法上,该webservice的proxy是静态的,而我那种方式,是动态的。   回复  引用  查看    

#13楼  2005-09-08 17:14 sun [未注册用户]

这种方法要求必须知道web Service的命名空间和类名吧,那我拿java写的web service还能用么?我试了试,一旦命名空间和类名不对就会出异常啊。   回复  引用    

#14楼  2005-09-22 10:19 Harrison      

不知楼主看到的是不是这个,其实很多东西都可以从wsdl得到
http://harrisonyu.cnblogs.com/Files/HarrisonYu/DynWSLib.rar   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接:
 







<2004年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

公告

web counter
访问量是此计数器+213636(粗略值) 大家不要给我私人留言了,经常忘记看。有事情往这里发邮件吧:juqiang@live.com,多谢!!!

与我联系

搜索

 

常用链接

留言簿(97)

我参加的小组

我参与的团队

我的标签

随笔分类

随笔档案

相册

积分与排名

最新评论

阅读排行榜

评论排行榜