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

转载于:https://www.cnblogs.com/soundcode/p/8986878.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

写一个函数,输入int型,返回整数逆序后的字符串

2019独角兽企业重金招聘Python工程师标准>>> 刚刚看到一个面试题&#xff1a;写一个函数&#xff0c;输入int型&#xff0c;返回整数逆序后的字符串。如&#xff1a;输入123&#xff0c;返回“321”。 要求必须用递归&#xff0c;不能用全局变量&#xff0c;输入必须…

VS2013 使用QCustomPlot等三方库如何配置

QCustomPlot 是一个小巧好用的 QT 图表插件。用来画曲线图、趋势图、坐标图、柱状图等类似二维图的库。实现大部分的2维图形绘制。使用时&#xff0c;我们在程序中写完相关调用的代码后&#xff0c;只需将 QCunstomPlot.cpp 和 QCustomPlot.h 两个文件加入工程&#xff0c;正常…

Php RSS

RSS 聚合最近非常流行&#xff0c;因此至少对 RSS 及其工作方式有所了解是一名 PHP 开发人员的迫切需要。本文介绍了 RSS 基础知识、RSS 众多用途中的一些用途、如何使用 PHP 从数据库创建 RSS 提要&#xff0c;以及如何使用 XML_RSS 模块读取现有 RSS 提要并将其转换为 HTML。…

分布式配置管理平台Disconf

2019独角兽企业重金招聘Python工程师标准>>> 摘要 为了更好的解决分布式环境下多台服务实例的配置统一管理问题&#xff0c;本文提出了一套完整的分布式配置管理解决方案&#xff08;简称为disconf[4]&#xff0c;下同&#xff09;。首先&#xff0c;实现了同构系统…

1.ELF之Elf Header

1.ELF的三个文件头 每个ELF文件有三个文件头&#xff0c;用来索引信息。 (1).EH ELF file Header 可在此读到PH&#xff0c;SH在文件中的offset。 (2).PH Program Header 与load program有关的索引&#xff0c;.o的PH为空。 (3).SH Section Header 组成此文件的所有secti…

java路径1.7_Java环境配置原理详解1.Jdk安装目录文件说明:一般jdk安装目录及路径 Javajdk1.7.0_79lib,里面主要包含以下文件夹。bin...

Java环境配置原理详解1.Jdk安装目录文件说明&#xff1a;一般jdk安装目录及路径 Javajdk1.7.0_79lib&#xff0c;里面主要包含以下文件夹。bin&#xff1a;主要存放的是java工具中常用命令如&#xff1a;java&#xff0c;javac等。db&#xff1a;安装java db的路径。include&am…

2018年5月5日论文阅读

国外精读&#xff01;title&#xff08;27&#xff09;&#xff1a;We don’t need no bounding-boxes: Training object class detectors using only human verification&#xff08;我们不需要任何边界框&#xff1a;只使用人工验证来训练对象类别检测器&#xff09;---20170…

sql2005主从数据库同步配置

网站规模到了一定程度之后&#xff0c;该分的也分了&#xff0c;该优化的也做了优化&#xff0c;但是还是不能满足业务上对性能的要求&#xff1b;这时候我们可以考虑使用主从库。主从库是两台服务器上的两个数据库&#xff0c;主库以最快的速度做增删改操作最新数据的查询操作…

InceptionV2----Batch Normalization层

一、BN层的操作 1.BN层的操作位置&#xff1a;在非线性映射之前&#xff0c;目的是为了减少梯度消失和梯度爆炸。 1.对输入的x做归一化 2.增加2个参数&#xff0c;提高模型表达能力 3.理想情况下E和Var应该是针对整个数据集的&#xff0c;但显然这是不现实的。因此&#xff0c;…

前端技术之_CSS详解第五天

前端技术之_CSS详解第五天 一、行高和字号 1.1 行高 CSS中&#xff0c;所有的行&#xff0c;都有行高。盒模型的padding&#xff0c;绝对不是直接作用在文字上的&#xff0c;而是作用在“行”上的。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu…

pxe装机dhcp获取不到_关于PXE服务器环境搭建流程中遇到的问题及解决方法

环境准备中遇到的问题首先需要将系统镜像挂载到 /mnt&#xff1a;#mount /dev/sdd2 /mnt/usb_disk 将U盘挂载#cp rhel-server-7.6-x86_64-dvd.iso /home 系统镜像拷到本地#mount -o loop rhel-server-7.6-x86_64-dvd.iso /mnt问题&#xff1a;ifconfig命令未找到解决&#xff1…

一小时包教会 —— webpack 入门指南

什么是 webpack&#xff1f; webpack是近期最火的一款模块加载器兼打包工具&#xff0c;它能把各种资源&#xff0c;例如JS&#xff08;含JSX&#xff09;、coffee、样式&#xff08;含less/sass&#xff09;、图片等都作为模块来使用和处理。 我们可以直接使用 require(XXX) 的…

java 简单图片浏览器_Java实现简单的图片浏览器

第一次写博客&#xff0c;不喜勿喷。最近一个小师弟问我怎么用Java做图片浏览器&#xff0c;感觉好久没玩Java了&#xff0c;就自己动手做了一下。学校的教程是用Swing来做界面的&#xff0c;所以这里也用这个来讲。首先要做个大概的界面出来&#xff0c;eclipse有一个很好用的…

60. Spring Boot写后感【从零开始学Spring Boot】

从2016年4月15日到2016年7月20日经历长达3个月的时间&#xff0c;【从零开始学习Spring Boot】系列就要告一段落了。国内的各种资源都比较乱或者是copy 来copy去的&#xff0c;错了也不加以修正下&#xff0c;导致通过百度找到的资源可能都是错误的&#xff0c;正是由于这么一种…

五角星

import turtle turtle.setup(600,400,0,0) turtle.bgcolor(red) turtle.color(yellow) turtle.fillcolor(yellow) turtle.begin_fill() for i in range(5):turtle.forward(200)turtle.right(144) turtle.end_fill()turtle.done()转载于:https://www.cnblogs.com/Paris-YY/p/900…

java customerservlet_顾客管理系统java+servlet

首先我先搭好网页的框架先写一个登陆的html&#xff0c;名字是login.html1)在js中跳转页面的方法&#xff0c;我这里用的是get提交&#xff0c;只传递了一个name。function mylogin() {var usernamedocument.getElementById("name").value;window.location.href"…

mysql给root开启远程访问权限,修改root密码

1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问. 这对于 Web-Server 与 MySql-Server 都在同一台服务器上的网站架构来说是没有问题的. 但随着网站流量的增加, 后期服务器架构可能会将 Web-Server 与 MySql-Server 分别放在独立的服务器上, 以便得…

Qt_Window@Qt Command Prompt从命令行创建工程

#include <QApplication> #include <QLabel>int main(int argc, char *argv[]) {QApplication app(argc, argv);QLabel *label new QLabel("Hello Qt!");label->show();return app.exec(); }第1 行和第2 行包含了两个类的定义&#xff1a;QApplicat…

linux中的守护进程

一、守护进程守护进程&#xff0c;也叫精灵进程&#xff08;daemon&#xff09;它和普通后台进程的区别在于以下三点1、守护进程自成会话&#xff0c;而普通后台进程则不一定2、守护进程不受终端的控制3、守护进程就是后台进程&#xff0c;而后台进程不同于守护进程用ps axj命令…

mysql主从复制 lvs+ keepalived

2019独角兽企业重金招聘Python工程师标准>>> 一、环境 Master&#xff08;主机A&#xff09;&#xff1a;192.168.1.1 Slave&#xff08;主机B&#xff09; &#xff1a;192.168.1.2 W-VIP&#xff08;写入&#xff09; &#xff1a;192.168.1.3 R-VIP&#xff…