NopCommerce开源项目中很基础但是很实用的C# Helper方法
NopCommerce是啥?
nopCommerce是最好的开源电子商务购物 系统。nopCommerce免费提供。今天,它是最好和最流行的ASP.NET电子商务软件。它已被下载超过180万次!
nopCommerce是一个完全可定制的购物系统。它稳定且高度可用。nopCommerce是一个开源的电子商务解决方案,它是基于MS SQL 2008(或更高版本)后端数据库的ASP.NET(MVC)。我们易于使用的购物车解决方案特别适合已经超过现有系统的商家,并可能与您当前的网站托管商或我们的托管合作伙伴一起托管。它拥有开始通过互联网销售物理和数字产品所需的一切。
以上解释引用自该项目的Github :https://github.com/nopSolutions/nopCommerce
因为这几天没无法静心学习该项目的架构,所有只拎出该项目的CommonHelper.cs来谈谈。
1.E-Mail校验
#region Fieldsprivate static readonly Regex _emailRegex;//we use EmailValidator from FluentValidation. So let's keep them sync - https://github.com/JeremySkinner/FluentValidation/blob/master/src/FluentValidation/Validators/EmailValidator.csprivate const string _emailExpression = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-||_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+([a-z]+|\d|-|\.{0,1}|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])?([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$";#endregion#region Methods/// <summary>/// 检查Email(是否为空,是否超长,格式是否规范)/// </summary>/// <param name="email">The email.</param>/// <returns></returns>public static string EnsureSubscriberEmailOrThrow(string email){var output = EnsureNotNull(email);output = output.Trim();output = EnsureMaximumLength(output, 255);if (!IsValidEmail(output)){throw new NopException("Email is not valid.");}return output;}/// <summary>/// 用正则表达式校验Email/// </summary>/// <param name="email">Email to verify</param>/// <returns>true if the string is a valid e-mail address and false if it's not</returns>public static bool IsValidEmail(string email){if (string.IsNullOrEmpty(email))return false;email = email.Trim();return _emailRegex.IsMatch(email);}
这个E-mial校验的方法基本是可以直接拿过来用的,校验的正则表达式也很全面,需要用的时候可以过来copy。
2.ip地址校验
/// <summary>/// 检查该字符串是否是可用的Ip地址/// </summary>/// <param name="ipAddress">IPAddress to verify</param>/// <returns>true if the string is a valid IpAddress and false if it's not</returns>public static bool IsValidIpAddress(string ipAddress){return IPAddress.TryParse(ipAddress, out IPAddress _);}
直接使用了系统自带的IPAddress.TryParse方法,很多小伙伴还不知道吧!
3.产生指定长度的随机数字字符串
/// <summary>/// 产生一个指定长度的随机数据字符串/// </summary>/// <param name="length">Length</param>/// <returns>Result string</returns>public static string GenerateRandomDigitCode(int length){var random = new Random();var str = string.Empty;for (var i = 0; i < length; i++)str = string.Concat(str, random.Next(10).ToString());return str;}
这里的话,其实我觉得用stringbuild比直接用string更好一点,尤其是当length比较长的时候,可能用stringbuild效率更高一些。
4.产生一个随机数字
/// <summary>/// 产生一个随机数/// </summary>/// <param name="min">Minimum number</param>/// <param name="max">Maximum number</param>/// <returns>Result</returns>public static int GenerateRandomInteger(int min = 0, int max = int.MaxValue){var randomNumberBuffer = new byte[10];new RNGCryptoServiceProvider().GetBytes(randomNumberBuffer);return new Random(BitConverter.ToInt32(randomNumberBuffer, 0)).Next(min, max);}
当时不懂Random工作原理的时候,觉得这个方法简直是脱裤子放P,多此一举,搞得这么麻烦干嘛! 直接Random().Next(min,max)不就产生了一个指定范围的随机数吗?干嘛搞得这么复杂呢?
原来,Random是需要一个随机数作为“种子”的,当这个种子相同时,那么产生的随机数也是相同的,有同学肯定会说,我们平时用的时候没有指定“种子”数据,也能产生我想要的随机数啊! 其实,当我们没有指定“种子”的时候,Random时默认以当前时间作为种子的,当高并发访问的情况下,如果使用时间作为种子数据,这显然就很有可能产生相同的随机数,这显然就不那么“随机”了,所以该方法看似多余的方法都只是为了利用RNGCryptoServiceProvider().GetBytes()产生一个足够随机的byte[],然后再把该byte[]转换成数字,那么该数字就能基本不会重复了,也就是”种子”不重复,所以随机数也不会重复了。
5.检查两个数组是否相等
/// <summary>/// 检查两个数组是否相等/// </summary>/// <typeparam name="T">Type</typeparam>/// <param name="a1">Array 1</param>/// <param name="a2">Array 2</param>/// <returns>Result</returns>public static bool ArraysEqual<T>(T[] a1, T[] a2){//also see Enumerable.SequenceEqual(a1, a2);if (ReferenceEquals(a1, a2))return true;if (a1 == null || a2 == null)return false;if (a1.Length != a2.Length)return false;var comparer = EqualityComparer<T>.Default;for (var i = 0; i < a1.Length; i++){if (!comparer.Equals(a1[i], a2[i])) return false;}return true;}
搜先检测地址引用是否相同,如果相同,肯定时同一个对象,那么相等,然后是检测时否为空….. 代码很简单,就不一一说了,我们比较的时候,容易遗忘一些条件,直接走到了for循环最后一步,其实,不到迫不得已,没不要for循环。
6.给对象的指定属性赋值
/// <summary>///给对象的指定属性赋值/// </summary>/// <param name="instance">The object whose property to set.</param>/// <param name="propertyName">The name of the property to set.</param>/// <param name="value">The value to set the property to.</param>public static void SetProperty(object instance, string propertyName, object value){if (instance == null) throw new ArgumentNullException(nameof(instance));if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));var instanceType = instance.GetType();var pi = instanceType.GetProperty(propertyName);if (pi == null)throw new NopException("No property '{0}' found on the instance of type '{1}'.", propertyName, instanceType);if (!pi.CanWrite)throw new NopException("The property '{0}' on the instance of type '{1}' does not have a setter.", propertyName, instanceType);if (value != null && !value.GetType().IsAssignableFrom(pi.PropertyType))value = To(value, pi.PropertyType);pi.SetValue(instance, value, new object[0]);}
我也是第一次知道,居然还能这么玩。
7.将一个值转换成目标类型
/// <summary>/// 将一个值转换成目标类型。/// </summary>/// <param name="value">The value to convert.</param>/// <param name="destinationType">The type to convert the value to.</param>/// <returns>The converted value.</returns>public static object To(object value, Type destinationType){return To(value, destinationType, CultureInfo.InvariantCulture);}/// <summary>/// 将一个值转换成目标类型./// </summary>/// <param name="value">The value to convert.</param>/// <param name="destinationType">The type to convert the value to.</param>/// <param name="culture">Culture</param>/// <returns>The converted value.</returns>public static object To(object value, Type destinationType, CultureInfo culture){if (value != null){var sourceType = value.GetType();var destinationConverter = TypeDescriptor.GetConverter(destinationType);if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType()))return destinationConverter.ConvertFrom(null, culture, value);var sourceConverter = TypeDescriptor.GetConverter(sourceType);if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType))return sourceConverter.ConvertTo(null, culture, value, destinationType);if (destinationType.IsEnum && value is int)return Enum.ToObject(destinationType, (int)value);if (!destinationType.IsInstanceOfType(value))return Convert.ChangeType(value, destinationType, culture);}return value;}/// <summary>/// 将一个值转换成目标类型/// </summary>/// <param name="value">The value to convert.</param>/// <typeparam name="T">The type to convert the value to.</typeparam>/// <returns>The converted value.</returns>public static T To<T>(object value){//return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);return (T)To(value, typeof(T));}
有了这个方法,我们就不用傻傻想着用Convent….到底Convernt点什么呢?哈哈,直接To<T>(),是不是很帅?
8.删除目录
/// <summary>/// 深度优先的递归删除/// </summary>/// <param name="path">Directory path</param>public static void DeleteDirectory(string path){if (string.IsNullOrEmpty(path))throw new ArgumentNullException(path);//find more info about directory deletion//and why we use this approach at https://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-trueforeach (var directory in Directory.GetDirectories(path)){DeleteDirectory(directory);}try{Directory.Delete(path, true);}catch (IOException){Directory.Delete(path, true);}catch (UnauthorizedAccessException){Directory.Delete(path, true);}}
一开始,我也不明白为什么要弄得这么复杂,要删除目录,直接Directory.Delete(path)就好了不是吗? 其实不是的,如果目录不为空,会报System.IO.IOException: The directory is not empty.的错误的,所以要递归,层层删除,据说Win系统的资源管理器,删除目录,其实就是这个逻辑实现的。
9.获取两个Datetime之间的年份间隔
/// <summary>/// 获取两个时间之间相差的年份/// </summary>/// <param name="startDate"></param>/// <param name="endDate"></param>/// <returns></returns>public static int GetDifferenceInYears(DateTime startDate, DateTime endDate){//source: http://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-in-c//this assumes you are looking for the western idea of age and not using East Asian reckoning.var age = endDate.Year - startDate.Year;if (startDate > endDate.AddYears(-age))age--;return age;}
对,如果endDate.Year - startDate.Year是不对的,就好像你是去年的8月份出生的,而现在才五月份,那么你现在还不能称为1岁一样的道理。同样的方法还可以用来获取月、日、时、分、秒的间隔。
10 虚拟路径转物理路径
/// <summary>/// 映射虚拟路径到物理路径/// </summary>/// <param name="path">The path to map. E.g. "~/bin"</param>/// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>public static string MapPath(string path){path = path.Replace("~/", "").TrimStart('/').Replace('/', '\\');
CommonHelper.BaseDirectory = hostingEnvironment.ContentRootPath;
return Path.Combine(BaseDirectory ?? string.Empty, path);}
大致就是这么多,可能以上方法大家都知道,但是自己写出来可能不够巧妙(老江湖除外),记录下来,希望对大家有所帮助,也用于自我加深映像。
有兴趣的可以去github上下载nopcommerce的源码来看看。
转:https://www.cnblogs.com/CoderAyu/p/8982842.html
NopCommerce开源项目中很基础但是很实用的C# Helper方法相关推荐
- 开源项目中经常出现的七种错误
启动一个新的开源项目可能会遇到一些困难.也许你脑子里有一个很棒的想法,但是想把它们变成富有成效的.健康的.吸引人的社区还需要做很多工作.令人叹息的是,相同的错误总是被无代价的重复,出现低级错误是团队中 ...
- 如何充分利用开源项目_5个技巧:在开源项目中利用以用户为中心的设计
如何充分利用开源项目 当我刚开始在开放技术学院 (OTI)工作时,我始终受到以下问题的挑战:"为什么UX设计师为什么要在开源组织工作?" 在我看来,事实是几乎所有设计和可用性工作本 ...
- 前端大型开源项目_在大型开源项目中管理问题
前端大型开源项目 We're honored by the amount of positive feedback we get from folks using Flutter. As one of ...
- 我们在开源项目中是怎样埋彩蛋的
今天的 AntDesign 圣诞节彩蛋事件确实炸开了锅,加彩蛋的初衷是好的,只是这次玩过了火. 在开源软件中,加彩蛋是一种乐趣,并不为奇,同为知名 UI 组件库的 iView 项目,也经常在 文档 中 ...
- 如何参与到GitHub开源项目中
最近一年开源项目特别的热,很多技术大会或论坛都以开源项目作为主题进行探讨,可见这是一种趋势.而Github作为开源项目的著名托管地,可谓无人不知,越来越多的个人和公司纷纷加入到Github的大家族里来 ...
- 喜报丨京东科技主导的开源项目ShardingSphere荣登报告榜单国人主导开源项目中活跃度第五名!...
1月19日,开源社发布<2020 中国开源年度报告>.在报告中,ShardingSphere荣登所有国人主导开源项目中活跃度第五名,作为 Apache 软件基金会下属的国人主导的开源项目中 ...
- 从15000个Python开源项目中精选的Top30,Github平均star为3707,赶紧收藏!
翻译 | AI科技大本营(ID:rgznai100) 参与 | SuiSui 继推出2017年机器学习开源项目Top 30榜单后,Mybridge AI又推出了一个Python开源项目Top 30榜单 ...
- 收藏!15000个Python开源项目中精选Top30!
来源:授权自AI科技大本营(ID:rgznai100) 本文长度为1700字,建议阅读6分钟 本文基于项目质量.用户参与度以及其他因素为你列出Python开源项目Top 30,建议收藏. 继推出201 ...
- 15000个开源项目中挑选Top 12
15000个开源项目中挑选Top 12,第一就是-- 2018-01-17
最新文章
- 程序员锁死服务器致公司倒闭当事人逐条反驳:这锅我不背
- MySQL存储过程中的3种循环
- ASP.NET的錯誤類型及錯誤處理方式
- 一道面试题:遇到大规模Oracle坏块该怎么处理?
- asp手机拍照显示_设备 | UNIJET募资约6600万元,用于大尺寸显示领域的新一代喷墨打印技术...
- C#利用Process关闭所有的IE窗口
- spring源码-bean加载整体流程
- 慕课软件质量保证与测试(第二章.课后作业)
- 华为光猫HG8120C的一些配置文件
- iOS HealthKit
- 炫酷又实用的发送邮箱链接修改密码
- DeeCamp2022正式开营!李开复、张亚勤亲授大师课 | 创新事
- java开发必备基础
- htts 及 tomcat ssl配置
- Leetcode 309. Best Time to Buy and Sell Stock with Cooldown
- 用Mouse_event()来模拟鼠标操作
- 雀巢近260款畅销产品集体亮相第三届进博会
- Unity3d如何实现四格漫画动态播放
- 如何杀掉“熊猫烧香”
- STM32F103学习笔记(1)掌握GPIO操作—输出模式(推挽/开漏)
热门文章
- OpenCV YOLO DNN(yolo_object_detection)
- Qt Creator自定义构建过程
- Qt Creator将应用程序部署到Android设备
- Qt Creator使用CVS
- C++以字符串形式返回第N个斐波那契的算法(附完整源码)
- QT的QSGGeometry类的使用
- QT的QDesignerCustomWidgetInterface类的使用
- 「SLAM」十四讲:第1讲 预备知识
- pytroch 数据增量 transforms的二十二个方法
- 04_Pytorch生态、PyTorch能做什么、PyTorch之Autograd、autograd案例、GPU加速案例