public byte[] SaveEnvelopeData(ImmutableEnvelope envelope) { // string contract, Guid messageId, Uri sender, var itemContracts = new MessageContract[envelope.Items.Length]; using (var content = new MemoryStream()) { int position = 0; for (int i = 0; i < envelope.Items.Length; i++) { var item = envelope.Items[i]; string name; if (!_dataSerializer.TryGetContractNameByType(item.MappedType, out name)) { var error = string.Format("Failed to find contract name to serialize '{0}'.", item.MappedType); throw new InvalidOperationException(error); } // normal serializers have a nasty habbit of closing the stream after they are done // we can suppress that or use a wrapper now instead using (var itemStream = new MemoryStream()) { _dataSerializer.Serialize(item.Content, item.MappedType, itemStream); var bytes = itemStream.ToArray(); content.Write(bytes, 0, bytes.Length); } int size = (int)content.Position - position; var attribContracts = EnvelopeConvert.ItemAttributesToContract(item.GetAllAttributes()); itemContracts[i] = new MessageContract(name, size, position, attribContracts); position += size; } var envelopeAttribs = EnvelopeConvert.EnvelopeAttributesToContract(envelope.GetAllAttributes()); var contract = new EnvelopeContract(envelope.EnvelopeId, envelopeAttribs, itemContracts, envelope.DeliverOnUtc, envelope.CreatedOnUtc); using (var stream = new MemoryStream()) { // skip header stream.Seek(EnvelopeHeaderContract.FixedSize, SeekOrigin.Begin); // save envelope attributes _envelopeSerializer.SerializeEnvelope(stream, contract); var envelopeBytes = stream.Position - EnvelopeHeaderContract.FixedSize; // copy data content.WriteTo(stream); // write the header stream.Seek(0, SeekOrigin.Begin); var header = new EnvelopeHeaderContract(EnvelopeHeaderContract.Schema2DataFormat, envelopeBytes, 0); header.WriteToStream(stream); return(stream.ToArray()); } } }