代码改变世界

WinForm中動態調用Webservice的問題

2009-07-08 17:37  博弈IT  阅读(868)  评论(5编辑  收藏  举报

转载:http://www.cnblogs.com/robin0925/archive/2006/05/30/412622.html

    今天調適一個webservice,發現我的WinForm一直都在調用局域網的Webservice,突然想到,要是我的WinForm程序,想要運行在不同網斷,那應該如何配置我的webservice?方案一:1.用一個公用的Webservice.就是把Webservice發布到Internet上,然後,WinForm調用Inernet上的Webservice.2. 在每個局域網都建立Webservice,動態的配置Webservice.  每個Webservice引用后,都會生成一個Reference.cs,然後,在Reference.cs裡面,更改Url或者讀取事先寫 在.config文件的Url,編譯成各個局域網的運行程序.3.建立WebService虚拟代理,使用xml登记WebService的引用地址。实现动态引用WebService.!

using System;
using System.Reflection ;
using System.Web .Services .Description ;
using Microsoft.CSharp;
using System.CodeDom ;
using System.CodeDom.Compiler ;
using  System.IO ;
using  System.Text ;
using System.Xml ;
using System.Net ;
using WebServiceProxy;

namespace WebServiceProxy
{
    
public class WebServiceProxy
    
{
        
private Assembly _ass = null;               
        
private string _protocolName = "Soap";      
        
private string _srcWSProxy = string.Empty;  
        
public Assembly Assembly getreturn _ass; } }

        
public string ProtocolName 
        
getreturn _protocolName; } set {_protocolName = value; } } 

        
public string SrcWSProxy getreturn _srcWSProxy; } } 

        
public WebServiceProxy ()
        
{
        }


        
public WebServiceProxy (string wsdlSourceName)
        
{
            AssemblyFromWsdl(GetWsdl(wsdlSourceName));
        }
 
        
public string WsdlFromUrl(string url)
        
{
            WebRequest req 
= WebRequest.Create(url);
            WebResponse result 
= req.GetResponse();
            Stream ReceiveStream 
= result.GetResponseStream();
            Encoding encode 
= System.Text.Encoding.GetEncoding("utf-8");
            StreamReader sr 
= new StreamReader( ReceiveStream, encode );
            
string strWsdl = sr.ReadToEnd();
            
return strWsdl;
        }

        
public string GetWsdl(string source) 
        
{
            
if(source.StartsWith("<?xml version"== true)
            
{
                
return source;              
            }

            
else
                
if(source.StartsWith("http://"== true)
            
{
                
return WsdlFromUrl(source);   
            }

            
return WsdlFromFile(source);   
        }


        
public string WsdlFromFile(string fileFullPathName)
        
{
            FileInfo fi 
= new FileInfo(fileFullPathName);
            
if(fi.Extension == "wsdl")
            
{
                FileStream fs 
= new FileStream(fileFullPathName, FileMode.Open,FileAccess.Read);
                StreamReader sr 
= new StreamReader(fs);
                
char[] buffer = new char[(int)fs.Length];
                sr.ReadBlock(buffer, 
0, (int)fs.Length);
                
return new string(buffer);
            }

            
throw new Exception("This is no a wsdl file");
        }

        
public Assembly AssemblyFromWsdl(string strWsdl)
        
{
            StringReader  wsdlStringReader 
= new StringReader(strWsdl);
            XmlTextReader tr 
= new XmlTextReader(wsdlStringReader);
            ServiceDescription sd 
= ServiceDescription.Read(tr);
            tr.Close();

            
// WSDL service description importer 
            CodeNamespace cns = new CodeNamespace("WebServiceProxy.WebServiceAccessor");
            ServiceDescriptionImporter sdi 
= new ServiceDescriptionImporter();
            sdi.AddServiceDescription(sd, 
nullnull);
            sdi.ProtocolName 
= _protocolName;
            sdi.Import(cns, 
null);

            
// source code generation
            CSharpCodeProvider cscp = new CSharpCodeProvider();
            ICodeGenerator icg 
= cscp.CreateGenerator();
            StringBuilder srcStringBuilder 
= new StringBuilder();
            StringWriter sw 
= new StringWriter(srcStringBuilder);
            icg.GenerateCodeFromNamespace(cns, sw, 
null);
            _srcWSProxy 
= srcStringBuilder.ToString();
            sw.Close(); 

            
// assembly compilation.
            CompilerParameters cp = new CompilerParameters();
            cp.ReferencedAssemblies.Add(
"System.dll");
            cp.ReferencedAssemblies.Add(
"System.Xml.dll");
            cp.ReferencedAssemblies.Add(
"System.Web.Services.dll");
            cp.GenerateExecutable 
= false;
            cp.GenerateInMemory 
= true
            cp.IncludeDebugInformation 
= false
            ICodeCompiler icc 
= cscp.CreateCompiler();
            CompilerResults cr 
= icc.CompileAssemblyFromSource(cp, _srcWSProxy);
            
if(cr.Errors.Count > 0)
                
throw new Exception(string.Format("Build failed: {0} errors",cr.Errors.Count)); 
            
return _ass = cr.CompiledAssembly;
        }

        
public object CreateInstance(string objTypeName) 
        
{
            Type t 
= _ass.GetType("WebServiceProxy.WebServiceAccessor" + "." + objTypeName);
            
return Activator.CreateInstance(t);
        }

        
public object Invoke(object obj, string methodName, params object[] args)
        
{
            MethodInfo mi 
= obj.GetType().GetMethod(methodName);
            
return mi.Invoke(obj, args);
        }

    }

}


4.動態調用webservice       (Copy from http://doc.readmen.com/1/133950.shtml)

/// <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> 

private object InvokeWebservice(string url, string @namespace, string 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)); 
}
 
}