日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

NopCommerce开源项目中很基础但是很实用的C# Helper方法

發(fā)布時(shí)間:2024/9/20 C# 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NopCommerce开源项目中很基础但是很实用的C# Helper方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

NopCommerce是啥?

nopCommerce是最好的開(kāi)源電子商務(wù)購(gòu)物 系統(tǒng)。nopCommerce免費(fèi)提供。今天,它是最好和最流行的ASP.NET電子商務(wù)軟件。它已被下載超過(guò)180萬(wàn)次!

nopCommerce是一個(gè)完全可定制的購(gòu)物系統(tǒng)。它穩(wěn)定且高度可用。nopCommerce是一個(gè)開(kāi)源的電子商務(wù)解決方案,它是基于MS SQL 2008(或更高版本)后端數(shù)據(jù)庫(kù)的ASP.NET(MVC)。我們易于使用的購(gòu)物車解決方案特別適合已經(jīng)超過(guò)現(xiàn)有系統(tǒng)的商家,并可能與您當(dāng)前的網(wǎng)站托管商或我們的托管合作伙伴一起托管。它擁有開(kāi)始通過(guò)互聯(lián)網(wǎng)銷售物理和數(shù)字產(chǎn)品所需的一切。

以上解釋引用自該項(xiàng)目的Github :https://github.com/nopSolutions/nopCommerce

因?yàn)檫@幾天沒(méi)無(wú)法靜心學(xué)習(xí)該項(xiàng)目的架構(gòu),所有只拎出該項(xiàng)目的CommonHelper.cs來(lái)談?wù)劇?/p>

1.E-Mail校驗(yàn)

#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(是否為空,是否超長(zhǎng),格式是否規(guī)范)/// </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>/// 用正則表達(dá)式校驗(yàn)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);}

這個(gè)E-mial校驗(yàn)的方法基本是可以直接拿過(guò)來(lái)用的,校驗(yàn)的正則表達(dá)式也很全面,需要用的時(shí)候可以過(guò)來(lái)copy。

2.ip地址校驗(yàn)

/// <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 _);}

直接使用了系統(tǒng)自帶的IPAddress.TryParse方法,很多小伙伴還不知道吧!

3.產(chǎn)生指定長(zhǎng)度的隨機(jī)數(shù)字字符串

/// <summary>/// 產(chǎn)生一個(gè)指定長(zhǎng)度的隨機(jī)數(shù)據(jù)字符串/// </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;}

這里的話,其實(shí)我覺(jué)得用stringbuild比直接用string更好一點(diǎn),尤其是當(dāng)length比較長(zhǎng)的時(shí)候,可能用stringbuild效率更高一些。

4.產(chǎn)生一個(gè)隨機(jī)數(shù)字

/// <summary>/// 產(chǎn)生一個(gè)隨機(jī)數(shù)/// </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);}

當(dāng)時(shí)不懂Random工作原理的時(shí)候,覺(jué)得這個(gè)方法簡(jiǎn)直是脫褲子放P,多此一舉,搞得這么麻煩干嘛! 直接Random().Next(min,max)不就產(chǎn)生了一個(gè)指定范圍的隨機(jī)數(shù)嗎?干嘛搞得這么復(fù)雜呢?

原來(lái),Random是需要一個(gè)隨機(jī)數(shù)作為“種子”的,當(dāng)這個(gè)種子相同時(shí),那么產(chǎn)生的隨機(jī)數(shù)也是相同的,有同學(xué)肯定會(huì)說(shuō),我們平時(shí)用的時(shí)候沒(méi)有指定“種子”數(shù)據(jù),也能產(chǎn)生我想要的隨機(jī)數(shù)啊! 其實(shí),當(dāng)我們沒(méi)有指定“種子”的時(shí)候,Random時(shí)默認(rèn)以當(dāng)前時(shí)間作為種子的,當(dāng)高并發(fā)訪問(wèn)的情況下,如果使用時(shí)間作為種子數(shù)據(jù),這顯然就很有可能產(chǎn)生相同的隨機(jī)數(shù),這顯然就不那么“隨機(jī)”了,所以該方法看似多余的方法都只是為了利用RNGCryptoServiceProvider().GetBytes()產(chǎn)生一個(gè)足夠隨機(jī)的byte[],然后再把該byte[]轉(zhuǎn)換成數(shù)字,那么該數(shù)字就能基本不會(huì)重復(fù)了,也就是”種子”不重復(fù),所以隨機(jī)數(shù)也不會(huì)重復(fù)了。

5.檢查兩個(gè)數(shù)組是否相等

/// <summary>/// 檢查兩個(gè)數(shù)組是否相等/// </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;}

搜先檢測(cè)地址引用是否相同,如果相同,肯定時(shí)同一個(gè)對(duì)象,那么相等,然后是檢測(cè)時(shí)否為空…..?? 代碼很簡(jiǎn)單,就不一一說(shuō)了,我們比較的時(shí)候,容易遺忘一些條件,直接走到了for循環(huán)最后一步,其實(shí),不到迫不得已,沒(méi)不要for循環(huán)。

6.給對(duì)象的指定屬性賦值

/// <summary>///給對(duì)象的指定屬性賦值/// </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.將一個(gè)值轉(zhuǎn)換成目標(biāo)類型

/// <summary>/// 將一個(gè)值轉(zhuǎn)換成目標(biāo)類型。/// </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>/// 將一個(gè)值轉(zhuǎn)換成目標(biāo)類型./// </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>/// 將一個(gè)值轉(zhuǎn)換成目標(biāo)類型/// </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));}

有了這個(gè)方法,我們就不用傻傻想著用Convent….到底Convernt點(diǎn)什么呢?哈哈,直接To<T>(),是不是很帥?

8.刪除目錄

/// <summary>/// 深度優(yōu)先的遞歸刪除/// </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);}}

一開(kāi)始,我也不明白為什么要弄得這么復(fù)雜,要?jiǎng)h除目錄,直接Directory.Delete(path)就好了不是嗎? 其實(shí)不是的,如果目錄不為空,會(huì)報(bào)System.IO.IOException: The directory is not empty.的錯(cuò)誤的,所以要遞歸,層層刪除,據(jù)說(shuō)Win系統(tǒng)的資源管理器,刪除目錄,其實(shí)就是這個(gè)邏輯實(shí)現(xiàn)的。

9.獲取兩個(gè)Datetime之間的年份間隔

/// <summary>/// 獲取兩個(gè)時(shí)間之間相差的年份/// </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;}

對(duì),如果endDate.Year -?startDate.Year是不對(duì)的,就好像你是去年的8月份出生的,而現(xiàn)在才五月份,那么你現(xiàn)在還不能稱為1歲一樣的道理。同樣的方法還可以用來(lái)獲取月、日、時(shí)、分、秒的間隔。

10 虛擬路徑轉(zhuǎn)物理路徑

/// <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);}

大致就是這么多,可能以上方法大家都知道,但是自己寫(xiě)出來(lái)可能不夠巧妙(老江湖除外),記錄下來(lái),希望對(duì)大家有所幫助,也用于自我加深映像。

有興趣的可以去github上下載nopcommerce的源碼來(lái)看看。

轉(zhuǎn):https://www.cnblogs.com/CoderAyu/p/8982842.html

總結(jié)

以上是生活随笔為你收集整理的NopCommerce开源项目中很基础但是很实用的C# Helper方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。