TransactionFlowProperty.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.ServiceModel;
  9. using System.ServiceModel.Security;
  10. using System.Transactions;
  11. using System.Runtime.Remoting.Messaging;
  12. using System.ServiceModel.Transactions;
  13. using System.ServiceModel.Diagnostics;
  14. sealed public class TransactionMessageProperty
  15. {
  16. TransactionInfo flowedTransactionInfo;
  17. Transaction flowedTransaction;
  18. const string PropertyName = "TransactionMessageProperty";
  19. private TransactionMessageProperty()
  20. {
  21. }
  22. public Transaction Transaction
  23. {
  24. get
  25. {
  26. if (this.flowedTransaction == null && this.flowedTransactionInfo != null)
  27. {
  28. try
  29. {
  30. this.flowedTransaction = this.flowedTransactionInfo.UnmarshalTransaction();
  31. }
  32. catch (TransactionException e)
  33. {
  34. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
  35. }
  36. }
  37. return this.flowedTransaction;
  38. }
  39. }
  40. static internal TransactionMessageProperty TryGet(Message message)
  41. {
  42. if (message.Properties.ContainsKey(PropertyName))
  43. return message.Properties[PropertyName] as TransactionMessageProperty;
  44. else
  45. return null;
  46. }
  47. static internal Transaction TryGetTransaction(Message message)
  48. {
  49. if (!message.Properties.ContainsKey(PropertyName))
  50. return null;
  51. return ((TransactionMessageProperty)message.Properties[PropertyName]).Transaction;
  52. }
  53. static TransactionMessageProperty GetPropertyAndThrowIfAlreadySet(Message message)
  54. {
  55. if (message.Properties.ContainsKey(PropertyName))
  56. {
  57. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
  58. new FaultException(SR.GetString(SR.SFxTryAddMultipleTransactionsOnMessage)));
  59. }
  60. return new TransactionMessageProperty();
  61. }
  62. static public void Set(Transaction transaction, Message message)
  63. {
  64. TransactionMessageProperty property = GetPropertyAndThrowIfAlreadySet(message);
  65. property.flowedTransaction = transaction;
  66. message.Properties.Add(PropertyName, property);
  67. }
  68. static internal void Set(TransactionInfo transactionInfo, Message message)
  69. {
  70. TransactionMessageProperty property = GetPropertyAndThrowIfAlreadySet(message);
  71. property.flowedTransactionInfo = transactionInfo;
  72. message.Properties.Add(PropertyName, property);
  73. }
  74. }
  75. class TransactionFlowProperty
  76. {
  77. Transaction flowedTransaction;
  78. List<RequestSecurityTokenResponse> issuedTokens;
  79. const string PropertyName = "TransactionFlowProperty";
  80. private TransactionFlowProperty()
  81. {
  82. }
  83. internal ICollection<RequestSecurityTokenResponse> IssuedTokens
  84. {
  85. get
  86. {
  87. if (this.issuedTokens == null)
  88. {
  89. this.issuedTokens = new List<RequestSecurityTokenResponse>();
  90. }
  91. return this.issuedTokens;
  92. }
  93. }
  94. internal Transaction Transaction
  95. {
  96. get { return this.flowedTransaction; }
  97. }
  98. static internal TransactionFlowProperty Ensure(Message message)
  99. {
  100. if (message.Properties.ContainsKey(PropertyName))
  101. return (TransactionFlowProperty)message.Properties[PropertyName];
  102. TransactionFlowProperty property = new TransactionFlowProperty();
  103. message.Properties.Add(PropertyName, property);
  104. return property;
  105. }
  106. static internal TransactionFlowProperty TryGet(Message message)
  107. {
  108. if (message.Properties.ContainsKey(PropertyName))
  109. return message.Properties[PropertyName] as TransactionFlowProperty;
  110. else
  111. return null;
  112. }
  113. static internal ICollection<RequestSecurityTokenResponse> TryGetIssuedTokens(Message message)
  114. {
  115. TransactionFlowProperty property = TransactionFlowProperty.TryGet(message);
  116. if (property == null)
  117. return null;
  118. // use this when reading only, consistently return null if no tokens.
  119. if (property.issuedTokens == null || property.issuedTokens.Count == 0)
  120. return null;
  121. return property.issuedTokens;
  122. }
  123. static internal Transaction TryGetTransaction(Message message)
  124. {
  125. if (!message.Properties.ContainsKey(PropertyName))
  126. return null;
  127. return ((TransactionFlowProperty)message.Properties[PropertyName]).Transaction;
  128. }
  129. static TransactionFlowProperty GetPropertyAndThrowIfAlreadySet(Message message)
  130. {
  131. TransactionFlowProperty property = TryGet(message);
  132. if (property != null)
  133. {
  134. if (property.flowedTransaction != null)
  135. {
  136. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FaultException(SR.GetString(SR.SFxTryAddMultipleTransactionsOnMessage)));
  137. }
  138. }
  139. else
  140. {
  141. property = new TransactionFlowProperty();
  142. }
  143. return property;
  144. }
  145. static internal void Set(Transaction transaction, Message message)
  146. {
  147. TransactionFlowProperty property = GetPropertyAndThrowIfAlreadySet(message);
  148. property.flowedTransaction = transaction;
  149. message.Properties.Add(PropertyName, property);
  150. }
  151. }
  152. }