ServiceDebugBehavior.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Description
  5. {
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.ComponentModel;
  10. using System.Diagnostics;
  11. using System.Runtime.Diagnostics;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Diagnostics;
  14. using System.ServiceModel.Dispatcher;
  15. public class ServiceDebugBehavior : IServiceBehavior
  16. {
  17. bool includeExceptionDetailInFaults = false;
  18. bool httpHelpPageEnabled = true;
  19. Uri httpHelpPageUrl;
  20. bool httpsHelpPageEnabled = true;
  21. Uri httpsHelpPageUrl;
  22. Binding httpHelpPageBinding;
  23. Binding httpsHelpPageBinding;
  24. [DefaultValue(true)]
  25. public bool HttpHelpPageEnabled
  26. {
  27. get { return this.httpHelpPageEnabled; }
  28. set { this.httpHelpPageEnabled = value; }
  29. }
  30. [DefaultValue(null)]
  31. [TypeConverter(typeof(UriTypeConverter))]
  32. public Uri HttpHelpPageUrl
  33. {
  34. get { return this.httpHelpPageUrl; }
  35. set
  36. {
  37. if (value != null && value.IsAbsoluteUri && value.Scheme != Uri.UriSchemeHttp)
  38. {
  39. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxServiceMetadataBehaviorUrlMustBeHttpOrRelative,
  40. "HttpHelpPageUrl", Uri.UriSchemeHttp, value.ToString(), value.Scheme));
  41. }
  42. this.httpHelpPageUrl = value;
  43. }
  44. }
  45. [DefaultValue(true)]
  46. public bool HttpsHelpPageEnabled
  47. {
  48. get { return this.httpsHelpPageEnabled; }
  49. set { this.httpsHelpPageEnabled = value; }
  50. }
  51. [DefaultValue(null)]
  52. [TypeConverter(typeof(UriTypeConverter))]
  53. public Uri HttpsHelpPageUrl
  54. {
  55. get { return this.httpsHelpPageUrl; }
  56. set
  57. {
  58. if (value != null && value.IsAbsoluteUri && value.Scheme != Uri.UriSchemeHttps)
  59. {
  60. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxServiceMetadataBehaviorUrlMustBeHttpOrRelative,
  61. "HttpsHelpPageUrl", Uri.UriSchemeHttps, value.ToString(), value.Scheme));
  62. }
  63. this.httpsHelpPageUrl = value;
  64. }
  65. }
  66. public Binding HttpHelpPageBinding
  67. {
  68. get { return this.httpHelpPageBinding; }
  69. set
  70. {
  71. if (value != null)
  72. {
  73. if (!value.Scheme.Equals(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
  74. {
  75. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxBindingSchemeDoesNotMatch,
  76. value.Scheme, value.GetType().ToString(), Uri.UriSchemeHttp));
  77. }
  78. CustomBinding customBinding = new CustomBinding(value);
  79. TextMessageEncodingBindingElement textMessageEncodingBindingElement = customBinding.Elements.Find<TextMessageEncodingBindingElement>();
  80. if (textMessageEncodingBindingElement != null && !textMessageEncodingBindingElement.MessageVersion.IsMatch(MessageVersion.None))
  81. {
  82. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxIncorrectMessageVersion,
  83. textMessageEncodingBindingElement.MessageVersion.ToString(), MessageVersion.None.ToString()));
  84. }
  85. HttpTransportBindingElement httpTransportBindingElement = customBinding.Elements.Find<HttpTransportBindingElement>();
  86. if (httpTransportBindingElement != null)
  87. {
  88. httpTransportBindingElement.Method = "GET";
  89. }
  90. this.httpHelpPageBinding = customBinding;
  91. }
  92. }
  93. }
  94. public Binding HttpsHelpPageBinding
  95. {
  96. get { return this.httpsHelpPageBinding; }
  97. set
  98. {
  99. if (value != null)
  100. {
  101. if (!value.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
  102. {
  103. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxBindingSchemeDoesNotMatch,
  104. value.Scheme, value.GetType().ToString(), Uri.UriSchemeHttps));
  105. }
  106. CustomBinding customBinding = new CustomBinding(value);
  107. TextMessageEncodingBindingElement textMessageEncodingBindingElement = customBinding.Elements.Find<TextMessageEncodingBindingElement>();
  108. if (textMessageEncodingBindingElement != null && !textMessageEncodingBindingElement.MessageVersion.IsMatch(MessageVersion.None))
  109. {
  110. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxIncorrectMessageVersion,
  111. textMessageEncodingBindingElement.MessageVersion.ToString(), MessageVersion.None.ToString()));
  112. }
  113. HttpsTransportBindingElement httpsTransportBindingElement = customBinding.Elements.Find<HttpsTransportBindingElement>();
  114. if (httpsTransportBindingElement != null)
  115. {
  116. httpsTransportBindingElement.Method = "GET";
  117. }
  118. this.httpsHelpPageBinding = customBinding;
  119. }
  120. }
  121. }
  122. [DefaultValue(false)]
  123. public bool IncludeExceptionDetailInFaults
  124. {
  125. get { return this.includeExceptionDetailInFaults; }
  126. set { this.includeExceptionDetailInFaults = value; }
  127. }
  128. void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
  129. {
  130. }
  131. void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
  132. {
  133. if (parameters == null)
  134. {
  135. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameters");
  136. }
  137. ServiceDebugBehavior param = parameters.Find<ServiceDebugBehavior>();
  138. if (param == null)
  139. {
  140. parameters.Add(this);
  141. }
  142. }
  143. void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
  144. {
  145. if (this.includeExceptionDetailInFaults)
  146. {
  147. for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
  148. {
  149. ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
  150. if (channelDispatcher != null)
  151. {
  152. channelDispatcher.IncludeExceptionDetailInFaults = true;
  153. }
  154. }
  155. }
  156. if (!(this.httpHelpPageEnabled || this.httpsHelpPageEnabled))
  157. return;
  158. ServiceMetadataExtension mex = ServiceMetadataExtension.EnsureServiceMetadataExtension(description, serviceHostBase);
  159. SetExtensionProperties(mex, serviceHostBase);
  160. CreateHelpPageEndpoints(description, serviceHostBase, mex);
  161. }
  162. private void SetExtensionProperties(ServiceMetadataExtension mex, ServiceHostBase host)
  163. {
  164. mex.HttpHelpPageEnabled = this.httpHelpPageEnabled;
  165. mex.HttpHelpPageUrl = host.GetVia(Uri.UriSchemeHttp, this.httpHelpPageUrl == null ? new Uri(string.Empty, UriKind.Relative) : this.httpHelpPageUrl);
  166. mex.HttpHelpPageBinding = this.HttpHelpPageBinding;
  167. mex.HttpsHelpPageEnabled = this.httpsHelpPageEnabled;
  168. mex.HttpsHelpPageUrl = host.GetVia(Uri.UriSchemeHttps, this.httpsHelpPageUrl == null ? new Uri(string.Empty, UriKind.Relative) : this.httpsHelpPageUrl);
  169. mex.HttpsHelpPageBinding = this.HttpsHelpPageBinding;
  170. }
  171. bool EnsureHelpPageDispatcher(ServiceHostBase host, ServiceMetadataExtension mex, Uri url, string scheme)
  172. {
  173. Uri address = host.GetVia(scheme, url == null ? new Uri(string.Empty, UriKind.Relative) : url);
  174. if (address == null)
  175. {
  176. return false;
  177. }
  178. ChannelDispatcher channelDispatcher = mex.EnsureGetDispatcher(address, true /* isServiceDebugBehavior */);
  179. ((ServiceMetadataExtension.HttpGetImpl)channelDispatcher.Endpoints[0].DispatchRuntime.SingletonInstanceContext.UserObject).HelpPageEnabled = true;
  180. return true;
  181. }
  182. void CreateHelpPageEndpoints(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
  183. {
  184. if (this.httpHelpPageEnabled)
  185. {
  186. if (!EnsureHelpPageDispatcher(host, mex, this.httpHelpPageUrl, Uri.UriSchemeHttp))
  187. {
  188. TraceWarning(this.httpHelpPageUrl, "ServiceDebugBehaviorHttpHelpPageUrl", "ServiceDebugBehaviorHttpHelpPageEnabled");
  189. }
  190. }
  191. if (this.httpsHelpPageEnabled)
  192. {
  193. if (!EnsureHelpPageDispatcher(host, mex, this.httpsHelpPageUrl, Uri.UriSchemeHttps))
  194. {
  195. TraceWarning(this.httpHelpPageUrl, "ServiceDebugBehaviorHttpsHelpPageUrl", "ServiceDebugBehaviorHttpsHelpPageEnabled");
  196. }
  197. }
  198. }
  199. static void TraceWarning(Uri address, string urlProperty, string enabledProperty)
  200. {
  201. if (DiagnosticUtility.ShouldTraceInformation)
  202. {
  203. Hashtable h = new Hashtable(2)
  204. {
  205. { enabledProperty, "true" },
  206. { urlProperty, (address == null) ? string.Empty : address.ToString() }
  207. };
  208. TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.WarnHelpPageEnabledNoBaseAddress,
  209. SR.GetString(SR.TraceCodeWarnHelpPageEnabledNoBaseAddress), new DictionaryTraceRecord(h), null, null);
  210. }
  211. }
  212. }
  213. }