WebService-问题

Posted 随缘梦中人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebService-问题相关的知识,希望对你有一定的参考价值。

1、引用问题

  在用C#对接webservice的时候,常用的方法是下载vs中引用webservice的地址。然后,new对应的client就可以使用了。但在,实际应用中往往会遇到webservice访问受限,比如政府单位中内网限制。因此,在开发过程中就会遇到引用问题。

  解决办法:

      1)使用vs自带的命令生成一个webservice类,是由webservice开发方生成的。推荐,最简单的方式

      2)使用Http请求,去拼接要发送的请求数据xml文档。

      3)使用反射,反射出webservice类,得到要请求的方法,再去调用。不推荐,如果是服务端有SoapHeader验证,该方法不适用。

  下面对这几种方法进行介绍。

public class WebService1 : System.Web.Services.WebService
    {
        public MyHeader myHeader = new MyHeader();
        [SoapHeader("myHeader")]
        [WebMethod]
        public string HelloWorld(string name, string pwd)
        {
            if (myHeader.key != "12")
            {
                return JsonConvert.SerializeObject(new { MsgId = 1, Msg = "用户验证成功" });
            }
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
            {
                return JsonConvert.SerializeObject(new { MsgId = 0, Msg = "用户名或密码不能为空" });
            }
            if (name.Equals("admin") && pwd.Equals("admin"))
            {
                return JsonConvert.SerializeObject(new { UserName = name, XueYuan = "外语学院", ZhuanYe = "英语专业", Email = "123456@qq.com", Phone = "12345678901", MsgId = 1, Msg = "获取成功" });

            }
            return JsonConvert.SerializeObject(new { MsgId = 0, Msg = "用户名或密码错误" });
        }
    }

    public class MyHeader : SoapHeader
    {

        public string key { get; set; }
        public string token { get; set; }
    }

2、服务端生成类方式

  命令:wsdl.exe /out:D:/Proxy.cs /order http://localhost:2178/Services.asmx?wsdl

  其他语言编写的webservice,有的可能没有.asmx,在地址后面加上?wsdl就可以生成了。

  把这个命令复制到vs的自带命令行中生成一个类文件。把这个类文件,发给要调用webservice方。调用方,引用Proxy.cs文件,接着就可以使用了。代码如下:

       WebService1 webService1 = new WebService1();
            MyHeader myHeader = new MyHeader();
            myHeader.key = "12";
            webService1.MyHeaderValue = myHeader;
            Response.Write(webService1.HelloWorld("ad","ad"));

3、Http请求方式

  拼接要发送的数据。如下是有SoapHeader和无SoapHeader的数据模板。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:HelloWorld>
         <!--Optional:-->
         <tem:name>?</tem:name>
         <!--Optional:-->
         <tem:pwd>?</tem:pwd>
      </tem:HelloWorld>
   </soapenv:Body>
</soapenv:Envelope>


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header>
      <tem:MySoapHeader>
         <!--Optional:-->
         <tem:IN_WSKEY>?</tem:IN_WSKEY>
         <!--Optional:-->
         <tem:IN_TOKEN>?</tem:IN_TOKEN>
      </tem:MySoapHeader>
   </soapenv:Header>
   <soapenv:Body>
      <tem:GetReaderInfo>
         <!--Optional:-->
         <tem:certNo>?</tem:certNo>
         <!--Optional:-->
         <tem:password>?</tem:password>
         <tem:certType>?</tem:certType>
      </tem:GetReaderInfo>
   </soapenv:Body>
</soapenv:Envelope>

  把占位符替换为对应的数据就可以了。HttpHelper是发送Http请求的工具类。不同的开发语言开发的webservice,对应的要发送的数据可能不太一样,原理是一样的就是发送http的请求。具体数据,可以通过Soap UI接口调试工具查看。

StringBuilder param = new StringBuilder();
            param.Append("<soapenv:Envelope xmlns:soapenv=\\"http://schemas.xmlsoap.org/soap/envelope/\\" xmlns:tem=\\"http://tempuri.org/\\">");
            param.Append(" <soapenv:Header><tem:Muse65WSSoapHeader><tem:IN_WSKEY>HxxxxG</tem:IN_WSKEY><tem:IN_TOKEN>6A1FCE13565B7BC4</tem:IN_TOKEN></tem:Muse65WSSoapHeader></soapenv:Header>");
            param.Append(
                "<soapenv:Body><tem:GetReaderInfo><tem:certNo>5807151617</tem:certNo><tem:password>151617</tem:password><tem:certType>2</tem:certType></tem:GetReaderInfo></soapenv:Body>");
            param.Append("</soapenv:Envelope>");
            HttpHelper httpHelper = new HttpHelper();
            httpHelper.SetContentType("text/xml;charset=UTF-8");
            httpHelper.SetEncoding(Encoding.UTF8);
            string str = httpHelper.HttpPost(url, param.ToString());
            string res = "";
            using (StringReader stringReader = new StringReader(str.Trim()))
            {
                using (XmlReader xmlReader = XmlReader.Create(stringReader))
                {
                    while (xmlReader.Read())
                    {
                        if (xmlReader.NodeType == XmlNodeType.Element)
                        {
                            switch (xmlReader.Name.Trim())
                            {
                                case "GetReaderInfoResult":
                                    if (xmlReader.Read())
                                    {
                                        res = xmlReader.Value.Trim();
                                    }
                                    break;
                                
                                default:
                                    break;
                            }

                        }
                    }
                }
            }

4、使用反射

  不推荐,并且在使用了SoapHeader的webservice中,这种没找到解决办法,不知道怎么传SoapHeader的值。

  具体参考:http://www.cnblogs.com/langhua/p/3344784.html

/// < summary>
        /// 动态调用web服务
        /// < /summary>
        /// < param name="url">WSDL服务地址< /param>
        /// < param name="classname">类名< /param>
        /// < param name="methodname">方法名< /param> 
        /// < param name="args">参数< /param> 
        /// < returns>< /returns> 
        public object InvokeWebService(string url, string classname, string methodname, object[] args)
        {
            string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
            if ((classname == null) || (classname == ""))
            {
                classname = CommonServiceHelper.GetWsClassName(url);
            }
            try
            {
                //获取WSDL 
                WebClient wc = new WebClient();
                Stream stream = wc.OpenRead(url + "?WSDL");
                ServiceDescription sd = ServiceDescription.Read(stream);
                ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
                sdi.AddServiceDescription(sd, "", "");
                CodeNamespace cn = new CodeNamespace(@namespace);
                //生成客户端代理类代码
                CodeCompileUnit ccu = new CodeCompileUnit();
                ccu.Namespaces.Add(cn);
                sdi.Import(cn, ccu);
                CSharpCodeProvider icc = new CSharpCodeProvider();
                //设定编译参数
                CompilerParameters cplist = new 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");
                //编译代理类 
                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);
                /*        
                 * PropertyInfo propertyInfo = type.GetProperty(propertyname);     
                 * return propertyInfo.GetValue(obj, null);      
                 * */
            }
            catch (Exception ex)
            {
                throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
            }
        }
        private static string GetWsClassName(string wsUrl)
        {
            string[] parts = wsUrl.Split(\'/\');
            string[] pps = parts[parts.Length - 1].Split(\'.\');
            return pps[0];
        }

 

以上是关于WebService-问题的主要内容,如果未能解决你的问题,请参考以下文章

C#动态调用webService出现 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。

Java RMI地址解析问题

当我们在webservice.asmx.cs中编写所有代码时,webservice.asmx有啥用?

java客户端调用webservice 超时问题

从 mfc 应用程序中点击 webservice 并希望从 webservice 登录方法读取用户代码返回

通过JDK自带工具生成WebService客户端代码