PageRenderTime 27ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/MVC3ControlsToolkit/Controls/Bindings/ModelTranslator.cs

#
C# | 253 lines | 207 code | 33 blank | 13 comment | 32 complexity | 7dd7b81d53b5581ccc57b324549e55e8 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Francesco Abbruzzese. All rights reserved.
  4. * francesco@dotnet-programming.com
  5. * http://www.dotnet-programming.com/
  6. *
  7. * This software is subject to the the license at http://mvccontrolstoolkit.codeplex.com/license
  8. * and included in the license.txt file of this distribution.
  9. *
  10. * You must not remove this notice, or any other, from this software.
  11. *
  12. * ***************************************************************************/
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Collections;
  16. using System.Linq;
  17. using System.Text;
  18. using MVCControlsToolkit.Core;
  19. using MVCControlsToolkit.Controls;
  20. using System.Web.Script.Serialization;
  21. using System.Reflection;
  22. using System.ComponentModel.DataAnnotations;
  23. using System.Text.RegularExpressions;
  24. using System.Collections.ObjectModel;
  25. using MVCControlsToolkit.DataAnnotations;
  26. using System.Web.Mvc;
  27. namespace MVCControlsToolkit.Controls.Bindings
  28. {
  29. internal class ModelTranslatorBase: IUpdateModelState, IRebindChildren
  30. {
  31. protected string prefix;
  32. protected System.Web.Mvc.ModelStateDictionary modelState;
  33. [AllowHtml]
  34. public string JSonModel { get; set; }
  35. protected void Validate(object x, object father, string propertyName, string currPrefix)
  36. {
  37. if (x == null) return;
  38. if (x is IConvertible)
  39. {
  40. if (father == null) return;
  41. ValidationContext ctx = new ValidationContext(father, null, null);
  42. ctx.MemberName = propertyName;
  43. List<ValidationResult> errors = new List<ValidationResult>();
  44. bool success = Validator.TryValidateProperty(x, ctx, errors);
  45. if (!success)
  46. {
  47. foreach (ValidationResult vs in errors)
  48. {
  49. modelState.AddModelError(currPrefix, vs.ErrorMessage);
  50. }
  51. }
  52. }
  53. else if (x is IEnumerable)
  54. {
  55. int i = 0;
  56. foreach (object y in x as IEnumerable)
  57. {
  58. Validate(y, null, null,
  59. currPrefix +
  60. string.Format("[{0}]", i)
  61. );
  62. i++;
  63. }
  64. }
  65. else
  66. {
  67. Type currType = x.GetType();
  68. if (currType.IsClass)
  69. {
  70. List<ValidationResult> errors = new List<ValidationResult>();
  71. bool success = Validator.TryValidateObject(x, new ValidationContext(x, null, null), errors, true);
  72. ValidationAttribute[] attrs = currType.GetCustomAttributes(typeof(ValidationAttribute), true) as ValidationAttribute[];
  73. foreach (ValidationAttribute attr in attrs)
  74. {
  75. ValidationResult vs = attr.GetValidationResult(x, new ValidationContext(x, null, null));
  76. if (vs != null && vs != ValidationResult.Success)
  77. modelState.AddModelError(currPrefix, vs.ErrorMessage);
  78. }
  79. foreach (PropertyInfo prop in currType.GetProperties())
  80. {
  81. ServerBindAttribute[] goServer = Attribute.GetCustomAttributes(prop, typeof(ServerBindAttribute)) as ServerBindAttribute[];
  82. if (goServer != null && goServer.Length > 0)
  83. {
  84. ModelBindingContext newBindingContext = new ModelBindingContext();
  85. newBindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType((() => null), prop.PropertyType);
  86. newBindingContext.ModelMetadata.IsRequired = false;
  87. newBindingContext.ModelName = BasicHtmlHelper.AddField(currPrefix, prop.Name);
  88. newBindingContext.ModelState = currentBindingContext.ModelState;
  89. newBindingContext.PropertyFilter = currentBindingContext.PropertyFilter;
  90. newBindingContext.ValueProvider = currentBindingContext.ValueProvider;
  91. object model = currBinder.BindModel(currentControllerContext, newBindingContext);
  92. prop.SetValue(x, model, new object[0]);
  93. }
  94. else if ((prop.PropertyType == typeof(DateTime) || prop.PropertyType == typeof(DateTime?)) && prop.CanRead && prop.CanWrite)
  95. {
  96. object dateVal = prop.GetValue(x, new object[0]);
  97. if (dateVal != null)
  98. {
  99. prop.SetValue(x, ((DateTime)dateVal).ToLocalTime(), new object[0]);
  100. }
  101. }
  102. Validate(prop.GetValue(x, new object[0]),
  103. x,
  104. prop.Name,
  105. BasicHtmlHelper.AddField(currPrefix, prop.Name));
  106. }
  107. }
  108. }
  109. }
  110. public void GetCurrState(string currPrefix, int updateIndex, System.Web.Mvc.ModelStateDictionary modelState)
  111. {
  112. if (currPrefix == "display") currPrefix = string.Empty;
  113. this.prefix = currPrefix;
  114. this.modelState = modelState;
  115. }
  116. public bool MoveState
  117. {
  118. get { return false; }
  119. }
  120. private System.Web.Mvc.IModelBinder currBinder;
  121. private System.Web.Mvc.ControllerContext currentControllerContext;
  122. System.Web.Mvc.ModelBindingContext currentBindingContext;
  123. public System.Web.Mvc.ControllerContext CurrentControllerContext
  124. {
  125. set { currentControllerContext = value; }
  126. }
  127. public System.Web.Mvc.ModelBindingContext CurrentBindingContext
  128. {
  129. set { currentBindingContext=value; }
  130. }
  131. public System.Web.Mvc.IModelBinder CurrBinder
  132. {
  133. set { currBinder=value; }
  134. }
  135. }
  136. internal class SipleModelTranslator<T> : ModelTranslatorBase, IDisplayModel
  137. {
  138. public object ExportToModel(Type targetType, params object[] context)
  139. {
  140. if (string.IsNullOrWhiteSpace(JSonModel)) return null;
  141. if (!targetType.IsAssignableFrom(typeof(T)))
  142. throw (new NotSupportedException(string.Format(ControlsResources.NotCompatibleTypes, typeof(T).FullName, targetType.FullName)));
  143. object result = BasicHtmlHelper.ClientDecode(JSonModel, typeof(T));
  144. Validate(result, null, null, prefix);
  145. return result;
  146. }
  147. public void ImportFromModel(object model, params object[] context)
  148. {
  149. JSonModel = BasicHtmlHelper.ClientEncode(model);
  150. }
  151. }
  152. internal class ModelTranslator<T> : ModelTranslatorBase, IDisplayModel
  153. {
  154. private static Regex dateRewrite;
  155. private static Regex dateRewriteOut;
  156. static ModelTranslator()
  157. {
  158. dateRewrite=new Regex("\""+@"\\/Date\(((-)?\d+)(?:[-+]\d+)?\)\\/"+"\"");
  159. dateRewriteOut = new Regex("\"" + @"\\\\/Date\(((-)?\d+)(?:[-+]\d+)?\)\\\\/" + "\"");
  160. }
  161. public object ExportToModel(Type TargetType, params object[] context)
  162. {
  163. if (string.IsNullOrWhiteSpace(JSonModel)) return null;
  164. if (!TargetType.IsAssignableFrom(typeof(T)))
  165. throw (new NotSupportedException(string.Format(ControlsResources.NotCompatibleTypes, typeof(T).FullName, TargetType.FullName)));
  166. JavaScriptSerializer serializer = new JavaScriptSerializer();
  167. //JSonModel = dateRewriteOut.Replace(JSonModel, "\"\\/Date($1)\\/\"");
  168. T result = serializer.Deserialize<T>(JSonModel);
  169. Validate(result, null, null, prefix);
  170. return result;
  171. }
  172. public void ImportFromModel(object model, params object[] context)
  173. {
  174. JavaScriptSerializer serializer = new JavaScriptSerializer();
  175. JSonModel = serializer.Serialize(model) ;
  176. JSonModel = dateRewrite.Replace(JSonModel, "new Date($1)");
  177. }
  178. }
  179. internal class JSONAdapter : ModelTranslatorBase, IDisplayModel
  180. {
  181. private static Regex dateRewrite;
  182. private static Regex dateRewriteOut;
  183. static JSONAdapter()
  184. {
  185. dateRewrite = new Regex("\"" + @"\\/Date\(((-)?\d+)(?:[-+]\d+)?\)\\/" + "\"");
  186. dateRewriteOut = new Regex("\"" + @"\\\\/Date\(((-)?\d+)(?:[-+]\d+)?\)\\\\/" + "\"");
  187. }
  188. public object ExportToModel(Type TargetType, params object[] context)
  189. {
  190. if (string.IsNullOrWhiteSpace(JSonModel)) return null;
  191. JavaScriptSerializer serializer = new JavaScriptSerializer();
  192. JSonModel = dateRewriteOut.Replace(JSonModel, "\"\\/Date($1)\\/\"");
  193. object result = serializer.Deserialize(JSonModel, TargetType);
  194. Validate(result, null, null, prefix);
  195. return result;
  196. }
  197. public void ImportFromModel(object model, params object[] context)
  198. {
  199. JavaScriptSerializer serializer = new JavaScriptSerializer();
  200. JSonModel = serializer.Serialize(model);
  201. JSonModel = dateRewrite.Replace(JSonModel, "new Date($1)");
  202. }
  203. }
  204. internal class ModelTranslatorLight : IDisplayModel
  205. {
  206. static ModelTranslatorLight()
  207. {
  208. }
  209. [AllowHtml]
  210. public string JSonModel { get; set; }
  211. public object ExportToModel(Type targetType, params object[] context)
  212. {
  213. return BasicHtmlHelper.ClientDecode(JSonModel, targetType);
  214. }
  215. public void ImportFromModel(object model, params object[] context)
  216. {
  217. JSonModel = BasicHtmlHelper.ClientEncode(model);
  218. }
  219. }
  220. }