PageRenderTime 69ms CodeModel.GetById 18ms RepoModel.GetById 2ms app.codeStats 0ms

/Utils/Helper.cs

https://github.com/noblethrasher/arc-reaction
C# | 426 lines | 320 code | 103 blank | 3 comment | 47 complexity | 12b472b6d4717b13ec909316f0029fc8 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Web;
  7. using System.Xml.Linq;
  8. namespace ArcReaction
  9. {
  10. public class ModelError : Exception, IEnumerable<ValidationError>
  11. {
  12. IEnumerable<ValidationError> errors;
  13. private ModelError(IEnumerable<ValidationError> errors) : base(string.Join("\r\n", errors))
  14. {
  15. this.errors = errors;
  16. }
  17. public static implicit operator ModelError(ModelState model)
  18. {
  19. if (model)
  20. return new ModelError(model);
  21. else
  22. return null;
  23. }
  24. public IEnumerator<ValidationError> GetEnumerator()
  25. {
  26. return errors.GetEnumerator();
  27. }
  28. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  29. {
  30. return GetEnumerator();
  31. }
  32. }
  33. public abstract class ValidationError
  34. {
  35. public abstract override string ToString();
  36. }
  37. /// <summary>
  38. /// The purpose of the ModelState type is to guard against and track errors that result from converting a set of user inputs (strings) into a set of strongly typed model attributes.
  39. /// </summary>
  40. public sealed class ModelState : IEnumerable<ValidationError>
  41. {
  42. bool is_valid = true;
  43. [ThreadStatic]
  44. static Stack<ModelError> errors;
  45. static ModelState()
  46. {
  47. errors = new Stack<ModelError>();
  48. }
  49. static Stack<ModelError> EnsureModelErrorObject()
  50. {
  51. return (errors = errors ?? new Stack<ModelError>());
  52. }
  53. public static void AddError(ModelError error)
  54. {
  55. if (error != null)
  56. {
  57. EnsureModelErrorObject().Push(error);
  58. }
  59. }
  60. public static void ClearErrors()
  61. {
  62. EnsureModelErrorObject().Clear();
  63. }
  64. public static ModelError GetLastError()
  65. {
  66. if (EnsureModelErrorObject().Any())
  67. return errors.Pop();
  68. else
  69. return null;
  70. }
  71. List<ValidationError> validation_errors = new List<ValidationError>();
  72. public void AddError(ValidationError error)
  73. {
  74. is_valid = false;
  75. validation_errors.Add(error);
  76. }
  77. public static bool operator true(ModelState model)
  78. {
  79. return !object.ReferenceEquals(null, model) && model.is_valid;
  80. }
  81. public static bool operator false(ModelState model)
  82. {
  83. return object.ReferenceEquals(null, model) || !model.is_valid;
  84. }
  85. public static implicit operator bool(ModelState model)
  86. {
  87. return !object.ReferenceEquals(null, model) && model.is_valid;
  88. }
  89. public IEnumerator<ValidationError> GetEnumerator()
  90. {
  91. return validation_errors.GetEnumerator();
  92. }
  93. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  94. {
  95. return GetEnumerator();
  96. }
  97. }
  98. public abstract class HttpFieldValidationError : ValidationError
  99. {
  100. readonly string key;
  101. readonly string message;
  102. public HttpFieldValidationError(string key, string message)
  103. {
  104. this.key = key;
  105. this.message = message;
  106. }
  107. public override string ToString()
  108. {
  109. return message + " " + key;
  110. }
  111. }
  112. public static class Utils
  113. {
  114. sealed class NullValueError : HttpFieldValidationError
  115. {
  116. public NullValueError(string key) : base(key, "FIELD CANNOT BE NULL") { }
  117. }
  118. sealed class InvalidIntegerFormatError : HttpFieldValidationError
  119. {
  120. public InvalidIntegerFormatError(string key) : base(key, "INVALID STRING FORMAT FOR INTEGER") { }
  121. }
  122. sealed class InvalidBooleanFormatError : HttpFieldValidationError
  123. {
  124. public InvalidBooleanFormatError(string key) : base(key, "INVALID STRING FORMAT FOR BOOLEAN") { }
  125. }
  126. sealed class InvalidDateTimeFormatError : HttpFieldValidationError
  127. {
  128. public InvalidDateTimeFormatError(string key) : base(key, "INVALID STRING FORMAT FOR DATETIME") { }
  129. }
  130. public static string GetNonEmptyString(this HttpContextEx context, string key, ref ModelState state)
  131. {
  132. var s = context.Request.Form[key];
  133. if (s == null || s.Length == 0)
  134. state.AddError(new NullValueError(key));
  135. return s;
  136. }
  137. public static int GetInt32(this HttpContextEx context, string key, ref ModelState state)
  138. {
  139. int n = 0;
  140. string s = null;
  141. if (!int.TryParse(s = context.Request.Form[key], out n))
  142. state.AddError(s == null ? (HttpFieldValidationError) new NullValueError(key) : new InvalidIntegerFormatError(key));
  143. return n;
  144. }
  145. public static byte GetByte(this HttpContextEx context, string key, ref ModelState state)
  146. {
  147. byte n = 0;
  148. string s = null;
  149. if (!byte.TryParse(s = context.Request.Form[key], out n))
  150. state.AddError(s == null ? (HttpFieldValidationError)new NullValueError(key) : new InvalidIntegerFormatError(key));
  151. return n;
  152. }
  153. public static byte? MaybeGetByte(this HttpContextEx context, string key)
  154. {
  155. byte n;
  156. if (byte.TryParse(key, out n))
  157. return n;
  158. else
  159. return null;
  160. }
  161. public static Int16? MaybeGetInt16(this HttpContextEx context, string key)
  162. {
  163. Int16 n;
  164. if (Int16.TryParse(key, out n))
  165. return n;
  166. else
  167. return null;
  168. }
  169. public static int? MaybeGetInt32(this HttpContextEx context, string key)
  170. {
  171. int n;
  172. if (int.TryParse(key, out n))
  173. return n;
  174. else
  175. return null;
  176. }
  177. public static DateTime GetDateTime(this HttpContextEx context, string key, ref ModelState state)
  178. {
  179. DateTime n;
  180. string s = null;
  181. if (!DateTime.TryParse(s = context.Request.Form[key], out n))
  182. state.AddError(s == null ? (HttpFieldValidationError)new NullValueError(key) : new InvalidDateTimeFormatError(key));
  183. return n;
  184. }
  185. public static DateTime? MaybeGetDateTime(this HttpContextEx context, string key)
  186. {
  187. DateTime n;
  188. if (DateTime.TryParse(context.Request.Form[key], out n))
  189. return n;
  190. else
  191. return null;
  192. }
  193. public static bool GetBoolean(this HttpContextEx context, string key, ref ModelState state)
  194. {
  195. bool b = default(bool);
  196. string s = null;
  197. if (!bool.TryParse(s = context.Request.Form[key], out b))
  198. state.AddError(s == null ? (HttpFieldValidationError) new NullValueError(key) : new InvalidBooleanFormatError(key));
  199. return b;
  200. }
  201. public static string GetString(this HttpContextEx context, string key, ref ModelState state)
  202. {
  203. var s = context.Request.Form[key];
  204. if (s == null)
  205. state.AddError(new NullValueError(key));
  206. return s;
  207. }
  208. public static string MaybeGetString(this HttpContextEx context, string key)
  209. {
  210. var s = context.Request.Form[key];
  211. return s;
  212. }
  213. public static XDocument GetXML(this HttpContextEx context, string key, ref ModelState model)
  214. {
  215. var s = context.Request.Form[key];
  216. if (s == null)
  217. {
  218. model.AddError(new NullValueError(key));
  219. return null;
  220. }
  221. return XDocument.Parse(s);
  222. }
  223. public struct ParseAttemptResult<T>
  224. {
  225. bool success;
  226. public T value;
  227. public ParseAttemptResult(T obj, bool success)
  228. {
  229. this.value = obj;
  230. this.success = success;
  231. }
  232. public static bool operator true(ParseAttemptResult<T> x)
  233. {
  234. return x.success;
  235. }
  236. public static bool operator false(ParseAttemptResult<T> x)
  237. {
  238. return !x.success;
  239. }
  240. }
  241. public static IEnumerable<T> Get<T>(this HttpContextEx context, string key, Func<string, ParseAttemptResult<T>> typeMap = null)
  242. {
  243. if (typeMap != null)
  244. {
  245. var ys = new List<T>();
  246. var val = context.Request.Form[key];
  247. if (val == null)
  248. return ys;
  249. foreach (var x in val.Split(','))
  250. {
  251. var result = typeMap(x);
  252. if (result)
  253. ys.Add(result.value);
  254. }
  255. return ys;
  256. }
  257. else
  258. {
  259. if (typeof(T) == typeof(string))
  260. {
  261. return context.Request.Form.GetValues(key) as IEnumerable<T>;
  262. }
  263. if (typeof(T) == typeof(int))
  264. {
  265. return (IEnumerable<T>)context.Get(key, s =>
  266. {
  267. int n;
  268. var b = int.TryParse(s, out n);
  269. return new ParseAttemptResult<int>(n, b);
  270. });
  271. }
  272. if (typeof(T) == typeof(bool))
  273. {
  274. return (IEnumerable<T>)context.Get(key, s =>
  275. {
  276. bool n;
  277. var b = bool.TryParse(s, out n);
  278. return new ParseAttemptResult<bool>(n, b);
  279. });
  280. }
  281. if (typeof(T) == typeof(byte))
  282. {
  283. return (IEnumerable<T>)context.Get(key, s =>
  284. {
  285. byte n;
  286. var b = byte.TryParse(s, out n);
  287. return new ParseAttemptResult<byte>(n, b);
  288. });
  289. }
  290. if (typeof(T) == typeof(DateTime))
  291. {
  292. return (IEnumerable<T>)context.Get(key, s =>
  293. {
  294. DateTime n;
  295. var b = DateTime.TryParse(s, out n);
  296. return new ParseAttemptResult<DateTime>(n, b);
  297. });
  298. }
  299. if (typeof(T) == typeof(Guid))
  300. {
  301. return (IEnumerable<T>)context.Get(key, s =>
  302. {
  303. Guid n;
  304. var b = Guid.TryParse(s, out n);
  305. return new ParseAttemptResult<Guid>(n, b);
  306. });
  307. }
  308. throw new ArgumentException("Unable to convert string to " + typeof(T).FullName);
  309. }
  310. }
  311. public static string ToBase64String(this string s)
  312. {
  313. var b64 = Convert.ToBase64String(Encoding.UTF32.GetBytes(s)).ToCharArray();
  314. for (var i = 0; i < b64.Length; i++)
  315. {
  316. var c = b64[i];
  317. if (c == '=')
  318. b64[i] = '-';
  319. }
  320. return new string(b64);
  321. }
  322. }
  323. }