posts - 54, comments - 282, trackbacks - 22, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

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


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




 

Feedback

#1楼    回复  引用  查看    

2006-05-30 10:07 by Stephen Leung      
基于dynamic webservice invoke虽然看上去灵活, 但是这样完全摈弃了.net提供的便利, 你用vs.net引用webservice会生成一个webservice agent class, 你如果希望动态引用, 如果接口不变的情况下只要在调用方法前设置Url属性就可以了。
for example
uddi.mywebservice webservice = new uddi.mywebservice();
webservice.url = "http://www.xxx.com/xxx.asmx";
webservice.invokemethid();

#2楼 [楼主]   回复  引用  查看    

2006-05-30 10:25 by 自適應軟件......      
能問問webservice.invokemethid()??怎麼來的?還是要反射method嗎?

#3楼    回复  引用  查看    

2006-05-30 11:20 by 沧海月明      
如果仅仅是主机的不确实,应该使用tephen Leung 所说的方法。

#4楼    回复  引用  查看    

2006-05-30 11:21 by 沧海月明      
不好意思,打错字了。是“不确定”

#5楼    回复  引用    

2006-11-03 19:12 by 郑 [未注册用户]
第一个程序能不能给一个调用的实例

#6楼    回复  引用  查看    

2007-09-01 23:51 by 晓风残月      
可以考虑设计一个继承自 VS 自动生成的代理类,提供可接收 WS URL 的构造器

#7楼    回复  引用  查看    

2008-01-22 10:38 by RainWaterLily      
不错,学习中。。。。。。

#8楼    回复  引用    

2008-11-30 14:18 by eeeeeeeee [未注册用户]
不能调用用实体类作参数的WebServrice??

发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接: