XmlSerializerOperationFormatter.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System.Collections;
  7. using System.ServiceModel.Channels;
  8. using System.ServiceModel;
  9. using System.ServiceModel.Description;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12. using System.Diagnostics;
  13. using System.Runtime.Serialization;
  14. using System.Reflection;
  15. using System.Xml;
  16. using System.Xml.Serialization;
  17. using System.ServiceModel.Diagnostics;
  18. using System.IO;
  19. using System.Xml.Schema;
  20. class XmlSerializerOperationFormatter : OperationFormatter
  21. {
  22. const string soap11Encoding = "http://schemas.xmlsoap.org/soap/encoding/";
  23. const string soap12Encoding = "http://www.w3.org/2003/05/soap-encoding";
  24. bool isEncoded;
  25. MessageInfo requestMessageInfo;
  26. MessageInfo replyMessageInfo;
  27. public XmlSerializerOperationFormatter(OperationDescription description, XmlSerializerFormatAttribute xmlSerializerFormatAttribute,
  28. MessageInfo requestMessageInfo, MessageInfo replyMessageInfo) :
  29. base(description, xmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc, xmlSerializerFormatAttribute.IsEncoded)
  30. {
  31. if (xmlSerializerFormatAttribute.IsEncoded && xmlSerializerFormatAttribute.Style != OperationFormatStyle.Rpc)
  32. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDocEncodedNotSupported, description.Name)));
  33. this.isEncoded = xmlSerializerFormatAttribute.IsEncoded;
  34. this.requestMessageInfo = requestMessageInfo;
  35. this.replyMessageInfo = replyMessageInfo;
  36. }
  37. protected override void AddHeadersToMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
  38. {
  39. XmlSerializer serializer;
  40. MessageHeaderDescriptionTable headerDescriptionTable;
  41. MessageHeaderDescription unknownHeaderDescription;
  42. bool mustUnderstand;
  43. bool relay;
  44. string actor;
  45. try
  46. {
  47. if (isRequest)
  48. {
  49. serializer = requestMessageInfo.HeaderSerializer;
  50. headerDescriptionTable = requestMessageInfo.HeaderDescriptionTable;
  51. unknownHeaderDescription = requestMessageInfo.UnknownHeaderDescription;
  52. }
  53. else
  54. {
  55. serializer = replyMessageInfo.HeaderSerializer;
  56. headerDescriptionTable = replyMessageInfo.HeaderDescriptionTable;
  57. unknownHeaderDescription = replyMessageInfo.UnknownHeaderDescription;
  58. }
  59. if (serializer != null)
  60. {
  61. object[] headerValues = new object[headerDescriptionTable.Count];
  62. MessageHeaderOfTHelper messageHeaderOfTHelper = null;
  63. int headerIndex = 0;
  64. foreach (MessageHeaderDescription headerDescription in messageDescription.Headers)
  65. {
  66. object parameterValue = parameters[headerDescription.Index];
  67. if (!headerDescription.IsUnknownHeaderCollection)
  68. {
  69. if (headerDescription.TypedHeader)
  70. {
  71. if (messageHeaderOfTHelper == null)
  72. messageHeaderOfTHelper = new MessageHeaderOfTHelper(parameters.Length);
  73. headerValues[headerIndex++] = messageHeaderOfTHelper.GetContentAndSaveHeaderAttributes(parameters[headerDescription.Index], headerDescription);
  74. }
  75. else
  76. headerValues[headerIndex++] = parameterValue;
  77. }
  78. }
  79. MemoryStream memoryStream = new MemoryStream();
  80. XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream);
  81. bufferWriter.WriteStartElement("root");
  82. serializer.Serialize(bufferWriter, headerValues, null, isEncoded ? GetEncoding(message.Version.Envelope) : null);
  83. bufferWriter.WriteEndElement();
  84. bufferWriter.Flush();
  85. XmlDocument doc = new XmlDocument();
  86. memoryStream.Position = 0;
  87. doc.Load(memoryStream);
  88. //doc.Save(Console.Out);
  89. foreach (XmlElement element in doc.DocumentElement.ChildNodes)
  90. {
  91. MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(element.LocalName, element.NamespaceURI);
  92. if (matchingHeaderDescription == null)
  93. message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
  94. false/*mustUnderstand*/, null/*actor*/, false/*relay*/, element));
  95. else
  96. {
  97. if (matchingHeaderDescription.TypedHeader)
  98. messageHeaderOfTHelper.GetHeaderAttributes(matchingHeaderDescription, out mustUnderstand, out relay, out actor);
  99. else
  100. {
  101. mustUnderstand = matchingHeaderDescription.MustUnderstand;
  102. relay = matchingHeaderDescription.Relay;
  103. actor = matchingHeaderDescription.Actor;
  104. }
  105. message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
  106. mustUnderstand, actor, relay, element));
  107. }
  108. }
  109. }
  110. if (unknownHeaderDescription != null && parameters[unknownHeaderDescription.Index] != null)
  111. {
  112. foreach (object unknownHeader in (IEnumerable)parameters[unknownHeaderDescription.Index])
  113. {
  114. XmlElement element = (XmlElement)GetContentOfMessageHeaderOfT(unknownHeaderDescription, unknownHeader, out mustUnderstand, out relay, out actor);
  115. if (element != null)
  116. message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
  117. mustUnderstand, actor, relay, element));
  118. }
  119. }
  120. }
  121. catch (InvalidOperationException e)
  122. {
  123. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
  124. SR.GetString(SR.SFxErrorSerializingHeader, messageDescription.MessageName, e.Message), e));
  125. }
  126. }
  127. protected override void GetHeadersFromMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
  128. {
  129. try
  130. {
  131. XmlSerializer serializer;
  132. MessageHeaderDescriptionTable headerDescriptionTable;
  133. MessageHeaderDescription unknownHeaderDescription;
  134. if (isRequest)
  135. {
  136. serializer = requestMessageInfo.HeaderSerializer;
  137. headerDescriptionTable = requestMessageInfo.HeaderDescriptionTable;
  138. unknownHeaderDescription = requestMessageInfo.UnknownHeaderDescription;
  139. }
  140. else
  141. {
  142. serializer = replyMessageInfo.HeaderSerializer;
  143. headerDescriptionTable = replyMessageInfo.HeaderDescriptionTable;
  144. unknownHeaderDescription = replyMessageInfo.UnknownHeaderDescription;
  145. }
  146. MessageHeaders headers = message.Headers;
  147. ArrayList unknownHeaders = null;
  148. XmlDocument xmlDoc = null;
  149. if (unknownHeaderDescription != null)
  150. {
  151. unknownHeaders = new ArrayList();
  152. xmlDoc = new XmlDocument();
  153. }
  154. if (serializer == null)
  155. {
  156. if (unknownHeaderDescription != null)
  157. {
  158. for (int headerIndex = 0; headerIndex < headers.Count; headerIndex++)
  159. AddUnknownHeader(unknownHeaderDescription, unknownHeaders, xmlDoc, null/*bufferWriter*/, headers[headerIndex], headers.GetReaderAtHeader(headerIndex));
  160. parameters[unknownHeaderDescription.Index] = unknownHeaders.ToArray(unknownHeaderDescription.TypedHeader ? typeof(MessageHeader<XmlElement>) : typeof(XmlElement));
  161. }
  162. return;
  163. }
  164. MemoryStream memoryStream = new MemoryStream();
  165. XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream);
  166. message.WriteStartEnvelope(bufferWriter);
  167. message.WriteStartHeaders(bufferWriter);
  168. MessageHeaderOfTHelper messageHeaderOfTHelper = null;
  169. for (int headerIndex = 0; headerIndex < headers.Count; headerIndex++)
  170. {
  171. MessageHeaderInfo header = headers[headerIndex];
  172. XmlDictionaryReader headerReader = headers.GetReaderAtHeader(headerIndex);
  173. MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(header.Name, header.Namespace);
  174. if (matchingHeaderDescription != null)
  175. {
  176. if (header.MustUnderstand)
  177. headers.UnderstoodHeaders.Add(header);
  178. if (matchingHeaderDescription.TypedHeader)
  179. {
  180. if (messageHeaderOfTHelper == null)
  181. messageHeaderOfTHelper = new MessageHeaderOfTHelper(parameters.Length);
  182. messageHeaderOfTHelper.SetHeaderAttributes(matchingHeaderDescription, header.MustUnderstand, header.Relay, header.Actor);
  183. }
  184. }
  185. if (matchingHeaderDescription == null && unknownHeaderDescription != null)
  186. AddUnknownHeader(unknownHeaderDescription, unknownHeaders, xmlDoc, bufferWriter, header, headerReader);
  187. else
  188. bufferWriter.WriteNode(headerReader, false);
  189. headerReader.Close();
  190. }
  191. bufferWriter.WriteEndElement();
  192. bufferWriter.WriteEndElement();
  193. bufferWriter.Flush();
  194. /*
  195. XmlDocument doc = new XmlDocument();
  196. memoryStream.Position = 0;
  197. doc.Load(memoryStream);
  198. doc.Save(Console.Out);
  199. */
  200. memoryStream.Position = 0;
  201. XmlDictionaryReader bufferReader = XmlDictionaryReader.CreateTextReader(memoryStream.GetBuffer(), 0, (int)memoryStream.Length, XmlDictionaryReaderQuotas.Max);
  202. bufferReader.ReadStartElement();
  203. bufferReader.MoveToContent();
  204. if (!bufferReader.IsEmptyElement)
  205. {
  206. bufferReader.ReadStartElement();
  207. object[] headerValues = (object[])serializer.Deserialize(bufferReader, isEncoded ? GetEncoding(message.Version.Envelope) : null);
  208. int headerIndex = 0;
  209. foreach (MessageHeaderDescription headerDescription in messageDescription.Headers)
  210. {
  211. if (!headerDescription.IsUnknownHeaderCollection)
  212. {
  213. object parameterValue = headerValues[headerIndex++];
  214. if (headerDescription.TypedHeader && parameterValue != null)
  215. parameterValue = messageHeaderOfTHelper.CreateMessageHeader(headerDescription, parameterValue);
  216. parameters[headerDescription.Index] = parameterValue;
  217. }
  218. }
  219. bufferReader.Close();
  220. }
  221. if (unknownHeaderDescription != null)
  222. parameters[unknownHeaderDescription.Index] = unknownHeaders.ToArray(unknownHeaderDescription.TypedHeader ? typeof(MessageHeader<XmlElement>) : typeof(XmlElement));
  223. }
  224. catch (InvalidOperationException e)
  225. {
  226. // all exceptions from XmlSerializer get wrapped in InvalidOperationException,
  227. // so we must be conservative and never turn this into a fault
  228. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
  229. SR.GetString(SR.SFxErrorDeserializingHeader, messageDescription.MessageName), e));
  230. }
  231. }
  232. private static void AddUnknownHeader(MessageHeaderDescription unknownHeaderDescription, ArrayList unknownHeaders, XmlDocument xmlDoc, XmlDictionaryWriter bufferWriter, MessageHeaderInfo header, XmlDictionaryReader headerReader)
  233. {
  234. object unknownHeader = xmlDoc.ReadNode(headerReader);
  235. if (bufferWriter != null)
  236. ((XmlElement)unknownHeader).WriteTo(bufferWriter);
  237. if (unknownHeader != null && unknownHeaderDescription.TypedHeader)
  238. unknownHeader = TypedHeaderManager.Create(unknownHeaderDescription.Type, unknownHeader, header.MustUnderstand, header.Relay, header.Actor);
  239. unknownHeaders.Add(unknownHeader);
  240. }
  241. protected override void WriteBodyAttributes(XmlDictionaryWriter writer, MessageVersion version)
  242. {
  243. if (isEncoded && version.Envelope == EnvelopeVersion.Soap11)
  244. {
  245. string encoding = GetEncoding(version.Envelope);
  246. writer.WriteAttributeString("encodingStyle", version.Envelope.Namespace, encoding);
  247. }
  248. writer.WriteAttributeString("xmlns", "xsi", null, XmlSchema.InstanceNamespace);
  249. writer.WriteAttributeString("xmlns", "xsd", null, XmlSchema.Namespace);
  250. }
  251. protected override void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, string action, MessageDescription messageDescription, object returnValue, object[] parameters, bool isRequest)
  252. {
  253. if (writer == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
  254. if (parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
  255. try
  256. {
  257. MessageInfo messageInfo;
  258. if (isRequest)
  259. messageInfo = requestMessageInfo;
  260. else
  261. messageInfo = replyMessageInfo;
  262. if (messageInfo.RpcEncodedTypedMessageBodyParts == null)
  263. {
  264. SerializeBody(writer, version, messageInfo.BodySerializer, messageDescription.Body.ReturnValue, messageDescription.Body.Parts, returnValue, parameters);
  265. return;
  266. }
  267. object[] bodyPartValues = new object[messageInfo.RpcEncodedTypedMessageBodyParts.Count];
  268. object bodyObject = parameters[messageDescription.Body.Parts[0].Index];
  269. if (bodyObject == null)
  270. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxBodyCannotBeNull, messageDescription.MessageName)));
  271. int i = 0;
  272. foreach (MessagePartDescription bodyPart in messageInfo.RpcEncodedTypedMessageBodyParts)
  273. {
  274. MemberInfo member = bodyPart.MemberInfo;
  275. FieldInfo field = member as FieldInfo;
  276. if (field != null)
  277. bodyPartValues[i++] = field.GetValue(bodyObject);
  278. else
  279. {
  280. PropertyInfo property = member as PropertyInfo;
  281. if (property != null)
  282. bodyPartValues[i++] = property.GetValue(bodyObject, null);
  283. }
  284. }
  285. SerializeBody(writer, version, messageInfo.BodySerializer, null/*returnPart*/, messageInfo.RpcEncodedTypedMessageBodyParts, null/*returnValue*/, bodyPartValues);
  286. }
  287. catch (InvalidOperationException e)
  288. {
  289. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
  290. SR.GetString(SR.SFxErrorSerializingBody, messageDescription.MessageName, e.Message), e));
  291. }
  292. }
  293. void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, object returnValue, object[] parameters)
  294. {
  295. if (serializer == null)
  296. {
  297. return;
  298. }
  299. bool hasReturnValue = IsValidReturnValue(returnPart);
  300. object[] bodyParameters = new object[bodyParts.Count + (hasReturnValue ? 1 : 0)];
  301. int paramIndex = 0;
  302. if (hasReturnValue)
  303. bodyParameters[paramIndex++] = returnValue;
  304. for (int i = 0; i < bodyParts.Count; i++)
  305. bodyParameters[paramIndex++] = parameters[bodyParts[i].Index];
  306. string encoding = isEncoded ? GetEncoding(version.Envelope) : null;
  307. serializer.Serialize(writer, bodyParameters, null, encoding);
  308. }
  309. protected override object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, string action, MessageDescription messageDescription, object[] parameters, bool isRequest)
  310. {
  311. MessageInfo messageInfo;
  312. if (isRequest)
  313. messageInfo = requestMessageInfo;
  314. else
  315. messageInfo = replyMessageInfo;
  316. if (messageInfo.RpcEncodedTypedMessageBodyParts == null)
  317. return DeserializeBody(reader, version, messageInfo.BodySerializer, messageDescription.Body.ReturnValue, messageDescription.Body.Parts, parameters, isRequest);
  318. object[] bodyPartValues = new object[messageInfo.RpcEncodedTypedMessageBodyParts.Count];
  319. DeserializeBody(reader, version, messageInfo.BodySerializer, null/*returnPart*/, messageInfo.RpcEncodedTypedMessageBodyParts, bodyPartValues, isRequest);
  320. object bodyObject = Activator.CreateInstance(messageDescription.Body.Parts[0].Type);
  321. int i = 0;
  322. foreach (MessagePartDescription bodyPart in messageInfo.RpcEncodedTypedMessageBodyParts)
  323. {
  324. MemberInfo member = bodyPart.MemberInfo;
  325. FieldInfo field = member as FieldInfo;
  326. if (field != null)
  327. field.SetValue(bodyObject, bodyPartValues[i++]);
  328. else
  329. {
  330. PropertyInfo property = member as PropertyInfo;
  331. if (property != null)
  332. property.SetValue(bodyObject, bodyPartValues[i++], null);
  333. }
  334. }
  335. parameters[messageDescription.Body.Parts[0].Index] = bodyObject;
  336. return null;
  337. }
  338. object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, object[] parameters, bool isRequest)
  339. {
  340. try
  341. {
  342. if (reader == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("reader"));
  343. if (parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
  344. object returnValue = null;
  345. if (serializer == null)
  346. {
  347. return null;
  348. }
  349. if (reader.NodeType == XmlNodeType.EndElement)
  350. return null;
  351. object[] bodyParameters = (object[])serializer.Deserialize(reader, isEncoded ? GetEncoding(version.Envelope) : null);
  352. int paramIndex = 0;
  353. if (IsValidReturnValue(returnPart))
  354. returnValue = bodyParameters[paramIndex++];
  355. for (int i = 0; i < bodyParts.Count; i++)
  356. parameters[bodyParts[i].Index] = bodyParameters[paramIndex++];
  357. return returnValue;
  358. }
  359. catch (InvalidOperationException e)
  360. {
  361. // all exceptions from XmlSerializer get wrapped in InvalidOperationException,
  362. // so we must be conservative and never turn this into a fault
  363. string resourceKey = isRequest ? SR.SFxErrorDeserializingRequestBody : SR.SFxErrorDeserializingReplyBody;
  364. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
  365. SR.GetString(resourceKey, OperationName), e));
  366. }
  367. }
  368. internal static string GetEncoding(EnvelopeVersion version)
  369. {
  370. if (version == EnvelopeVersion.Soap11)
  371. {
  372. return soap11Encoding;
  373. }
  374. else if (version == EnvelopeVersion.Soap12)
  375. {
  376. return soap12Encoding;
  377. }
  378. else
  379. {
  380. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("version",
  381. SR.GetString(SR.EnvelopeVersionNotSupported, version));
  382. }
  383. }
  384. internal abstract class MessageInfo
  385. {
  386. internal abstract XmlSerializer BodySerializer { get; }
  387. internal abstract XmlSerializer HeaderSerializer { get; }
  388. internal abstract MessageHeaderDescriptionTable HeaderDescriptionTable { get; }
  389. internal abstract MessageHeaderDescription UnknownHeaderDescription { get; }
  390. internal abstract MessagePartDescriptionCollection RpcEncodedTypedMessageBodyParts { get; }
  391. }
  392. class MessageHeaderOfTHelper
  393. {
  394. object[] attributes;
  395. internal MessageHeaderOfTHelper(int parameterCount)
  396. {
  397. attributes = new object[parameterCount];
  398. }
  399. internal object GetContentAndSaveHeaderAttributes(object parameterValue, MessageHeaderDescription headerDescription)
  400. {
  401. if (parameterValue == null)
  402. return null;
  403. bool mustUnderstand;
  404. bool relay;
  405. string actor;
  406. if (headerDescription.Multiple)
  407. {
  408. object[] messageHeaderOfTArray = (object[])parameterValue;
  409. MessageHeader<object>[] messageHeaderOfTAttributes = new MessageHeader<object>[messageHeaderOfTArray.Length];
  410. Array tArray = Array.CreateInstance(headerDescription.Type, messageHeaderOfTArray.Length);
  411. for (int i = 0; i < tArray.Length; i++)
  412. {
  413. tArray.SetValue(GetContentOfMessageHeaderOfT(headerDescription, messageHeaderOfTArray[i], out mustUnderstand, out relay, out actor), i);
  414. messageHeaderOfTAttributes[i] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
  415. }
  416. attributes[headerDescription.Index] = messageHeaderOfTAttributes;
  417. return tArray;
  418. }
  419. else
  420. {
  421. object content = GetContentOfMessageHeaderOfT(headerDescription, parameterValue, out mustUnderstand, out relay, out actor);
  422. attributes[headerDescription.Index] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
  423. return content;
  424. }
  425. }
  426. internal void GetHeaderAttributes(MessageHeaderDescription headerDescription, out bool mustUnderstand, out bool relay, out string actor)
  427. {
  428. MessageHeader<object> matchingMessageHeaderOfTAttribute = null;
  429. if (headerDescription.Multiple)
  430. {
  431. MessageHeader<object>[] messageHeaderOfTAttributes = (MessageHeader<object>[])attributes[headerDescription.Index];
  432. for (int i = 0; i < messageHeaderOfTAttributes.Length; i++)
  433. {
  434. if (messageHeaderOfTAttributes[i] != null)
  435. {
  436. matchingMessageHeaderOfTAttribute = messageHeaderOfTAttributes[i];
  437. messageHeaderOfTAttributes[i] = null;
  438. break;
  439. }
  440. }
  441. //assert(matchingMessageHeaderOfTAttribute != null);
  442. }
  443. else
  444. matchingMessageHeaderOfTAttribute = (MessageHeader<object>)attributes[headerDescription.Index];
  445. mustUnderstand = matchingMessageHeaderOfTAttribute.MustUnderstand;
  446. relay = matchingMessageHeaderOfTAttribute.Relay;
  447. actor = matchingMessageHeaderOfTAttribute.Actor;
  448. }
  449. internal void SetHeaderAttributes(MessageHeaderDescription headerDescription, bool mustUnderstand, bool relay, string actor)
  450. {
  451. if (headerDescription.Multiple)
  452. {
  453. if (attributes[headerDescription.Index] == null)
  454. attributes[headerDescription.Index] = new List<MessageHeader<object>>();
  455. ((List<MessageHeader<object>>)attributes[headerDescription.Index]).Add(new MessageHeader<object>(null, mustUnderstand, actor, relay));
  456. }
  457. else
  458. attributes[headerDescription.Index] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
  459. }
  460. internal object CreateMessageHeader(MessageHeaderDescription headerDescription, object headerValue)
  461. {
  462. if (headerDescription.Multiple)
  463. {
  464. IList<MessageHeader<object>> messageHeaderOfTAttributes = (IList<MessageHeader<object>>)attributes[headerDescription.Index];
  465. object[] messageHeaderOfTArray = (object[])Array.CreateInstance(TypedHeaderManager.GetMessageHeaderType(headerDescription.Type), messageHeaderOfTAttributes.Count);
  466. Array headerValues = (Array)headerValue;
  467. for (int i = 0; i < messageHeaderOfTArray.Length; i++)
  468. {
  469. MessageHeader<object> messageHeaderOfTAttribute = messageHeaderOfTAttributes[i];
  470. messageHeaderOfTArray[i] = TypedHeaderManager.Create(headerDescription.Type, headerValues.GetValue(i),
  471. messageHeaderOfTAttribute.MustUnderstand, messageHeaderOfTAttribute.Relay, messageHeaderOfTAttribute.Actor);
  472. }
  473. return messageHeaderOfTArray;
  474. }
  475. else
  476. {
  477. MessageHeader<object> messageHeaderOfTAttribute = (MessageHeader<object>)attributes[headerDescription.Index];
  478. return TypedHeaderManager.Create(headerDescription.Type, headerValue,
  479. messageHeaderOfTAttribute.MustUnderstand, messageHeaderOfTAttribute.Relay, messageHeaderOfTAttribute.Actor);
  480. }
  481. }
  482. }
  483. }
  484. }