PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/System.Web.Http/Metadata/Providers/CachedDataAnnotationsModelMetadata.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 267 lines | 208 code | 35 blank | 24 comment | 45 complexity | a19830717456fe1e38ad9d9b5266dc3b MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Security;
  6. using System.Web.Http.Internal;
  7. using System.Web.Http.Properties;
  8. namespace System.Web.Http.Metadata.Providers
  9. {
  10. // REVIEW: No access to HiddenInputAttribute
  11. public class CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes>
  12. {
  13. public CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
  14. : base(prototype, modelAccessor)
  15. {
  16. }
  17. public CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType, string propertyName, IEnumerable<Attribute> attributes)
  18. : base(provider, containerType, modelType, propertyName, new CachedDataAnnotationsMetadataAttributes(attributes.ToArray()))
  19. {
  20. }
  21. // [SecuritySafeCritical] because it uses DataAnnotations type
  22. [SecuritySafeCritical]
  23. protected override bool ComputeConvertEmptyStringToNull()
  24. {
  25. return PrototypeCache.DisplayFormat != null
  26. ? PrototypeCache.DisplayFormat.ConvertEmptyStringToNull
  27. : base.ComputeConvertEmptyStringToNull();
  28. }
  29. // [SecuritySafeCritical] because it uses DataAnnotations type
  30. [SecuritySafeCritical]
  31. protected override string ComputeDataTypeName()
  32. {
  33. if (PrototypeCache.DataType != null)
  34. {
  35. return PrototypeCache.DataType.ToDataTypeName();
  36. }
  37. if (PrototypeCache.DisplayFormat != null && !PrototypeCache.DisplayFormat.HtmlEncode)
  38. {
  39. return DataTypeUtil.HtmlTypeName;
  40. }
  41. return base.ComputeDataTypeName();
  42. }
  43. // [SecuritySafeCritical] because it uses DataAnnotations type
  44. [SecuritySafeCritical]
  45. protected override string ComputeDescription()
  46. {
  47. return PrototypeCache.Display != null
  48. ? PrototypeCache.Display.GetDescription()
  49. : base.ComputeDescription();
  50. }
  51. // [SecuritySafeCritical] because it uses DataAnnotations type
  52. [SecuritySafeCritical]
  53. protected override string ComputeDisplayFormatString()
  54. {
  55. return PrototypeCache.DisplayFormat != null
  56. ? PrototypeCache.DisplayFormat.DataFormatString
  57. : base.ComputeDisplayFormatString();
  58. }
  59. // [SecuritySafeCritical] because it uses DataAnnotations type
  60. [SecuritySafeCritical]
  61. protected override string ComputeDisplayName()
  62. {
  63. string result = null;
  64. if (PrototypeCache.Display != null)
  65. {
  66. result = PrototypeCache.Display.GetName();
  67. }
  68. if (result == null && PrototypeCache.DisplayName != null)
  69. {
  70. result = PrototypeCache.DisplayName.DisplayName;
  71. }
  72. return result ?? base.ComputeDisplayName();
  73. }
  74. // [SecuritySafeCritical] because it uses DataAnnotations type
  75. [SecuritySafeCritical]
  76. protected override string ComputeEditFormatString()
  77. {
  78. if (PrototypeCache.DisplayFormat != null && PrototypeCache.DisplayFormat.ApplyFormatInEditMode)
  79. {
  80. return PrototypeCache.DisplayFormat.DataFormatString;
  81. }
  82. return base.ComputeEditFormatString();
  83. }
  84. protected override bool ComputeHideSurroundingHtml()
  85. {
  86. return /*PrototypeCache.HiddenInput != null
  87. ? !PrototypeCache.HiddenInput.DisplayValue
  88. :*/ base.ComputeHideSurroundingHtml();
  89. }
  90. // [SecuritySafeCritical] because it uses DataAnnotations type EditableAttribute
  91. [SecuritySafeCritical]
  92. protected override bool ComputeIsReadOnly()
  93. {
  94. if (PrototypeCache.Editable != null)
  95. {
  96. return !PrototypeCache.Editable.AllowEdit;
  97. }
  98. if (PrototypeCache.ReadOnly != null)
  99. {
  100. return PrototypeCache.ReadOnly.IsReadOnly;
  101. }
  102. return base.ComputeIsReadOnly();
  103. }
  104. // [SecuritySafeCritical] because it uses DataAnnotations type RequiredAttribute
  105. [SecuritySafeCritical]
  106. protected override bool ComputeIsRequired()
  107. {
  108. return PrototypeCache.Required != null
  109. ? true
  110. : base.ComputeIsRequired();
  111. }
  112. // [SecuritySafeCritical] because it uses DataAnnotations type DisplayFormatAttribute
  113. [SecuritySafeCritical]
  114. protected override string ComputeNullDisplayText()
  115. {
  116. return PrototypeCache.DisplayFormat != null
  117. ? PrototypeCache.DisplayFormat.NullDisplayText
  118. : base.ComputeNullDisplayText();
  119. }
  120. // [SecuritySafeCritical] because it uses DataAnnotations type OrderAttribute
  121. [SecuritySafeCritical]
  122. protected override int ComputeOrder()
  123. {
  124. int? result = null;
  125. if (PrototypeCache.Display != null)
  126. {
  127. result = PrototypeCache.Display.GetOrder();
  128. }
  129. return result ?? base.ComputeOrder();
  130. }
  131. // [SecuritySafeCritical] because it uses DataAnnotations type DisplayAttribute
  132. [SecuritySafeCritical]
  133. protected override string ComputeShortDisplayName()
  134. {
  135. return PrototypeCache.Display != null
  136. ? PrototypeCache.Display.GetShortName()
  137. : base.ComputeShortDisplayName();
  138. }
  139. // [SecuritySafeCritical] because it uses DataAnnotations type ScaffoldColumnAttribute
  140. [SecuritySafeCritical]
  141. protected override bool ComputeShowForDisplay()
  142. {
  143. return PrototypeCache.ScaffoldColumn != null
  144. ? PrototypeCache.ScaffoldColumn.Scaffold
  145. : base.ComputeShowForDisplay();
  146. }
  147. // [SecuritySafeCritical] because it uses DataAnnotations type ScaffoldColumnAttribute
  148. [SecuritySafeCritical]
  149. protected override bool ComputeShowForEdit()
  150. {
  151. return PrototypeCache.ScaffoldColumn != null
  152. ? PrototypeCache.ScaffoldColumn.Scaffold
  153. : base.ComputeShowForEdit();
  154. }
  155. // [SecuritySafeCritical] because it uses DataAnnotations type DisplayColumnAttribute
  156. [SecuritySafeCritical]
  157. protected override string ComputeSimpleDisplayText()
  158. {
  159. if (Model != null)
  160. {
  161. if (PrototypeCache.DisplayColumn != null && !String.IsNullOrEmpty(PrototypeCache.DisplayColumn.DisplayColumn))
  162. {
  163. PropertyInfo displayColumnProperty = GetPropertyInfoViaReflection(PrototypeCache.DisplayColumn.DisplayColumn);
  164. ValidateDisplayColumnAttribute(PrototypeCache.DisplayColumn, displayColumnProperty, ModelType);
  165. string simpleDisplayTextValue;
  166. if (TryGetPropertyValueAsStringViaReflection(displayColumnProperty, out simpleDisplayTextValue))
  167. {
  168. return simpleDisplayTextValue;
  169. }
  170. }
  171. }
  172. return base.ComputeSimpleDisplayText();
  173. }
  174. // [SecuritySafeCritical] because it uses DataAnnotations type UIHintAttribute
  175. [SecuritySafeCritical]
  176. protected override string ComputeTemplateHint()
  177. {
  178. if (PrototypeCache.UIHint != null)
  179. {
  180. return PrototypeCache.UIHint.UIHint;
  181. }
  182. #if false
  183. if (PrototypeCache.HiddenInput != null)
  184. {
  185. return "HiddenInput";
  186. }
  187. #endif
  188. return base.ComputeTemplateHint();
  189. }
  190. // [SecuritySafeCritical] because it uses DataAnnotations type DisplayAttribute
  191. [SecuritySafeCritical]
  192. protected override string ComputeWatermark()
  193. {
  194. return PrototypeCache.Display != null
  195. ? PrototypeCache.Display.GetPrompt()
  196. : base.ComputeWatermark();
  197. }
  198. // [SecuritySafeCritical] because it uses DataAnnotations type DisplayColumnAttribute
  199. [SecuritySafeCritical]
  200. private static void ValidateDisplayColumnAttribute(DisplayColumnAttribute displayColumnAttribute, PropertyInfo displayColumnProperty, Type modelType)
  201. {
  202. if (displayColumnProperty == null)
  203. {
  204. throw Error.InvalidOperation(SRResources.DataAnnotationsModelMetadataProvider_UnknownProperty, modelType, displayColumnAttribute.DisplayColumn);
  205. }
  206. if (displayColumnProperty.GetGetMethod() == null)
  207. {
  208. throw Error.InvalidOperation(SRResources.DataAnnotationsModelMetadataProvider_UnreadableProperty, modelType, displayColumnAttribute.DisplayColumn);
  209. }
  210. }
  211. // This method is [SecurityTransparent] and is used only so that we don't call Reflection from
  212. // a [SecuritySafeCritical] method. Reflection works differently when called from [SecurityTransparent].
  213. private PropertyInfo GetPropertyInfoViaReflection(string propertyName)
  214. {
  215. return ModelType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
  216. }
  217. // This method is [SecurityTransparent] and is used only so that we don't call Reflection from
  218. // a [SecuritySafeCritical] method. Reflection works differently when called from [SecurityTransparent].
  219. private bool TryGetPropertyValueAsStringViaReflection(PropertyInfo propertyInfo, out string valueAsString)
  220. {
  221. // PropertyInfo.GetValue() done here to avoid danger of the reflected method call under [SecuritySafeCritical]
  222. object value = propertyInfo.GetValue(Model, new object[0]);
  223. if (value == null)
  224. {
  225. valueAsString = null;
  226. return false;
  227. }
  228. valueAsString = value.ToString();
  229. return true;
  230. }
  231. }
  232. }