这是一个关于: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信息过去。
本人现在的项目遇到一个问题。服务端是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信息过去。
问题:如果用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端。
[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中认证类来写,结构要一致!!!