Reputation: 111
I need to serialize out a composite object. I have a object "Trailer" that contains "Shipments" of "Items". When I serialize out the object using the SoapFormatter like so:
Trailer trailer = new Trailer() { TrailerID = "1234" };
Shipment shipment1 = new Shipment() { ShipmentNo = "123456789", CarrierCode = "1234", SupplierCode = "12345", CarrierProNo = "1234567", BillOfLadingNo = "11111111", DateNeeded = "2013-04-15", Loc = "000", PackageSlipNo = "11111111", OrderShipped = "2013-02-15", UnloadPriority = "", UpdateID = "" };
shipment1.Items.Add(new Item() { ItemNo = "111111", ItemDescription = "Blah", ItemQty= "11", OrderNo = "1111111", OrderLineNo = "111" });
shipment1.Items.Add(new Item() { ItemNo = "222222", ItemDescription = "Blah 2", ItemQty= "22", OrderNo = "2222", OrderLineNo = "2222" });
trailer.Contents.Add(shipment1);
MemoryStream memoryStream = new MemoryStream();
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(memoryStream, trailer);
string trailerSoapMessage = Encoding.ASCII.GetString(memoryStream.GetBuffer());
I get this:
<SOAP-ENV:Body>
<Trailer id="ref-1">
<TrailerID id="ref-2">1234</TrailerID>
<Contents href="#ref-3"/>
</Trailer>
<a1:ArrayList id="ref-3" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-4"/>
<_size>2</_size>
<_version>2</_version>
</a1:ArrayList>
<SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="xsd:anyType[4]">
<item href="#ref-5"/>
<item href="#ref-6"/>
</SOAP-ENC:Array>
<Shipment id="ref-5">
<ASNNumber id="ref-7">123456789</ASNNumber>
<SupplierCode id="ref-8">12345</SupplierCode>
<Loc id="ref-9">000</Loc>
<CarrierCode id="ref-10">12345</CarrierCode>
<CarrierProNo id="ref-11">12223</CarrierProNo>
<BillOfLadingNo href="#ref-7"/>
<PackageSlipNo href="#ref-7"/>
<UpdateID id="ref-12"></UpdateID>
<UnloadPriority href="#ref-12"/>
<DateNeeded id="ref-13">2013-03-15</DateNeeded>
<OrderShipped id="ref-14">2013-02-15</OrderShipped>
<Items href="#ref-15"/>
</Shipment>
.....
I would like a more structured message with Trailer as the top node containing shipments that contain items. I would also like to remove the id attributes added to the nodes and not have the ArrayList metadata serialized out. I realize that this is by design but I don't want/need the extra data. This maybe a case of using the wrong tool for the job.
Thanks
Upvotes: 1
Views: 1293
Reputation: 111
I believe I have my solution. I have decorated my Trailer class with MessageContract and decorated all properties with MessageBodyMember:
[MessageContract]
public class Trailer
{
[MessageBodyMember(Order=1)]
public string TrailerID { get; set; }
[MessageBodyMember]
public List<Shipment> Contents { get; set; }
public Trailer()
{
this.Contents = new List<Shipment>();
}
}
public class Shipment
{
[MessageBodyMember(Order = 1)]
public string ASNNumber { get; set; }
[MessageBodyMember(Order = 2)]
public string SupplierCode { get; set; }
[MessageBodyMember(Order = 3)]
public string Loc { get; set; }
[MessageBodyMember(Order = 4)]
public string CarrierCode { get; set; }
[MessageBodyMember(Order = 5)]
public string CarrierProNo { get; set; }
[MessageBodyMember(Order = 6)]
public string BillOfLadingNo { get; set; }
[MessageBodyMember(Order = 7)]
public string PackageSlipNo { get; set; }
[MessageBodyMember(Order = 8)]
public string UpdateID { get; set; }
[MessageBodyMember(Order = 9)]
public string UnloadPriority { get; set; }
[MessageBodyMember(Order = 10)]
public string DateNeeded { get; set; }
[MessageBodyMember(Order = 11)]
public string OrderShipped { get; set; }
[MessageBodyMember(Order = 12)]
public List<Item> Items { get; set; }
public Shipment()
{
this.Items = new List<Item>();
}
}
public class Item
{
[MessageBodyMember(Order = 1)]
public string ItemNo { get; set; }
[MessageBodyMember(Order = 2)]
public string OrderNo { get; set; }
[MessageBodyMember(Order = 3)]
public string OrderLineNo { get; set; }
[MessageBodyMember(Order = 4)]
public string ItemDescription { get; set; }
[MessageBodyMember(Order = 5)]
public string ItemQty { get; set; }
public Item() { }
}
I can then create a message like so:
System.ServiceModel.Channels.Message message = System.ServiceModel.Channels.Message.CreateMessage(System.ServiceModel.Channels.MessageVersion.Default, "GetTrailerContents", trailer);
Upvotes: 2