Incorrect deserialization of SOAP message in .NET app - c#

I am working on converting an existing application from .NET Framework to .NET 6. Deserialization of SOAP message no longer works as expected.
I have the following response message:
<?xml version="1.0" encoding="utf-16"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
<S:Body>
<ns2:findAgreementResponse
xmlns:ns2="example.webservices.licensing.secure"
xmlns:ns3="example.webservices.exceptions">
<return>
<description>Standard</description>
<idLicenseAgreement>1234</idLicenseAgreement>
</return>
</ns2:findAgreementResponse>
</S:Body>
</S:Envelope>
With the .NET Framework, the code generated when I added a service reference included this:
[System.Xml.Serialization.XmlIncludeAttribute(typeof(agreement))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3221.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/licensing/")]
public partial class messageBase {
private System.Xml.XmlElement[] anyField;
private string messageIdField;
[System.Xml.Serialization.XmlAnyElementAttribute()]
public System.Xml.XmlElement[] Any {
get { return this.anyField; }
set { this.anyField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string messageId {
get { return this.messageIdField; }
set { this.messageIdField = value; }
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3221.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/licensing/")]
public partial class agreement : messageBase {
private string descriptionField;
private long idLicenseAgreementField;
private bool idLicenseAgreementFieldSpecified;
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string description {
get { return this.descriptionField; }
set { this.descriptionField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public long idLicenseAgreement {
get { return this.idLicenseAgreementField; }
set { this.idLicenseAgreementField = value; }
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool idLicenseAgreementSpecified {
get { return this.idLicenseAgreementFieldSpecified; }
set { this.idLicenseAgreementFieldSpecified = value; }
}
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", RequestNamespace="example.webservices.licensing.secure", ResponseNamespace="example.webservices.licensing.secure", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("return", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public agreement findAgreement([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] string arg0) {
object[] results = this.Invoke("findAgreement", new object[] {
arg0});
return ((agreement)(results[0]));
}
This worked well, the response was properly deserialized (when calling the findAgreement method). When something was not expected (there are many methods and responses), it was added to the Any array from messageBase.
After migrating to .NET 6, adding the service resulted in the following code:
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(agreement))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/licensing/")]
public partial class messageBase
{
private System.Xml.XmlElement[] anyField;
private string messageIdField;
[System.Xml.Serialization.XmlAnyElementAttribute(Order=0)]
public System.Xml.XmlElement[] Any
{
get { return this.anyField; }
set { this.anyField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
public string messageId
{
get { return this.messageIdField; }
set { this.messageIdField = value; }
}
}
[System.SerializableAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/licensing/")]
public partial class agreement : messageBase
{
private string descriptionField;
private long idLicenseAgreementField;
private bool idLicenseAgreementFieldSpecified;
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
public string description
{
get { return this.descriptionField; }
set { this.descriptionField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
public long idLicenseAgreement
{
get { return this.idLicenseAgreementField; }
set { this.idLicenseAgreementField = value; }
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool idLicenseAgreementSpecified
{
get { return this.idLicenseAgreementFieldSpecified; }
set { this.idLicenseAgreementFieldSpecified = value; }
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="findAgreementResponse", WrapperNamespace="example.webservices.licensing.secure", IsWrapped=true)]
public partial class findAgreementResponse
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="example.webservices.licensing.secure", Order=0)]
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public agreement #return;
public findAgreementResponse()
{
}
public findAgreementResponse(agreement #return)
{
this.#return = #return;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
findAgreementResponse findAgreement(findAgreementRequest request)
{
return base.Channel.findAgreement(request);
}
What happens now is that the description and idLicenseAgreement properties are not filled in. Instead, the Any array from the base class contains both these XML elements:
<description>Standard</description>
<idLicenseAgreement>1234</idLicenseAgreement>
If I remove the messageBase base class, parsing occurs correctly, and the agreement object is properly filled in with the data from the SOAP response.
I expect this to be a namespace issue but I was unable to figure it out.

I figured out the problem was the explicit ordering of elements. In the code generated by Svcutil in .NET 6, all the XML elements are attributed like this:
[System.Xml.Serialization.XmlAnyElementAttribute(Order=0)]
Once I removed the Order property from all of them, deserialization worked as expected.

Related

"Unable to strip payload from SOAP envelope" using ParkSquare.SoapClient

I try to challenge generated svcUtil SOAP Client with alternative approach.
Although the svcUtil approach works well but as it is using a persistent WCF channel to the Saop Server we would like to try to avoid this always connected behavior. In the other hand svcUtil does a great job by generating DTO from the wsdl so we would like to use it only for the DTO.
SparkQuare provide a SoapClient nuget which use a standard HttpClient and then fits our goal. However I get trouble to set it up properly.
Currently I get this error :
System.AggregateException : One or more errors occurred. (Unable to strip payload from SOAP envelope)
---- ParkSquare.SoapClient.SoapHttpClientException : Unable to strip payload from SOAP envelope
My guess is I did not properly set up defaultNamespace and action but I didn't find relevant documentation yet. Anyone got hints about it?
using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using ParkSquare.SoapClient;
using System.Net.Http.Headers;
using System.Text;
using Soap_sern_mvt_ServiceReference; //DTO generated by SvcUtil
namespace ErpApi.EndPoint.ParkSquareSoapClient
{
public class SerialNumberMouvementParkSquareSoapClient : ISerialNumberMouvement
{
private ISoapClient _soapClient;
private HttpClient _httpClient;
public SerialNumberMouvementParkSquareSoapClient()
{
string cred = "some:credentials";
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes(cred)));
_soapClient = new ParkSquare.SoapClient.SoapClient(
_httpClient,
new RawBodySerializer(),
new SoapHttpRequestBuilder(),
new PayloadStripper(),
new BodyDeserializer());
}
public async Task<IEnumerable<string>> GetAsync(string serialNumber)
{
ZsdSernMvtRequest requestDto = new ZsdSernMvtRequest();
ZsdSernMvt data = new ZsdSernMvt
{
EtSernrMvt = new List<ZsdSSernrSalesMvt>().ToArray(),
IndividualSerialNumber = serialNumber
};
requestDto.ZsdSernMvt = data;
//Exception will fire here :
var responseDto = await _soapClient.PostAsync<ZsdSernMvtRequest, ZsdSernMvtResponse1>(
endpoint: new Uri("http://theSoapServer/sap/bc/srt/rfc/sap/zws_sern_mvt/010/zome_sern_mvt/zome_sern_mvt?sap-client=010"),
request: requestDto,
defaultNamespace: "urn:sap-com:document:sap:soap:functions:mc-style",
action: "urn:sap-com:document:sap:soap:functions:mc-style:ZWS_SERN_MVT:ZsdSernMvtRequest",
SoapVersion.Soap12);
return new List<string>() { responseDto.ToString() };
}
}
}
for reference below is the code generated by svcutil which contains DTO used above.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Soap_sern_mvt_ServiceReference
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.ServiceModel.ServiceContractAttribute(Namespace="urn:sap-com:document:sap:soap:functions:mc-style", ConfigurationName="Soap_sern_mvt_ServiceReference.ZWS_SERN_MVT")]
public interface ZWS_SERN_MVT
{
[System.ServiceModel.OperationContractAttribute(Action="urn:sap-com:document:sap:soap:functions:mc-style:ZWS_SERN_MVT:ZsdSernMvtRequest", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
System.Threading.Tasks.Task<Soap_sern_mvt_ServiceReference.ZsdSernMvtResponse1> ZsdSernMvtAsync(Soap_sern_mvt_ServiceReference.ZsdSernMvtRequest request);
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:sap-com:document:sap:soap:functions:mc-style")]
public partial class ZsdSernMvt
{
private ZsdSSernrSalesMvt[] etSernrMvtField;
private string individualSerialNumberField;
private ZsdSSernr[] multipleSerialNumbersField;
private string productIsAWatchField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
public ZsdSSernrSalesMvt[] EtSernrMvt
{
get
{
return this.etSernrMvtField;
}
set
{
this.etSernrMvtField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
public string IndividualSerialNumber
{
get
{
return this.individualSerialNumberField;
}
set
{
this.individualSerialNumberField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2)]
[System.Xml.Serialization.XmlArrayItemAttribute("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
public ZsdSSernr[] MultipleSerialNumbers
{
get
{
return this.multipleSerialNumbersField;
}
set
{
this.multipleSerialNumbersField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=3)]
public string ProductIsAWatch
{
get
{
return this.productIsAWatchField;
}
set
{
this.productIsAWatchField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:sap-com:document:sap:soap:functions:mc-style")]
public partial class ZsdSSernrSalesMvt
{
private string brand_codeField;
private string intercompagy_codeField;
private string serial_numberField;
private string product_SAP_numberField;
private string receipt_dateField;
private string sales_dateField;
private string customer_numberField;
private string nameField;
private string additional_textField;
private string movement_codeField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
public string Brand_code
{
get
{
return this.brand_codeField;
}
set
{
this.brand_codeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
public string Intercompagy_code
{
get
{
return this.intercompagy_codeField;
}
set
{
this.intercompagy_codeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2)]
public string Serial_number
{
get
{
return this.serial_numberField;
}
set
{
this.serial_numberField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=3)]
public string Product_SAP_number
{
get
{
return this.product_SAP_numberField;
}
set
{
this.product_SAP_numberField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=4)]
public string Receipt_date
{
get
{
return this.receipt_dateField;
}
set
{
this.receipt_dateField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=5)]
public string Sales_date
{
get
{
return this.sales_dateField;
}
set
{
this.sales_dateField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=6)]
public string Customer_number
{
get
{
return this.customer_numberField;
}
set
{
this.customer_numberField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=7)]
public string Name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=8)]
public string Additional_text
{
get
{
return this.additional_textField;
}
set
{
this.additional_textField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=9)]
public string Movement_code
{
get
{
return this.movement_codeField;
}
set
{
this.movement_codeField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:sap-com:document:sap:soap:functions:mc-style")]
public partial class ZsdSSernr
{
private string serial_numberField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
public string Serial_number
{
get
{
return this.serial_numberField;
}
set
{
this.serial_numberField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:sap-com:document:sap:soap:functions:mc-style")]
public partial class ZsdSernMvtResponse
{
private ZsdSSernrSalesMvt[] etSernrMvtField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
public ZsdSSernrSalesMvt[] EtSernrMvt
{
get
{
return this.etSernrMvtField;
}
set
{
this.etSernrMvtField = value;
}
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class ZsdSernMvtRequest
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:sap-com:document:sap:soap:functions:mc-style", Order=0)]
public Soap_sern_mvt_ServiceReference.ZsdSernMvt ZsdSernMvt;
public ZsdSernMvtRequest()
{
}
public ZsdSernMvtRequest(Soap_sern_mvt_ServiceReference.ZsdSernMvt ZsdSernMvt)
{
this.ZsdSernMvt = ZsdSernMvt;
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class ZsdSernMvtResponse1
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:sap-com:document:sap:soap:functions:mc-style", Order=0)]
public Soap_sern_mvt_ServiceReference.ZsdSernMvtResponse ZsdSernMvtResponse;
public ZsdSernMvtResponse1()
{
}
public ZsdSernMvtResponse1(Soap_sern_mvt_ServiceReference.ZsdSernMvtResponse ZsdSernMvtResponse)
{
this.ZsdSernMvtResponse = ZsdSernMvtResponse;
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
public interface ZWS_SERN_MVTChannel : Soap_sern_mvt_ServiceReference.ZWS_SERN_MVT, System.ServiceModel.IClientChannel
{
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1")]
public partial class ZWS_SERN_MVTClient : System.ServiceModel.ClientBase<Soap_sern_mvt_ServiceReference.ZWS_SERN_MVT>, Soap_sern_mvt_ServiceReference.ZWS_SERN_MVT
{
public ZWS_SERN_MVTClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public System.Threading.Tasks.Task<Soap_sern_mvt_ServiceReference.ZsdSernMvtResponse1> ZsdSernMvtAsync(Soap_sern_mvt_ServiceReference.ZsdSernMvtRequest request)
{
return base.Channel.ZsdSernMvtAsync(request);
}
public virtual System.Threading.Tasks.Task OpenAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
}
public virtual System.Threading.Tasks.Task CloseAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
}
}
}
Do you have the full stack trace that results in that exception?
Also, a full (valid) SOAP request that is sent across the wire by the generated client? You could get this by running Fiddler (or similar) to capture the request.

ASMX Service XML request deserializing partially

I know this old tech, if it was up to me life would be different. I am relatively new to this old tech, I am extending an existing service at work and I am experiencing an odd issue. I have 3 service endpoints and 2 of them are working as expected but my issue with the third one is that some how the "framework" fails to deserialize the xml request.
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<UpdateSale xmlns="http://tokenws.netgen.co.za/">
<p_objrequest>
<transactionTypeId>1</transactionTypeId>
<tenderTypeId>1</tenderTypeId>
<standardHeader>
<requestId xmlns="">1_8</requestId>
<localeId xmlns="" />
<systemId xmlns="">asdf</systemId>
<batchReference xmlns="">11</batchReference>
</standardHeader>
<account>
<accountId xmlns="">123</accountId>
<pin xmlns="" >123</pin>
</account>
<amount>
<valueCode xmlns="">ZAR</valueCode>
<enteredAmount xmlns="">30</enteredAmount>
<nsfAllowed xmlns="">N</nsfAllowed>
</amount>
<lineItems>
<LineItem>
<productCode>1</productCode>
<categoryCode>1</categoryCode>
<qty>1</qty>
<price>50</price>
<discountedPrice>0</discountedPrice>
<description>Buffet Breakfast</description>
</LineItem>
</lineItems>
</p_objrequest>
<netCredentials>
<UserName xmlns="http://tempuri.org/">123</UserName>
<Password xmlns="http://tempuri.org/">123</Password>
</netCredentials>
</UpdateSale>
</soap:Body>
</soap:Envelope>
Above is the xml, the netCredentials get deserialized correctly but p_objrequest comes as null.
How can I resolve this?
Below is the class:
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://tokenws.netgen.co.za/")]
public class Sale
{
private int transactionTypeIdField;
private int tenderTypeIdField;
private RequestStandardHeaderComponent standardHeaderField;
private AccountComponent accountField;
private string activatingField;
private AmountComponent amountField;
private CustomerInfoComponent customerInfoField;
private PromotionCode[] promotionCodesField;
private QuestionAndAnswer[] questionsAndAnswersField;
private LineItem[] lineItemsField;
private string includeTipField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public int transactionTypeId
{
get
{
return this.transactionTypeIdField;
}
set
{
this.transactionTypeIdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public int tenderTypeId
{
get
{
return this.tenderTypeIdField;
}
set
{
this.tenderTypeIdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 2)]
public RequestStandardHeaderComponent standardHeader
{
get
{
return this.standardHeaderField;
}
set
{
this.standardHeaderField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 3)]
public AccountComponent account
{
get
{
return this.accountField;
}
set
{
this.accountField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 4)]
public string activating
{
get
{
return this.activatingField;
}
set
{
this.activatingField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 5)]
public AmountComponent amount
{
get
{
return this.amountField;
}
set
{
this.amountField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 6)]
public CustomerInfoComponent customerInfo
{
get
{
return this.customerInfoField;
}
set
{
this.customerInfoField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Order = 7)]
public PromotionCode[] promotionCodes
{
get
{
return this.promotionCodesField;
}
set
{
this.promotionCodesField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Order = 8)]
public QuestionAndAnswer[] questionsAndAnswers
{
get
{
return this.questionsAndAnswersField;
}
set
{
this.questionsAndAnswersField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Order = 9)]
public LineItem[] lineItems
{
get
{
return this.lineItemsField;
}
set
{
this.lineItemsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 10)]
public string includeTip
{
get
{
return this.includeTipField;
}
set
{
this.includeTipField = value;
}
}
}
The tag name and the class/property names must match including case. See below :
[XmlRoot(ElementName= "UpdateSale", Namespace="http://tokenws.netgen.co.za/")]
public class Sale
{
}
[XmlRoot(ElementName= "netCredentials")]
public class NetCredentials
{
[XmlElement(ElementName="UserName",Namespace="http://tempuri.org/")]
public Name userName { get; set;}
[XmlElement(ElementName="Password",Namespace="http://tempuri.org/")]
public Name password { get; set;}
}
public class Name
{
[XmlText]
public string name { get; set;}
}

svcutil.exe xsd code generation for objects with nested arrays

I've got and XSD which I use to generate DataContracts for my WCF service.
Here is visual represantation of XSD
When i use XSD.EXE for generation everything is fine and i get object like so
public partial class MessageType {
private MessageInfoType messageInfoField;
private LotType[] lotsListField;
/// <remarks/>
public MessageInfoType messageInfo {
get {
return this.messageInfoField;
}
set {
this.messageInfoField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("lot", IsNullable=false)]
public LotType[] lotsList {
get {
return this.lotsListField;
}
set {
this.lotsListField = value;
}
}
}
And here is generated code for nested lot object
public partial class LotType {
private LotGeneralInfoType lotGeneralInfoField;
private ProductInfoType[] productInfoField;
//Other generated fields
}
but when I try to generated classes via svcutil.exe with command
svcutil *.xsd /dconly /ser:XmlSerializer /importXmlTypes
I get different result. Here is generated code for MessageType object.
[System.Runtime.Serialization.DataContractAttribute(Name="MessageType", Namespace="http://test.me/types")]
public partial class MessageType : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private MessageInfoType messageInfoField;
private LotsListType lotsListField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false)]
public MessageInfoType messageInfo
{
get
{
return this.messageInfoField;
}
set
{
this.messageInfoField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false, Order=1)]
public LotsListType lotsList
{
get
{
return this.lotsListField;
}
set
{
this.lotsListField = value;
}
}
}
It's look like that everything is ok but nested LotType array is different. It represents collection with some kind of xml elements with it. Here is the generated code
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.CollectionDataContractAttribute(Name="LotsListType", Namespace="http://test.me/types", ItemName="lot")]
public class LotsListType : System.Collections.Generic.List<LotType>
{
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Xml.Serialization.XmlSchemaProviderAttribute("ExportSchema")]
[System.Xml.Serialization.XmlRootAttribute(IsNullable=false)]
public partial class LotType : object, System.Xml.Serialization.IXmlSerializable
{
private System.Xml.XmlNode[] nodesField;
private static System.Xml.XmlQualifiedName typeName = new System.Xml.XmlQualifiedName("LotType", "http://test.me/types");
public System.Xml.XmlNode[] Nodes
{
get
{
return this.nodesField;
}
set
{
this.nodesField = value;
}
}
public void ReadXml(System.Xml.XmlReader reader)
{
this.nodesField = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader);
}
public void WriteXml(System.Xml.XmlWriter writer)
{
System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes);
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public static System.Xml.XmlQualifiedName ExportSchema(System.Xml.Schema.XmlSchemaSet schemas)
{
System.Runtime.Serialization.XmlSerializableServices.AddDefaultSchema(schemas, typeName);
return typeName;
}
}
Is there any way to generated just the same code like XSD.EXE but with DataMemeber/DataContract attributes?

Create soap request

I've tried to serialize an object with XmlSerializer and SoapFormatter but i can't get the output to look like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Login xmlns="http://www.myfirm.com/2010/core/ConnectTypes">
<UserLogin>
<UserName>User</UserName>
<Password>PW</Password>
<Mandant>1</Mandant>
</UserLogin>
</Login>
</soap:Body>
</soap:Envelope>
My classes:
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class UserLoginType
{
private string userNameField;
private string passwordField;
private int mandantField;
/// <remarks/>
public string UserName
{
get
{
return this.userNameField;
}
set
{
this.userNameField = value;
}
}
/// <remarks/>
public string Password
{
get
{
return this.passwordField;
}
set
{
this.passwordField = value;
}
}
/// <remarks/>
public int Mandant
{
get
{
return this.mandantField;
}
set
{
this.mandantField = value;
}
}
}
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class LoginType
{
private object itemField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("LoginToken", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("UserLogin", typeof(UserLoginType))]
public object Item
{
get
{
return this.itemField;
}
set
{
this.itemField = value;
}
}
}
Can anyone help?
To Log the SoapRequest try MessageInspector or enable the Logging in Web.Config for Web Service.
Generally, you do not have to serialize our objects way like that.
You should add the Web-Reference via WSDL-url, and invoke methods of the service by the generated proxy class

Missing fields when serializing .NET object

I am having a problem with serializing an object in C#. When the application goes to serialize the object, certain fields get serialized but others do not. In the following code:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ACORDInsuranceSvcRqHomePolicyQuoteInqRq
{
private string rqUIDField;
private System.DateTime transactionRequestDtField;
private System.DateTime transactionEffectiveDtField;
private string curCdField;
/// <remarks/>
public string RqUID
{
get
{
return this.rqUIDField;
}
set
{
this.rqUIDField = value;
}
}
/// <remarks/>
public string CurCd
{
get
{
return this.curCdField;
}
set
{
this.curCdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnore()]
public System.DateTime TransactionRequestDt
{
get
{
return this.transactionRequestDtField;
}
set
{
this.transactionRequestDtField = value;
}
}
/// <remarks/>
[XmlElement("TransactionRequestDt")]
public string TransactionRequestDtString
{
get
{
return String.Format("{0:yyyy-MM-dd}", this.TransactionRequestDt);
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnore]
public System.DateTime TransactionEffectiveDt
{
get
{
return this.transactionEffectiveDtField;
}
set
{
this.transactionEffectiveDtField = value;
}
}
/// <remarks/>
[XmlElement("TransactionEffectiveDt")]
public string TransactionEffectiveDtString
{
get
{
return String.Format("{0:yyyy-MM-dd}", this.TransactionEffectiveDt);
}
}
}
you can see that the Fields/Accessors RqUID and CurCd get called but TransactionRequestDtString and TransactionEffectiveDtString do not. I need all of these to be serialized. Thanks!
If they need to be xml serialized they need a public get and set.
Try changing your code to this:
[ReadOnly(true)]
[XmlElement("TransactionRequestDt")]
public string TransactionRequestDtString
{
get
{
return String.Format("{0:yyyy-MM-dd}", this.TransactionRequestDt);
}
set{}
}`
The ReadOnly attribute will not let anyone change it.
Possible answer see: Serializing private member data
I was facing the same issue with some properties(which are nullable) , i FIXED it by using : [XmlElement(IsNullable = true)] decorator
public class Person
{
[XmlElement(IsNullable = true)]
public string Name { get; set; }
}

Categories