C# winform 中動態調用Webservice的問題

今天調適一個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)); 
}
 
}
 



兄弟們,還有其他的解決方案嗎?一起討論!

posted @ 2012-09-21 17:28  AIの海雅  阅读(744)  评论(0编辑  收藏  举报