设置主动被动无果,如图设置列表命令为SATA-l可以解决
Monthly Archives: 四月 2019
在C#中生成与PHP一样的MD5 Hash Code
最近在对一个现有的系统进行C#改造,该系统以前是用PHP做的,后台的管理员登陆用的是MD5加密算法。在PHP中,要对一个字符串进行MD5加密非常简单,一行代码即可:
md5("Something you want to encrypt.")
直接调用md5()方法,然后将要进行MD5加密的字符串传进去,就可以得到返回的hash code。在C#中应该也会有对应的算法吧!对吗?我首先尝试了下面的代码,结果得到的hash code和PHP不一样。
public static string MD5(string stringToHash) { return FormsAuthentication.HashPasswordForStoringInConfigFile(stringToHash, "md5"); }
所以,我们不得不借用C#的MD5CryptoServiceProvider对象自己写代码进行转换。
1. 实例化MD5CryptoServiceProvider对象
2. 将字符串转换成byte数组
3. 使用MD5CryptoServiceProvider对象的ComputeHash()方法将byte数组进行加密,返回转换后的byte数组
4. 在讲byte数组转换成字符串之前,还需要对其进行遍历并做如下转换:
myByte.ToString("x2").ToLower()
然后,你才能得到和PHP中一样的MD5 hash code。为什么在.NET中要这么麻烦,或许这也是为什么那么多的开发人员仍然热衷于PHP开发的理由之一,每一门编程语言都有它自身的魅力,也都有它存在的意义!
基于上面的讨论,完整的代码如下:
public static string MD5ForPHP(string stringToHash) { var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] emailBytes = Encoding.UTF8.GetBytes(stringToHash.ToLower()); byte[] hashedEmailBytes = md5.ComputeHash(emailBytes); StringBuilder sb = new StringBuilder(); foreach (var b in hashedEmailBytes) { sb.Append(b.ToString("x2").ToLower()); } return sb.ToString(); }
或者,你也可以把上面的方法写成一个C#扩展方法,只需要修改方法签名即可。
public static string MD5ForPHP(this String, string stringToHash) { // Your code here. }
PHP程序和C#程序在许多方面都会涉及到格式之间的转换,如果运行PHP的服务器是UNIX类型的,则还会存在日期格式之间的转换。下面的两个方法展示了如何将UNIX时间转换成C# DateTime以及如何将C# DateTime转换成UNIX时间。
public static DateTime UnixTimeStampToDateTime(long unixTimeStamp) { // Unix timestamp is seconds past epoch DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); return dtDateTime.AddSeconds(unixTimeStamp); } public static long DateTimeToUnixTimeStamp(DateTime datetime) { TimeSpan span = (datetime - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)); return (long)span.TotalSeconds; }
无法序列化会话状态。在“StateServer”或“SQLServer”模式下,ASP.NET 将序列化
开发asp.net应用时,修改web.config中的SessionState节点。
<sessionState mode=“StateServer” stateConnectionString=“tcpip=127.0.0.1:42424″ sqlConnectionString=“data source=127.0.0.1;Trusted_Connection=yes” cookieless=“false” timeout=“120”/>
<sessionState mode=“InProc” stateConnectionString=“tcpip=127.0.0.1:42424″ sqlConnectionString=“data source=127.0.0.1;Trusted_Connection=yes” cookieless=“false” timeout=“120”/>
InProc模式
优点:获取session状态的速度快,session状态直接存储在iis的进程中。
缺点:易丢失,经常需要重新登录
StateServer模式
优点:session状态单独存储在一个进程中,不会因为iis或者应用的重启而丢失状态
缺点:获取session状态的速度比InProc慢一些,毕竟是两个不同的进程。
在开发的时候,对应用有一点修改,就会导致应用的重启,这时候如果使用InProc模式
,那么每次都需要重新登录,比较浪费时间.建议使用StateServer模式。并在iis里面设置超时时间长一些。
注:使用StateServer模式的时候
1、要开启“ASP.NET State Service”服务(设为“自动”)
2、如果stateConnectionString的值不是127.0.0.1或者localhost等代表本地地址的值,需要修改注册表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state \Parameters 节点 → 将 AllowRemoteConnection 的键值设置成“1”(1 为允许远程电脑的连接,0 代表禁止)→ 设置 Port (端口号)
3、session中存储非序列化的对象,如果违反会抛出 无法序列化会话状态。在“StateServer”或“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许使用无法序列化的对象或 MarshalByRef 对象。如果自定义会话状态存储在“Custom”模式下执行了类似的序列化,则适用同样的限制。这样的异常。如果向session存储自定义的对象,那么该对象的类上一定要加上[Serializable]注释。
entity framework 实现按照距离排序
纯SQL语句实现方法:
SELECT es_name, es_lon, es_lat, ROUND( 6378.138 * 2 * ASIN( SQRT( POW( SIN( ( 30.611842 * PI() / 180 - es_lat * PI() / 180 ) / 2 ), 2 ) + COS(30.611842 * PI() / 180) * COS(es_lat * PI() / 180) * POW( SIN( ( 104.074666 * PI() / 180 - es_lon * PI() / 180 ) / 2 ), 2 ) ) ) * 1000 ) AS distance_um FROM c_ershuai ORDER BY distance_um ASC
但是我比较习惯使用 entity framework,于是我就想着能不能用 entity framework 实现按照距离排序。
以下是我采用的方案
首先定义一个接口,用来表示具有经纬度信息的实体。
/// <summary> /// 具有经纬度 /// </summary> public interface IHasLngAndLat { /// <summary> /// 经度 /// </summary> double Lng { get; set; } /// <summary> /// 纬度 /// </summary> double Lat { get; set; } }
然后创建泛型类,用来包装计算的距离。
/// <summary> /// 带距离的数据 /// </summary> /// <typeparam name="TEntity"></typeparam> public class DataWithDistance<TEntity> { /// <summary> /// 距离(km) /// </summary> public double Distance { get; set; } /// <summary> /// 实体数据 /// </summary> public TEntity Entity { get; set; } }
最后编写根据距离排序的扩展方法
注意:这个方法是采用的 SqlFunctions 类,所以仅支持SqlServer数据库,如果是其它数据库,需要将 SqlFunctions 更换成对应的类
/// <summary> /// IQueryable扩展类 /// </summary> public static class QueryableExtension { /// <summary> /// 根据距离排序 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="queryable"></param> /// <param name="lng">经度</param> /// <param name="lat">纬度</param> /// <returns></returns> public static IQueryable<DataWithDistance<TEntity>> OrderByDistance<TEntity>(this IQueryable<TEntity> queryable, double lng, double lat) where TEntity : class, IHasLngAndLat { var rtn = from q in queryable let radLat1 = lat * Math.PI / 180.0 let radLat2 = q.Lat * Math.PI / 180.0 let a = radLat1 - radLat2 let b = lng * Math.PI / 180.0 - q.Lng * Math.PI / 180.0 let s = 2 * SqlFunctions.Asin(SqlFunctions.SquareRoot(Math.Pow((double)SqlFunctions.Sin(a / 2), 2) + SqlFunctions.Cos(radLat1) * SqlFunctions.Cos(radLat2) * Math.Pow((double)SqlFunctions.Sin(b / 2), 2))) * 6378.137 let d = Math.Round((double)s * 10000) / 10000 orderby d select new DataWithDistance<TEntity> { Entity = q, Distance = d }; return rtn; } }
以上就完成了 entity framework 按照距离排序的功能。
接下来我们用它来写一个小小的demo
首先创建一个商店实体类,具有经纬度字段,实现了 IHasLngAndLat 接口。
/// <summary> /// 商店实体 /// </summary> public class Shop : IHasLngAndLat { /// <summary> /// 主键 /// </summary> public int Id { get; set; } /// <summary> /// 商店名称 /// </summary> [Required] [StringLength(64)] public string ShopName { get; set; } /// <summary> /// 经度 /// </summary> public double Lng { get; set; } /// <summary> /// 纬度 /// </summary> public double Lat { get; set; } }
然后创建EF上下文类
/// <summary> /// EF上下文 /// </summary> public class DemoDbContext : DbContext { public DemoDbContext() : base("name=DemoDbContext") { } public virtual DbSet<Shop> Shop { get; set; } }
最后我们分页查询商店,并按照距离由近到远排序
#region 入参 double user_lng = 113.46, user_lat = 22.27; //用户经纬度 int pageIndex = 3; //当前页码 int pageSize = 10; //每页条数 #endregion using (DemoDbContext context = new DemoDbContext()) { var queryable = context.Shop.AsNoTracking().AsQueryable(); IQueryable<DataWithDistance<Shop>> sort_queryable = queryable.OrderByDistance(user_lng, user_lat); //按照用户的距离从近到远排序 List<DataWithDistance<Shop>> data = sort_queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); //分页并执行sql查询获取数据 //TODO:将查到的数据映射成DTO对象,并返回给客户端 }
好了,entity framework 实现按照距离排序 也就全部完成了。