PageRenderTime 6159ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/WCFWebApi/src/Microsoft.ApplicationServer.Http/Microsoft/ApplicationServer/Http/Description/HttpOperationDescriptionExtensionMethods.cs

#
C# | 204 lines | 143 code | 32 blank | 29 comment | 38 complexity | bb0dcc5c73d44c9cb14a03e45f10cb75 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, Apache-2.0
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace Microsoft.ApplicationServer.Http.Description
  5. {
  6. using System;
  7. using System.ComponentModel;
  8. using System.Net.Http;
  9. using System.ServiceModel.Description;
  10. using System.ServiceModel.Web;
  11. using System.Text;
  12. using System.Xml;
  13. using Microsoft.Server.Common;
  14. /// <summary>
  15. /// Provides extension methods for <see cref="OperationDescription"/> instances.
  16. /// </summary>
  17. public static class HttpOperationDescriptionExtensionMethods
  18. {
  19. private static readonly Type webGetAttributeType = typeof(WebGetAttribute);
  20. private static readonly Type webInvokeAttributeType = typeof(WebInvokeAttribute);
  21. private static readonly Type descriptionAttributeType = typeof(DescriptionAttribute);
  22. /// <summary>
  23. /// Creates an <see cref="HttpOperationDescription"/> instance based on the given
  24. /// <see cref="OperationDescription"/> instance.
  25. /// </summary>
  26. /// <param name="operation">The <see cref="OperationDescription"/> instance.</param>
  27. /// <returns>A new <see cref="HttpOperationDescription"/> instance.</returns>
  28. public static HttpOperationDescription ToHttpOperationDescription(this OperationDescription operation)
  29. {
  30. if (operation == null)
  31. {
  32. throw Fx.Exception.ArgumentNull("operation");
  33. }
  34. return new HttpOperationDescription(operation);
  35. }
  36. /// <summary>
  37. /// Gets the <see cref="HttpMethod"/> for the given <paramref name="operation"/>.
  38. /// </summary>
  39. /// <param name="operation">The <see cref="HttpOperationDescription"/> instance.</param>
  40. /// <returns>The <see cref="HttpMethod"/>.</returns>
  41. public static HttpMethod GetHttpMethod(this HttpOperationDescription operation)
  42. {
  43. if (operation == null)
  44. {
  45. throw Fx.Exception.ArgumentNull("operation");
  46. }
  47. return new HttpMethod(GetWebMethod(operation));
  48. }
  49. /// <summary>
  50. /// Gets the <see cref="UriTemplate"/> associated with the given <paramref name="operation"/>.
  51. /// </summary>
  52. /// <param name="operation">The <see cref="HttpOperationDescription"/> instance.</param>
  53. /// <returns>The <see cref="UriTemplate"/>.</returns>
  54. public static UriTemplate GetUriTemplate(this HttpOperationDescription operation)
  55. {
  56. // AutoRedirect is default TrailingSlashMode
  57. return GetUriTemplate(operation, TrailingSlashMode.AutoRedirect);
  58. }
  59. /// <summary>
  60. /// Gets the <see cref="UriTemplate"/> associated with the given <paramref name="operation"/>.
  61. /// </summary>
  62. /// <param name="operation">The <see cref="HttpOperationDescription"/> instance.</param>
  63. /// <param name="trailingSlashMode">The <see cref="TrailingSlashMode"/> option to use for the <see cref="UriTemplate"/>.</param>
  64. /// <returns>The <see cref="UriTemplate"/>.</returns>
  65. public static UriTemplate GetUriTemplate(this HttpOperationDescription operation, TrailingSlashMode trailingSlashMode)
  66. {
  67. if (operation == null)
  68. {
  69. throw Fx.Exception.ArgumentNull("operation");
  70. }
  71. TrailingSlashModeHelper.Validate(trailingSlashMode, "trailingSlashMode");
  72. return new UriTemplate(operation.GetUriTemplateStringOrDefault(), trailingSlashMode == TrailingSlashMode.Ignore);
  73. }
  74. internal static string GetDescription(this HttpOperationDescription operation)
  75. {
  76. Fx.Assert(operation != null, "The 'operation' parameter should not be null.");
  77. OperationDescription operationDescription = operation.ToOperationDescription();
  78. object[] attributes = null;
  79. if (operationDescription.SyncMethod != null)
  80. {
  81. attributes = operationDescription.SyncMethod.GetCustomAttributes(descriptionAttributeType, true);
  82. }
  83. else if (operationDescription.BeginMethod != null)
  84. {
  85. attributes = operationDescription.BeginMethod.GetCustomAttributes(descriptionAttributeType, true);
  86. }
  87. if (attributes != null && attributes.Length > 0)
  88. {
  89. return ((DescriptionAttribute)attributes[0]).Description;
  90. }
  91. else
  92. {
  93. return String.Empty;
  94. }
  95. }
  96. private static string GetWebMethod(this HttpOperationDescription operation)
  97. {
  98. Fx.Assert(operation != null, "The 'operation' parameter should not be null.");
  99. WebGetAttribute webGet = operation.Behaviors.Find<WebGetAttribute>();
  100. WebInvokeAttribute webInvoke = operation.Behaviors.Find<WebInvokeAttribute>();
  101. EnsureOneOneWebAttribute(webGet, webInvoke, operation);
  102. if (webGet != null)
  103. {
  104. return HttpMethod.Get.ToString();
  105. }
  106. if (webInvoke == null)
  107. {
  108. return HttpMethod.Post.ToString();
  109. }
  110. return webInvoke.Method ?? HttpMethod.Post.ToString();
  111. }
  112. private static string GetWebUriTemplate(this HttpOperationDescription operation)
  113. {
  114. Fx.Assert(operation != null, "The 'operation' parameter should not be null.");
  115. WebGetAttribute webGet = operation.Behaviors.Find<WebGetAttribute>();
  116. WebInvokeAttribute webInvoke = operation.Behaviors.Find<WebInvokeAttribute>();
  117. EnsureOneOneWebAttribute(webGet, webInvoke, operation);
  118. if (webGet != null)
  119. {
  120. return webGet.UriTemplate;
  121. }
  122. if (webInvoke != null)
  123. {
  124. return webInvoke.UriTemplate;
  125. }
  126. return null;
  127. }
  128. private static string GetUriTemplateStringOrDefault(this HttpOperationDescription operation)
  129. {
  130. Fx.Assert(operation != null, "The 'operation' parameter should not be null.");
  131. string webUriTemplate = GetWebUriTemplate(operation);
  132. if ((webUriTemplate == null) && (GetWebMethod(operation) == HttpMethod.Get.ToString()))
  133. {
  134. webUriTemplate = MakeDefaultGetUriTemplateString(operation);
  135. }
  136. if (webUriTemplate == null)
  137. {
  138. webUriTemplate = operation.Name;
  139. }
  140. return webUriTemplate;
  141. }
  142. private static string MakeDefaultGetUriTemplateString(this HttpOperationDescription operation)
  143. {
  144. Fx.Assert(operation != null, "The 'operation' parameter should not be null.");
  145. StringBuilder builder = new StringBuilder(XmlConvert.DecodeName(operation.Name));
  146. builder.Append("?");
  147. foreach (HttpParameter parameterDescription in operation.InputParameters)
  148. {
  149. string decodedName = XmlConvert.DecodeName(parameterDescription.Name);
  150. builder.Append(decodedName);
  151. builder.Append("={");
  152. builder.Append(decodedName);
  153. builder.Append("}&");
  154. }
  155. builder.Remove(builder.Length - 1, 1);
  156. return builder.ToString();
  157. }
  158. private static void EnsureOneOneWebAttribute(WebGetAttribute webGet, WebInvokeAttribute webInvoke, HttpOperationDescription operation)
  159. {
  160. if (webGet != null && webInvoke != null)
  161. {
  162. throw Fx.Exception.AsError(
  163. new InvalidOperationException(
  164. Http.SR.MultipleWebAttributes(
  165. operation.Name,
  166. operation.DeclaringContract.Name,
  167. webGetAttributeType.Name,
  168. webInvokeAttributeType.Name)));
  169. }
  170. }
  171. }
  172. }