To consume a SOAP service, I need to send messages in XML which looks like:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:bus="http://ws.praxedo.com/v6/businessEvent">
<soap:Header/>
<soap:Body>
<bus:listAttachments>
<businessEventId>00044</businessEventId>
</bus:listAttachments>
</soap:Body>
</soap:Envelope>
Obviously, the easy way to do this would just be to create a string and interpolate some variable (e.g. businessEventId
) into the midst of it, like:
$"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\""
" xmlns:bus=\"http://ws.praxedo.com/v6/businessEvent\">"
"<soap:Header/><soap:Body>"
"<bus:listAttachments><businessEventId>{businessEventId}</businessEventId>"
"</bus:listAttachments></soap:Body></soap:Envelope>"
But I'd rather instantiate some collection of POPO, like:
public class Envelope {
public Header Header {get; init;}
public Body Body {get; init;}
}
public class Header {
}
public class Body {
public ListAttachments Attachments {get; init;}
}
public class ListAttachments {
public string BusinessEventId {get; init;}
}
What Attributes do I need to declare?
And what would I then need to do to serialize this, assuming I have a populated instance already?
--
As per @DavidBrowne's comment, I've tried the following which does NOT work:
private string CreateBody(string businessEventId)
{
BusinessEventAttachmentListRequestEnvelope envelope = BusinessEventAttachmentListRequestEnvelope.From(businessEventId);
MemoryStream memorystream = new();
DataContractSerializer serializer = new(typeof(BusinessEventAttachmentListRequestEnvelope));
serializer.WriteObject(memorystream, envelope);
memorystream.Seek(0, SeekOrigin.Begin);
using StreamReader streamReader = new(memorystream);
return streamReader.ReadToEnd();
}
[DataContract(Name = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class BusinessEventAttachmentListRequestEnvelope
{
[DataMember]
EmptySoapHeader Header = new();
[DataMember]
BusinessEventAttachmentListRequestBody Body { get; init; }
public static BusinessEventAttachmentListRequestEnvelope From(string businessEventId) =>
new()
{
Body = new()
{
Request = new()
{
BusinessEventId = businessEventId
}
}
};
}
[DataContract(Name = "Header", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class EmptySoapHeader
{
}
[DataContract(Name = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class BusinessEventAttachmentListRequestBody
{
[DataMember(Name = "listAttachments")]
public BusinessEventAttachmentListRequest Request { get; init; }
}
[DataContract(Name = "listAttachments", Namespace = "http://ws.praxedo.com/v6/businessEvent")]
public class BusinessEventAttachmentListRequest
{
[DataMember(Name = "businessEventId")]
public string BusinessEventId { get; init; }
}
The resulting XML seems substantially different:
<Envelope xmlns=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">
<Body>
<listAttachments xmlns:a=\"http://ws.praxedo.com/v6/businessEvent\">
<a:businessEventId>00044</a:businessEventId>
</listAttachments>
</Body>
<Header/>
</Envelope>
And the remote server returns error 500.
CodePudding user response:
If you're using Visual Studio there's a really easy shortcut you can use: Paste XML as Classes:
Which creates for your sample XML:
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
public partial class Envelope
{
private object headerField;
private EnvelopeBody bodyField;
/// <remarks/>
public object Header
{
get
{
return this.headerField;
}
set
{
this.headerField = value;
}
}
/// <remarks/>
public EnvelopeBody Body
{
get
{
return this.bodyField;
}
set
{
this.bodyField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public partial class EnvelopeBody
{
private listAttachments listAttachmentsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "http://ws.praxedo.com/v6/businessEvent")]
public listAttachments listAttachments
{
get
{
return this.listAttachmentsField;
}
set
{
this.listAttachmentsField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.praxedo.com/v6/businessEvent")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.praxedo.com/v6/businessEvent", IsNullable = false)]
public partial class listAttachments
{
private byte businessEventIdField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "")]
public byte businessEventId
{
get
{
return this.businessEventIdField;
}
set
{
this.businessEventIdField = value;
}
}
}