天天看点

C# 动态调用各种网络环境下的webservice

我试了调用天气预报的接口(外网),和我本机的iis上发布的接口,还有公司服务器上(内网)的接口,都可以实现。

话不多说,直接上代码。可以直接用:

public class Webservice
    {
        /// <summary>
        /// 实例化WebServices
        /// </summary>
        /// <param name="url">WebServices地址</param>
        /// <param name="methodname">调用的方法</param>
        /// <param name="args">把webservices里需要的参数按顺序放到这个object[]里</param>
        public static object InvokeWebService(string url, string methodname, object[] args)
        {
            try
            {
                WebClient client = new WebClient();
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Stream stream = client.OpenRead(url);
                ServiceDescription description = ServiceDescription.Read(stream);
                string classname = description.Services[0].Name;//类名
                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 = "gsh";//这个命名空间可以自己取
                
                CodeCompileUnit unit = new CodeCompileUnit();
                unit.Namespaces.Add(nmspace);
                checkForImports(url, importer);//不走这个方法局域网内的webservice调用会异常
                ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");//指定编程语言
                
                CompilerParameters parameter = new CompilerParameters();
                parameter.GenerateExecutable = false;
                parameter.OutputAssembly = "MyWebservice.dll";//输出程序集的名称...在bin\Debug下
                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)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (CompilerError ce in result.Errors)
                    {
                        sb.Append(ce.ToString());
                        sb.Append(Environment.NewLine);
                    }
                    throw new Exception(sb.ToString());
                }
                //生成代理实例,并调用方法
                Assembly asm = Assembly.LoadFrom("MyWebservice.dll");//加载前面生成的程序集
                Type t = asm.GetType(nmspace.Name+"."+classname);//前面的命名空间.类名,类必须是webservice中定义的
                object o = Activator.CreateInstance(t);
                MethodInfo method = t.GetMethod(methodname);
                object item = method.Invoke(o, args);
                return item;
            }
            catch
            {
                return null;
            }
        }
        private static void checkForImports(string baseWsdlUrl, ServiceDescriptionImporter importer)
        {
            DiscoveryClientProtocol dcp = new DiscoveryClientProtocol();
            dcp.DiscoverAny(baseWsdlUrl);
            dcp.ResolveAll();
            foreach (object osd in dcp.Documents.Values)
            {
                if (osd is ServiceDescription) importer.AddServiceDescription((ServiceDescription)osd, null, null); ;
                if (osd is XmlSchema) importer.Schemas.Add((XmlSchema)osd);
            }
        }
        private static  bool CheckValidationResult(object sender, X509Certificate certificate,X509Chain chain, SslPolicyErrors errors)
        {  
            // 总是接受  
            return true;
        }
    }
           

页面调用方法:按钮控件事件里写如下:

string method = "Add";
            string ip = "http://192.168.**.***:8090/WebService1.asmx?wsdl";
            object[] arg = new object[] { Convert.ToInt32(txtNumb1.Text.Trim()), Convert.ToInt32(txtNumb2.Text.Trim()) };
            object res = Webservice.InvokeWebService(ipadd, method, arg);
            txtres.Text = res.ToString();
           

测试结果图:

C# 动态调用各种网络环境下的webservice

网上有很多例子,但是都不能符合我的要求,所以是整合了一下,供大家参考。。