SoapHeader class not instantiated during response deserialization
I had no problem creating a .Net web service that uses document binding style
and literal formatting that had both a SoapHeader on input for Authentication
and a SoapHeader on output for sending back general status information.
Unfortunately, I have to communicate with a web service that is using rpc
binding stype and encoded formatting. I have no problem sending the input
authentication SoapHeader up to the service provider's web service and I do
receive a response back with correct return parameters, but the class
associated with the output SoapHeader does not get instantiated during the
response deserialization process like it does in the implementation I stated
in the first paragraph.
Here's the .Net Web Service implementation:
public class Service1 : System.Web.Services.WebService
{
public AuthenticationHeader1 AuthHeader;
public callStatus1 ResponseStatus;
[WebMethod]
[SoapHeader("AuthHeader")]
[SoapHeader("ResponseStatus", Direction = SoapHeaderDirection.Out)]
public string HelloWorldEx(string name, int val)
{
ResponseStatus = new callStatus1();
if (AuthHeader.username == 45 && AuthHeader.password == "npa")
{
ResponseStatus.statusText = "Success";
ResponseStatus.statusCode = 0;
return "Hello World Ex";
}
else
{
ResponseStatus.statusText = "Unauthorized Access";
ResponseStatus.statusCode = 1;
return "Unauthorized Access";
}
}
}
Here's are the important portions of the proxy client for the web service
above:
[System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap",
Namespace="http://tempuri.org/")]
public partial class Service1 :
System.Web.Services.Protocols.SoapHttpClientProtocol {
private AuthenticationHeader1 authenticationHeader1ValueField;
private callStatus1 callStatus1ValueField;
private System.Threading.SendOrPostCallback HelloWorldOperationCompleted;
private System.Threading.SendOrPostCallback
HelloWorldExOperationCompleted;
/// <remarks/>
public Service1() {
this.Url = "http://localhost:2387/Service1.asmx";
}
public AuthenticationHeader1 AuthenticationHeader1Value {
get {
return this.authenticationHeader1ValueField;
}
set {
this.authenticationHeader1ValueField = value;
}
}
public callStatus1 callStatus1Value {
get {
return this.callStatus1ValueField;
}
set {
this.callStatus1ValueField = value;
}
}
[System.Web.Services.Protocols.SoapHeaderAttribute("callStatus1Value",
Direction=System.Web.Services.Protocols.SoapHeaderDirection.Out)]
[System.Web.Services.Protocols.SoapHeaderAttribute("AuthenticationHeader1Value")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorldEx",
RequestNamespace="http://tempuri.org/",
ResponseNamespace="http://tempuri.org/",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string HelloWorldEx(string name, int val) {
object[] results = this.Invoke("HelloWorldEx", new object[] {
name,
val});
return ((string)(results[0]));
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/",
IsNullable=false)]
public partial class callStatus1 : System.Web.Services.Protocols.SoapHeader {
private string statusTextField;
private int statusCodeField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
public string statusText {
get {
return this.statusTextField;
}
set {
this.statusTextField = value;
}
}
/// <remarks/>
public int statusCode {
get {
return this.statusCodeField;
}
set {
this.statusCodeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyAttributeAttribute()]
public System.Xml.XmlAttribute[] AnyAttr {
get {
return this.anyAttrField;
}
set {
this.anyAttrField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/",
IsNullable=false)]
public partial class AuthenticationHeader1 :
System.Web.Services.Protocols.SoapHeader {
private int usernameField;
private string passwordField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
public int username {
get {
return this.usernameField;
}
set {
this.usernameField = value;
}
}
/// <remarks/>
public string password {
get {
return this.passwordField;
}
set {
this.passwordField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyAttributeAttribute()]
public System.Xml.XmlAttribute[] AnyAttr {
get {
return this.anyAttrField;
}
set {
this.anyAttrField = value;
}
}
}
Here is the code that calls the proxy client:
private void LHTestEx()
{
Service1 dhs;
try
{
dhs = new Service1();
// To see the request turn the proxy on and run ProxyTrace
on 8080
// You will also need to change the web service URL to
192.168.1.178
// and it will fail, but at least you get to see the packet
going out
// in the ProxyTrace window
//WebProxy webProxy = new WebProxy("http://localhost:8080/",
false);
//dhs.Proxy = webProxy;
AuthenticationHeader1 ah = new AuthenticationHeader1();
ah.username = 111;
ah.password = "xxx";
dhs.AuthenticationHeader1Value = ah;
string result = dhs.HelloWorldEx("blah", 123);
int statusCode = dhs.callStatus1Value.statusCode;
string statusText = dhs.callStatus1Value.statusText;
MessageBox.Show(result);
}
catch (SoapHeaderException ex)
{
string s = ex.Message;
s = ex.Message;
}
catch (Exception ex)
{
string s = ex.Message;
s = ex.Message;
}
}
************************************************************
Below is the proxy client generated from the service provider's WSDL file
that is using RPC / encoded. Basically there is just the changes in the
Attributes to support SOAP serialization instead of XML serialization:
[System.Web.Services.WebServiceBindingAttribute(Name =
"DemoSoapBinding", Namespace = "https://centdev.liveglobalbid.com/Demo")]
public partial class DemoHandlerService :
System.Web.Services.Protocols.SoapHttpClientProtocol
{
private AuthenticationHeader authenticationHeaderValueField;
private callStatus callStatusValueField;
private System.Threading.SendOrPostCallback hiOperationCompleted;
private System.Threading.SendOrPostCallback
getSaleCountOperationCompleted;
/// <remarks/>
public DemoHandlerService()
{
this.Url =
"https://centdev.liveglobalbid.com/secure/ws/server.cgi";
}
public AuthenticationHeader AuthenticationHeaderValue
{
get
{
return this.authenticationHeaderValueField;
}
set
{
this.authenticationHeaderValueField = value;
}
}
public callStatus callStatusValue
{
get
{
return this.callStatusValueField;
}
set
{
this.callStatusValueField = value;
}
[System.Web.Services.Protocols.SoapHeaderAttribute("callStatusValue",
Direction = System.Web.Services.Protocols.SoapHeaderDirection.Out)]
[System.Web.Services.Protocols.SoapHeaderAttribute("AuthenticationHeaderValue")]
[System.Web.Services.Protocols.SoapRpcMethodAttribute("",
RequestNamespace = "https://centdev.liveglobalbid.com/Demo",
ResponseNamespace = "https://centdev.liveglobalbid.com/Demo")]
[return:
System.Xml.Serialization.SoapElementAttribute("getSaleCountReturn")]
public string getSaleCount(string dummyone, int dummytwo)
{
object[] results = this.Invoke("getSaleCount", new object[] {
dummyone,
dummytwo});
return ((string)(results[0]));
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute("callStatus", Namespace =
"https://centdev.liveglobalbid.com/Demo")]
public partial class callStatus : SoapHeader
{
private string statusTextField;
private int statusCodeField;
public string statusText
{
get
{
return this.statusTextField;
}
set
{
this.statusTextField = value;
}
}
public int statusCode
{
get
{
return this.statusCodeField;
}
set
{
this.statusCodeField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace =
"https://centdev.liveglobalbid.com/Demo")]
public partial class AuthenticationHeader : SoapHeader
{
private int usernameField;
private string passwordField;
/// <remarks/>
public int username
{
get
{
return this.usernameField;
}
set
{
this.usernameField = value;
}
}
/// <remarks/>
public string password
{
get
{
return this.passwordField;
}
set
{
this.passwordField = value;
}
}
}
Here is the calling code to the proxy client for the service provider's web
service:
private void LGBGetSaleCount()
{
DemoHandlerService dhs;
try
{
dhs = new DemoHandlerService();
//WebProxy webProxy = new WebProxy("http://localhost:8080/",
false);
//dhs.Proxy = webProxy;
AuthenticationHeader ah = new AuthenticationHeader();
//callStatus cs = new callStatus();
ah.username = 111;
ah.password = "xxx";
dhs.AuthenticationHeaderValue = ah;
//dhs.callStatusValue = cs;
string result = dhs.getSaleCount("Binh", 5);
int statusCode = dhs.callStatusValue.statusCode;
string statusText = dhs.callStatusValue.statusText;
MessageBox.Show(result);
}
catch (SoapHeaderException ex)
{
string s = ex.Message;
s = ex.Message;
}
catch (Exception ex)
{
string s = ex.Message;
s = ex.Message;
}
}
**********************************************************
date: Fri, 4 Apr 2008 17:58:38 -0700
author: Larry Herbinaux