这是一个关于:C#调用axis框架下的webservice的问题
    本人现在的项目遇到一个问题。服务端是axis框架用java写的webservice,我的客户端是用.net去调用。刚开始直接通过IDE添加web代理,编译调用一切正常。现在服务端增加了一项功能,在发送过去的请求中验证soapheader头信息中用户名、密码是否正确。
    问题:我如何在。net端给服务端添加soapheader头信息呢?因为我不能像我调用.net写的服务端这样UIService ws = new UIService();
CredentialSoapHeader header = new CredentialSoapHeader();
header.UserName = GlobalModel.UserName;
header.SessionID = GlobalModel.SessionID;
ws.CredentialSoapHeaderValue = header;
调用,因为在生成的Reference.cs中没有CredentialSoapHeader这个对象。    于是我自己在本地重新写了一下Reference.cs,这样可以保证我能将soapheader发送过去。修改cs前,对方收到的请求:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:tns="http://10.10.3.71:8081/app/services/UIToolService" 
xmlns:types="http://10.10.3.71:8081/app/services/UIToolService/encodedTypes" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<q1:getUserByName xmlns:q1="http://ws.uiTool.nj.bee.com">
<userName xsi:type="xsd:string">admin</userName>
</q1:getUserByName>
</soap:Body>
</soap:Envelope>修改cs后,对方收到的请求:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<CredentialSoapHeader xmlns="http://10.10.3.71:8081/app/services/UIToolService">
<UserName>admin</UserName>
<SessionID>3cb9438e-2148-4622-88cc-e6da134f2207</SessionID>
</CredentialSoapHeader>
</soap:Header>
<soap:Body>
<getUserByName xmlns="http://ws.uiTool.nj.bee.com">
<userName>admin</userName>
</getUserByName>
</soap:Body>
</soap:Envelope>可以看出修改后header确实增加了信息,可是我调用的getUserByName方法返回值确是null(可以十分肯定对方给我的绝对是个对象,且不为null)这是怎么回事呢?请高手指点如何传递soapheader信息过去。

解决方案 »

  1.   

    你改cs后,命名空间和没改之前不一致。你可以通过服务器端的wsdl来生成代理类
      

  2.   

    参考资料:
    问题:如果用c#调用java 的 webservice 时,发现调用返回值为基本类型(如 xsd:string xsd:int)的服务能过正常返回,而调用返回复杂类型如自定义对象时却返回 null,同时抓包发现服务器段明明已经正常答复soap消息。 就需要考虑命名空间的问题。由于我把用来返回结果的bean 单独放到一个 xxx.xxx.bean 包中,而把webservice 的文件放在 xxx.xxx.service包中,在用wtp生成 webservice 服务时就把它们放到不同的命名空间中去了。解决方案:把用来的bean文件放置到与service同一个package中,这样用wtp lomboz之类工具生成时就直接会在一个命名空间中。--本人备忘最近在一个项目中,就遇到了这个问题,此文对我帮助很大,先谢谢这会兄弟了。另附一小段代码,备忘一下:Java端的webservice中saveUser(JafUser user)方法中的JafUser类代码如下:java 代码
    /**   
     *    
     * @author lixy 2006-12-14 10:16:04   
     *   
     */   
    public class JafUser  implements java.io.Serializable {    
       
       
        // Fields        
       
         private String userId;    
         private String userName;    
         private Integer regionId;    
             
        // Constructors    
       
        /** default constructor */   
        public JafUser() {    
        }    
       
        public Integer getRegionId() {    
            return regionId;    
        }    
       
        public void setRegionId(Integer regionId) {    
            this.regionId = regionId;    
        }    
       
        public String getUserId() {    
            return userId;    
        }    
       
        public void setUserId(String userId) {    
            this.userId = userId;    
        }    
       
        public String getUserName() {    
            return userName;    
        }    
       
        public void setUserName(String userName) {    
            this.userName = userName;    
        }    
       
        public String toString() {    
            StringBuffer sb = new StringBuffer("[ ");    
            sb.append("userId = "+this.userId).append(",");    
            sb.append("userName = "+this.userName).append(",");    
            sb.append("regionId = "+this.regionId).append(" ]");    
            return sb.toString();    
        }    
    }   
    客户端c# 代码:ConsoleApplication1.com.lixy.ws.UserServiceEx manager = new ConsoleApplication1.com.lixy.ws.UserServiceEx();    
    JafUser user = new JafUser();    
    user.userId = "lixy01";    
    user.userName = "lixiangyang01";    
    user.regionId = 4301;    
    user.regionIdSpecified = true;    
    String result = manager.saveUser(user);    
    Console.WriteLine("Result = " + result);    
    Console.ReadLine();    
    regionIdSpecified 虽然不是JafUser对象()中的属性,但是在测试程序时,发现只有将user.regionIdSpecified设为 true,regionId才被发送到webservice端。
      

  3.   

    在客户端的webservice代理类中增加一个soapheader类:/// <res/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://xxx.com/xxxservice/")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace="http://xxx.com/xxxservice/", IsNullable=false)]
        public partial class AuthenHeader : System.Web.Services.Protocols.SoapHeader {
                   
            private string usernameField;
            
            private string passwordField;
                    
            private System.Xml.XmlAttribute[] anyAttrField;
                   
            /// <res/>
            public string Username {
                get {
                    return this.usernameField;
                }
                set {
                    this.usernameField = value;
                }
            }
            
            /// <res/>
            public string Password {
                get {
                    return this.passwordField;
                }
                set {
                    this.passwordField = value;
                }
            }
             
            /// <res/>
            [System.Xml.Serialization.XmlAnyAttributeAttribute()]
            public System.Xml.XmlAttribute[] AnyAttr {
                get {
                    return this.anyAttrField;
                }
                set {
                    this.anyAttrField = value;
                }
            }
        }
    然后在你的代理类中加上:
    AuthenHeader AuthenHeaderValue的属性
    并且在代理类中的webservice方法上加三Attribute:[System.Web.Services.Protocols.SoapHeaderAttribute("AuthenHeaderValue", Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
    那么你在调用代理类来访问axis的webservice时,只要在调用的时候设置AuthenHeaderValue属性就可以了。当然AuthenHeader类,要根据axis中认证类来写,结构要一致!!!