首页 > 代码库 > 作个有安全感的应用,告别裸奔
作个有安全感的应用,告别裸奔
自个对架构比较感兴趣。闲暇时间学习学习相关姿势,也涨涨姿势。
算是自娱自乐也算是实践吧!把自己平时用的小功能做了个系统都算不上的小应用吧!
一开始通过账号密码验证,然后加上了,mac地址验证还是觉得不够安全,最近把数字证书的功能也加上了,感觉小有有点安全感,不再裸奔了。可以跟大家分享分享。
1、浅说架构
这样一个拓扑图,大家首先想到的是bs的网站吧!其实我们今天说的cs架构的小应用。
使用wcf支撑的soa架构:
为什么用wcf呢?首先wcf简单上手快,然后wcf我可以通过简单的配置实现用http还是tcp协议,如果是http我可以考虑用json还是xml,如果是tcp我可以使用流(http://www.cnblogs.com/wuguilin/p/3319883.html)。然后他是也是微软的产品,兄弟产品兼容性肯定好些,可以有N种安全机制供我选择。
为何soa呢?客户端直接连数据库嘛不安全,都连数据库的话那个连接数会比较多。Soa后业务逻辑的更新只用升级服务端即可。
关于soa和wcf的强大之处网上很多我就不多说啦。主要遗憾的是微软的产品太产品啦,都是告诉用户功能,不需要知道怎么实现,使得我遇到问题查找起来比较麻烦。
2、知识分享
2.1、wcf第一次请求慢,闲置很久后再次请求也慢
第一次应该是很正常的,第一次使用它肯定需要初始化一些东西,网上有朋友说UseDefaultWebProxy = false就是不适应默认代理,我也试了下效果不明显,而且NetTcpBinding没 有这个这个属性。闲置后再次请求慢,我猜应该是代理闲置很久 了,就不是激活状态了,再次使用需要去激活。这个用个定时器每分钟去请求服务一次就可以保持一直处于激活状态啦。
2.2、证书使用
2.2.1WCF部署到IIS出现“证书必须具有能够进行密钥交换的私钥,该进程必须具有访问私钥的权限”
主要是NETWORK SERVICE没有权限访问证书,解决方法在下面
解决之门:http://hi.baidu.com/168hello/item/434874ba0771b4d684dd79ac
2.2.2C#证书操作
/// <summary> /// 判断证书状态 /// </summary> /// <param name="findValue">证书名称</param> /// <param name="storeName">指定 X.509 证书存储区名称的枚举值之一</param> /// <param name="storeLocation">指定 X.509 证书存储区位置的枚举值之一</param> /// <returns> /// 10:不存在 /// 20:失效 /// 1 :正常 /// </returns> public static int Status(string findValue,StoreName storeName, StoreLocation storeLocation) { var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.MaxAllowed); X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, findValue, false); if (certs.Count == 0) { return 10; } else { if (certs[0].NotAfter < DateTime.Now) return 20; else { return 1; } } } /// <summary> /// 新增证书 /// </summary> /// <param name="filePath"></param> /// <param name="findValue"></param> /// <param name="storeName">指定 X.509 证书存储区名称的枚举值之一</param> /// <param name="storeLocation">指定 X.509 证书存储区位置的枚举值之一</param> public static void Add(string filePath, string findValue,StoreName storeName, StoreLocation storeLocation) { var certificate = new X509Certificate2(filePath, findValue); var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadWrite); store.Add(certificate); store.Close(); } /// <summary> /// 删除证书 /// </summary> /// <param name="filePath"></param> /// <param name="findValue"></param> /// <param name="storeName">指定 X.509 证书存储区名称的枚举值之一</param> /// <param name="storeLocation">指定 X.509 证书存储区位置的枚举值之一</param> public static void Remove(string filePath, string findValue,StoreName storeName, StoreLocation storeLocation) { var certificate = new X509Certificate2(filePath, findValue); var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadWrite); store.Remove(certificate); store.Close(); }
要注意的是证书在个人、受信任人、收信任的根证书颁发机构都需要添加
2.2.3使用makecert 创建证书后导出的时候记得要选择导出密钥,具体原因我忘记啦。我之前遇到这个错误。
3、工具类分享
运行Cmd
using System;using System.Diagnostics;using System.IO;namespace Yike.Tools{ public class CmdHelper { public static string RunCmd(string strCmd) { string rInfo; try { var myProcess = new Process(); var myProcessStartInfo = new ProcessStartInfo("cmd.exe"); myProcessStartInfo.UseShellExecute = false; myProcessStartInfo.CreateNoWindow = true; myProcessStartInfo.RedirectStandardOutput = true; myProcess.StartInfo = myProcessStartInfo; myProcessStartInfo.Arguments = "/c " + strCmd; myProcess.Start(); StreamReader myStreamReader = myProcess.StandardOutput; rInfo = myStreamReader.ReadToEnd(); myProcess.Close(); rInfo = strCmd + "\r\n" + rInfo; return rInfo; } catch (Exception ex) { return ex.Message; } } }}
using System;using System.Configuration;using System.Windows.Forms;using System.Xml;namespace Yike.Tools{ public class ConfigHelper { public static void UpdateOrCreateSettings(string key, string value) { Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); if (config.AppSettings.Settings[key] != null) config.AppSettings.Settings[key].Value = value; else config.AppSettings.Settings.Add(key, value); config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("appSettings"); } /// <summary> /// 更新或新增[connectionStrings]节点的子节点值,存在则更新子节点,不存在则新增子节点,返回成功与否布尔值 /// </summary> /// <param name="name">子节点name值</param> /// <param name="connectionString">子节点connectionString值</param> /// <param name="providerName">子节点providerName值</param> /// <returns>返回成功与否布尔值</returns> public static bool UpdateOrCreateConnection(string name, string connectionString, string providerName) { try { string filename = Application.ExecutablePath + ".config"; var doc = new XmlDocument(); doc.Load(filename); //加载配置文件 XmlNode node = doc.SelectSingleNode("//connectionStrings"); //得到[connectionStrings]节点 ////得到[connectionStrings]节点中关于Name的子节点 if (node != null) { var element = (XmlElement)node.SelectSingleNode("//add[@name=‘" + name + "‘]"); if (element != null) { //存在则更新子节点 element.SetAttribute("connectionString", connectionString); element.SetAttribute("providerName", providerName); } else { //不存在则新增子节点 XmlElement subElement = doc.CreateElement("add"); subElement.SetAttribute("name", name); subElement.SetAttribute("connectionString", connectionString); subElement.SetAttribute("providerName", providerName); node.AppendChild(subElement); } } //保存至配置文件(方式二) doc.Save(filename); return true; } catch (Exception) { return false; throw; } } /// <summary> /// 移除[connectionStrings]节点的子节点值,存在则更新子节点,不存在则新增子节点,返回成功与否布尔值 /// </summary> /// <param name="name">子节点name值</param> /// <param name="connectionString">子节点connectionString值</param> /// <param name="providerName">子节点providerName值</param> /// <returns>返回成功与否布尔值</returns> public static bool RemoveConnection(string name) { bool isSuccess = false; string filename = string.Empty; filename = Application.ExecutablePath + ".config"; var doc = new XmlDocument(); doc.Load(filename); //加载配置文件 XmlNode node = doc.SelectSingleNode("//connectionStrings"); //得到[connectionStrings]节点 if (node == null) return true; ////得到[connectionStrings]节点中关于Name的子节点 var element = (XmlElement)node.SelectSingleNode("//add[@name=‘" + name + "‘]"); if (element != null) { node.RemoveChild(element); } //保存至配置文件(方式二) doc.Save(filename); isSuccess = true; return isSuccess; } }}
using System;using System.Text;using System.Web;using System.IO;using System.Drawing;using System.Security.Cryptography;using System.Net;namespace Yike.Tools{ public static class FormatTransform { /// <summary> /// 将字符串转换为MD5码 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string StrToMD5(string str) { return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToUpper(); } /// <summary> /// 解码 /// </summary> /// <param name="oStr"></param> /// <returns></returns> public static string Decode(string oStr) { return HttpUtility.UrlDecode(oStr, Encoding.UTF8); } /// <summary> /// 编码 /// </summary> /// <param name="oStr"></param> /// <returns></returns> public static string Encode(string oStr) { return HttpUtility.UrlEncode(oStr, Encoding.UTF8); } /// <summary> /// 字符串转Base64 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string StrToBase64(string str) { return Convert.ToBase64String(System.Text.Encoding.GetEncoding("utf-8").GetBytes(str)); } //默认密钥向量 private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; /// <summary> /// DES加密字符串 /// </summary> /// <param name="encryptString">待加密的字符串</param> /// <param name="encryptKey">加密密钥,要求为8位</param> /// <returns>加密成功返回加密后的字符串,失败返回源串</returns> public static string EncryptDES(string encryptString, string encryptKey) { try { byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8)); byte[] rgbIV = Keys; byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Convert.ToBase64String(mStream.ToArray()); } catch { return encryptString; } } /// <summary> /// DES解密字符串 /// </summary> /// <param name="decryptString">待解密的字符串</param> /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param> /// <returns>解密成功返回解密后的字符串,失败返源串</returns> public static string DecryptDES(string decryptString, string decryptKey) { try { byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey); byte[] rgbIV = Keys; byte[] inputByteArray = Convert.FromBase64String(decryptString); DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Encoding.UTF8.GetString(mStream.ToArray()); } catch { return decryptString; } } /// <summary> /// 字符串转Base64 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string StrToBase64(string code_type, string str) { return Convert.ToBase64String(System.Text.Encoding.GetEncoding(code_type).GetBytes(str)); } /// <summary> /// Base64转字符串 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string Base64ToStr(string str) { return System.Text.Encoding.GetEncoding("utf-8").GetString(Convert.FromBase64String(str)); } /// <summary> /// Base64转字符串 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string Base64ToStr(string code_type, string str) { return System.Text.Encoding.GetEncoding(code_type).GetString(Convert.FromBase64String(str)); } /// <summary> /// 将文件转换成二进制 /// </summary> /// <param name="Path">文件路径</param> /// <returns></returns> public static byte[] FileToBinary(string Path) { using (FileStream stream = new FileInfo(Path).OpenRead()) { byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, Convert.ToInt32(stream.Length)); return buffer; } } /// <summary> /// 将二进制转化成文件 /// </summary> /// <param name="filePath">文件路径</param> /// <param name="br">二进制</param> public static void BinaryToFile(string filePath, byte[] br) { using (FileStream fstream = File.Create(filePath, br.Length)) { try { fstream.Write(br, 0, br.Length); fstream.Close(); } catch (Exception ex) { //抛出异常信息 throw ex; } finally { fstream.Close(); } } } public static bool SaveWebResponseToFile(WebResponse response, string savePath, string fileName) { bool value = http://www.mamicode.com/false; byte[] buffer = new byte[1024]; Stream outStream = null; Stream inStream = null; try { DirectoryHelper.Create(savePath); if (File.Exists(savePath + fileName)) File.Delete(savePath + fileName); outStream = System.IO.File.Create(savePath + fileName); inStream = response.GetResponseStream(); int l; do { l = inStream.Read(buffer, 0, buffer.Length); if (l > 0) outStream.Write(buffer, 0, l); } while (l > 0); value = true; } finally { if (outStream != null) outStream.Close(); if (inStream != null) inStream.Close(); } return value; } /// <summary> /// byte[] to Stream /// </summary> public static Stream ByteToStream(this byte[] bytes) { if (bytes == null) return null; Stream stream = new MemoryStream(bytes); return stream; } /// <summary> /// Stream to byte[] /// </summary> public static byte[] StreamToByte(this Stream stream) { if (stream == null) return null; stream.Seek(0, System.IO.SeekOrigin.Begin); byte[] bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); // 设置当前流的位置为流的开始 stream.Seek(0, SeekOrigin.Begin); return bytes; } /// <summary> /// Image to byte[] /// </summary> /// <param name="Image"></param> /// <param name="imageFormat"></param> /// <returns></returns> public static byte[] ImageToByte(this Image Image, System.Drawing.Imaging.ImageFormat imageFormat) { if (Image == null) { return null; } byte[] data = http://www.mamicode.com/null; using (MemoryStream oMemoryStream = new MemoryStream()) { //建立副本 using (Bitmap oBitmap = new Bitmap(Image)) { //儲存圖片到 MemoryStream 物件,並且指定儲存影像之格式 oBitmap.Save(oMemoryStream, imageFormat); //設定資料流位置 oMemoryStream.Position = 0; //設定 buffer 長度 data = http://www.mamicode.com/new byte[oMemoryStream.Length]; //將資料寫入 buffer oMemoryStream.Read(data, 0, Convert.ToInt32(oMemoryStream.Length)); //將所有緩衝區的資料寫入資料流 oMemoryStream.Flush(); } } return data; } public static Image StreamToImage(Stream stream) { //初始化 System.Drawing.Bitmap 类的新实例。 Bitmap bm = new Bitmap(stream); //格式化 return Image.FromHbitmap(bm.GetHbitmap()); } }}
using System.Data;namespace Yike.Tools{ public static class DataTableExpand { /// <summary> /// DataTable里是否存在该值 /// </summary> /// <param name="dt">DataTable</param> /// <param name="columnName">列名</param> /// <param name="value">值</param> /// <returns></returns> public static bool HasColumnData(this DataTable dt, string columnName, string value) { foreach (DataRow dr in dt.Rows) { if (dr[columnName].ToString() == value) return true; } return false; } /// <summary> /// 第一个数据表 /// </summary> /// <param name="ds"></param> /// <returns></returns> public static DataTable FristTable(this DataSet ds) { if (ds == null || ds.Tables.Count == 0) { return null; } else { return ds.Tables[0]; } } }}
using System.IO;namespace Yike.Tools{ public class DirectoryHelper { /// <summary> /// 拷贝文件夹 /// </summary> /// <param name="sourceDirPath">源路径</param> /// <param name="destDirPath">目的路径</param> public static void Copy(string sourceDirPath, string destDirPath) { if (Directory.Exists(sourceDirPath)) { if (!Directory.Exists(destDirPath)) Create(destDirPath); DirectoryInfo di = new DirectoryInfo(sourceDirPath); foreach (FileInfo fi in di.GetFiles()) { string toName = destDirPath + "\\" + fi.Name; File.Copy(fi.FullName, toName, true); } foreach (DirectoryInfo dir in di.GetDirectories()) { Copy(dir.FullName, destDirPath + dir.FullName.Replace(sourceDirPath, "")); } } } /// <summary> /// 移动文件夹 /// </summary> /// <param name="sourceDirPath">源路径</param> /// <param name="destDirPath">目的路径</param> public static void Move(string sourceDirPath, string destDirPath) { if (Directory.Exists(sourceDirPath)) { if (!Directory.Exists(destDirPath)) Create(destDirPath); DirectoryInfo di = new DirectoryInfo(sourceDirPath); foreach (FileInfo fi in di.GetFiles()) { string toName = destDirPath + "\\" + fi.Name; if (File.Exists(toName)) { File.Delete(toName); } File.Move(fi.FullName, toName); } foreach (DirectoryInfo dir in di.GetDirectories()) { Move(dir.FullName, destDirPath + dir.FullName.Replace(sourceDirPath, "")); } Directory.Delete(sourceDirPath); } } /// <summary> /// 创建文件夹 /// </summary> /// <param name="dirPath">路径</param> public static void Create(string dirPath) { string[] paths = dirPath.Split(‘\\‘); string path = paths[0]; for (int i = 1; i < paths.Length; i++) { path = path + "\\" + paths[i]; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } /// <summary> /// 删除文件夹 /// </summary> /// <param name="dirPath">路径</param> public static void Delete(string dirPath) { if (Directory.Exists(dirPath)) { DirectoryInfo di = new DirectoryInfo(dirPath); foreach (FileInfo fi in di.GetFiles()) { fi.Delete(); } foreach (DirectoryInfo dir in di.GetDirectories()) { Delete(dir.FullName); } Directory.Delete(dirPath); } } }}
using System;using System.IO;using System.Net;using System.Text.RegularExpressions;namespace Yike.Tools{ public class FtpHelper { private string _FtpServerIP = string.Empty; public string FtpServerIP { get { if (FtpPort == 0) { return _FtpServerIP; } else { return string.Format("{0}:{1}", _FtpServerIP, FtpPort); } } set { _FtpServerIP = value; } } public string FtpUserName { get; set; } public string FtpPwd { get; set; } public long FtpPort { get; set; } public string ErrorMessage { get; set; } private static Regex regexName = new Regex(@"[^\s]*$", RegexOptions.Compiled); /// <summary> /// 初始化FTP请求 /// </summary> /// <param name="ftpServerIP"></param> /// <param name="ftpUserName"></param> /// <param name="ftpPwd"></param> /// <param name="ftpPort"></param> public FtpHelper(string ftpServerIP, string ftpUserName, string ftpPwd) { FtpServerIP = ftpServerIP; FtpPwd = ftpPwd; FtpUserName = ftpUserName; } /// <summary> /// 初始化FTP请求 /// </summary> /// <param name="ftpServerIP"></param> /// <param name="ftpUserName"></param> /// <param name="ftpPwd"></param> /// <param name="ftpPort"></param> public FtpHelper(string ftpServerIP, string ftpUserName, string ftpPwd, long ftpPort) { FtpServerIP = ftpServerIP; FtpPort = ftpPort; FtpPwd = ftpPwd; FtpUserName = ftpUserName; } /// <summary> /// 从客户端上传文件到FTP上 /// </summary> /// <param name="sFilePath"></param> /// <param name="filename"></param> /// <param name="FolderName"></param> public bool UploadFtp(string filename, string folderName, Stream stream) { try { ErrorMessage = string.Empty; FtpWebRequest reqFTP; reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(string.Format("ftp://{0}/{1}/{2}", FtpServerIP, folderName, filename))); reqFTP.Credentials = new NetworkCredential(FtpUserName, FtpPwd); reqFTP.KeepAlive = false; reqFTP.Method = WebRequestMethods.Ftp.UploadFile; reqFTP.UseBinary = true; reqFTP.UsePassive = false; reqFTP.ContentLength = stream.Length; //设置缓存 int buffLength = 2048; byte[] buff = new byte[buffLength]; int contentLen; using (Stream strm = reqFTP.GetRequestStream()) { contentLen = stream.Read(buff, 0, buffLength); while (contentLen != 0) { strm.Write(buff, 0, contentLen); contentLen = stream.Read(buff, 0, buffLength); } strm.Close(); stream.Close(); } return true; } catch (Exception ex) { ErrorMessage = ex.Message; return false; } } /// <summary> /// 创建目录 /// </summary> /// <param name="FolderName"></param> public bool CreateDirectory(string folderName) { FtpWebRequest reqFTP; try { // dirName = name of the directory to create. reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + FtpServerIP + "/" + folderName)); reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory; reqFTP.UseBinary = true; reqFTP.Credentials = new NetworkCredential(FtpUserName, FtpPwd); FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); Stream ftpStream = response.GetResponseStream(); ftpStream.Close(); response.Close(); return true; } catch (Exception ex) { ErrorMessage = ex.Message; if (ex.Message.IndexOf("550") > 0) return true; return false; } } /// <summary> /// 上面的代码实现了从ftp服务器下载文件的功能 /// </summary> /// <param name="filePath"></param> /// <param name="outFilePath"></param> /// <param name="errorinfo"></param> /// <returns></returns> public bool Download(string filePath, string outFilePath, out string errorinfo) { try { if (File.Exists(outFilePath)) { File.Delete(outFilePath); } FtpWebRequest reqFTP; reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(filePath.Replace("http", "ftp"))); reqFTP.Credentials = new NetworkCredential(FtpUserName, FtpPwd); reqFTP.KeepAlive = false; reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; reqFTP.UseBinary = true; reqFTP.UsePassive = false; FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); Stream ftpStream = response.GetResponseStream(); long cl = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); FileStream outputStream = new FileStream(outFilePath, FileMode.Create); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } ftpStream.Close(); outputStream.Close(); response.Close(); errorinfo = ""; return true; } catch (Exception ex) { errorinfo = string.Format("因{0},无法下载", ex.Message); return false; } } /// <summary> /// 检查日期目录和文件是否存在 /// </summary> public bool CheckFileOrPath(string folderName, string filePath) { try { if (!string.IsNullOrEmpty(filePath)) filePath = "ftp://" + FtpServerIP + "/" + filePath; else filePath = "ftp://" + FtpServerIP + "/"; //检查一下日期目录是否存在 FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(filePath)); reqFTP.UseBinary = true; reqFTP.UsePassive = false; reqFTP.Credentials = new NetworkCredential(FtpUserName, FtpPwd); reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails; Stream stream = reqFTP.GetResponse().GetResponseStream(); using (StreamReader sr = new StreamReader(stream, System.Text.Encoding.Default)) { string line = sr.ReadLine(); while (!string.IsNullOrEmpty(line)) { GroupCollection gc = regexName.Match(line).Groups; if (gc.Count != 1) { throw new ApplicationException("FTP 返回的字串格式不正确"); } string path = gc[0].Value; if (path == folderName) { return true; } line = sr.ReadLine(); } } return false; } catch (Exception ex) { throw ex; } } }}
using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Reflection;using grproLib;namespace Yike.Tools{ public class GridReportPrintHelper { private struct MatchFieldPairType { public IGRField grField; public int MatchColumnIndex; } // 将 DataTable 的数据转储到 Grid++Report 的数据集中 public static void FillRecordToReport(IGridppReport Report, DataTable dt) { MatchFieldPairType[] MatchFieldPairs = new MatchFieldPairType[Math.Min(Report.DetailGrid.Recordset.Fields.Count, dt.Columns.Count)]; //根据字段名称与列名称进行匹配,建立DataReader字段与Grid++Report记录集的字段之间的对应关系 int MatchFieldCount = 0; for (int i = 0; i < dt.Columns.Count; ++i) { foreach (IGRField fld in Report.DetailGrid.Recordset.Fields) { if (String.Compare(fld.Name, dt.Columns[i].ColumnName, true) == 0) { MatchFieldPairs[MatchFieldCount].grField = fld; MatchFieldPairs[MatchFieldCount].MatchColumnIndex = i; ++MatchFieldCount; break; } } } // 将 DataTable 中的每一条记录转储到 Grid++Report 的数据集中去 foreach (DataRow dr in dt.Rows) { Report.PrepareRecordset(); Report.DetailGrid.Recordset.Append(); for (int i = 0; i < MatchFieldCount; ++i) { if (!dr.IsNull(MatchFieldPairs[i].MatchColumnIndex)) MatchFieldPairs[i].grField.Value = dr[MatchFieldPairs[i].MatchColumnIndex]; } Report.DetailGrid.Recordset.Post(); } } // 将 DataTable 的数据转储到 Grid++Report 的数据集中 public static void FillRecordToReport<T>(IGridppReport Report, List<T> obj) where T : class { if (obj == null || obj.Count == 0) return; foreach (T tt in obj) { Report.PrepareRecordset(); Report.DetailGrid.Recordset.Append(); Type t1 = tt.GetType(); foreach (IGRField fld in Report.DetailGrid.Recordset.Fields) { fld.Value = t1.GetProperty(fld.DBFieldName).GetValue(tt, null).ToString(); } Report.DetailGrid.Recordset.Post(); } } }}
using System;using System.Collections.Generic;using System.Data;using System.IO;using System.Reflection;using System.Text;namespace Yike.Tools{ public class JsonHelper { public static string ObjToJson<T>(T data) { try { System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(data.GetType()); using (MemoryStream ms = new MemoryStream()) { serializer.WriteObject(ms, data); return Encoding.UTF8.GetString(ms.ToArray()); } } catch (Exception ex) { throw ex; } } public static Object JsonToObj(String json, Type t) { try { System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(t); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) { return serializer.ReadObject(ms); } } catch (Exception ex) { throw ex; } } public static string ListToJson<T>(List<T> aData, string needPropertys) where T : class, new() { StringBuilder jsonBuilder = new StringBuilder(); if (aData.Count > 0) jsonBuilder.Append("[");//转换成多个model的形式 if (aData != null && aData.Count > 0) { foreach (T o in aData) { jsonBuilder.AppendFormat("{0},", getSingleEntityStr<T>(o, needPropertys.Split(‘,‘))); } jsonBuilder.Remove(jsonBuilder.Length - 1, 1); } if (aData.Count > 0) jsonBuilder.Append("]"); return jsonBuilder.ToString(); } public static string EntityToJson<T>(T aData, string needPropertys) where T : class, new() { return string.Format("{0}", getSingleEntityStr<T>(aData, needPropertys.Split(‘,‘))); } private static string getSingleEntityStr<T>(T aData, string[] needPropertys) { Type t = aData.GetType(); IEnumerable<PropertyInfo> fields = t.GetProperties(); StringBuilder jsonBuilder = new StringBuilder(); jsonBuilder.Append("{"); foreach (PropertyInfo field in fields) { if (Array.IndexOf(needPropertys, field.Name) > -1) jsonBuilder.AppendFormat("\"{0}\":\"{1}\",", field.Name, t.GetProperty(field.Name).GetValue(aData, null)); } if (jsonBuilder.Length > 1) jsonBuilder.Remove(jsonBuilder.Length - 1, 1); jsonBuilder.Append("}"); return jsonBuilder.ToString(); } public static string DataTable2Json(DataTable dt) { if (dt.Rows.Count == 0) { return ""; } StringBuilder jsonBuilder = new StringBuilder(); jsonBuilder.Append("[");//转换成多个model的形式 for (int i = 0; i < dt.Rows.Count; i++) { jsonBuilder.Append("{"); for (int j = 0; j < dt.Columns.Count; j++) { jsonBuilder.Append("\""); jsonBuilder.Append(dt.Columns[j].ColumnName); jsonBuilder.Append("\":\""); jsonBuilder.Append(dt.Rows[i][j].ToString()); jsonBuilder.Append("\","); } jsonBuilder.Remove(jsonBuilder.Length - 1, 1); jsonBuilder.Append("},"); } jsonBuilder.Remove(jsonBuilder.Length - 1, 1); jsonBuilder.Append("]"); return jsonBuilder.ToString(); } }}
using System;using System.Runtime.InteropServices;using System.Windows.Forms;namespace Yike.Tools{ public class HotKeyHelper { //如果函数执行成功,返回值不为0。 //如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。 [DllImport("user32.dll", SetLastError = true)] public static extern bool RegisterHotKey( IntPtr hWnd, //要定义热键的窗口的句柄 int id, //定义热键ID(不能与其它ID重复) uint fsModifiers, //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效 Keys vk //定义热键的内容 ); [DllImport("user32.dll", SetLastError = true)] public static extern bool UnregisterHotKey( IntPtr hWnd, //要取消热键的窗口的句柄 int id //要取消热键的ID ); }}
using System; using System.IO; using System.Xml.Serialization; namespace Yike.Tools { public class SerializerHelper { public static string ToXml<T>(T t) { var xmls = new XmlSerializer(t.GetType()); var sw = new StringWriter(); var tmpxn = new XmlSerializerNamespaces(); tmpxn.Add(string.Empty, string.Empty); xmls.Serialize(sw, t, tmpxn); return sw.ToString().Replace("utf-16", "utf-8"); } public static bool ToModel<T>(string s, ref T t, out string outMessage) { try { outMessage = string.Empty; using (var rdr = new StringReader(s)) { //声明序列化对象实例serializer var serializer = new XmlSerializer(t.GetType()); //反序列化,并将反序列化结果值赋给变量i t = (T) serializer.Deserialize(rdr); return true; } } catch (Exception ex) { outMessage = ex.Message; return false; } } } }
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Diagnostics;using System.Management;namespace Yike.Tools{ public class SystemInfoHelper { /// <summary> /// 总线程数 /// </summary> public static int ProcessorCount { get { return Environment.ProcessorCount; } } /// <summary> /// CPU利用率 /// </summary> public static float CpuLoad { get { PerformanceCounter pcCpuLoad = new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName); pcCpuLoad.MachineName = "."; return pcCpuLoad.NextValue(); } } /// /// 获取可用内存 /// public long MemoryAvailable { get { long availablebytes = 0; ManagementClass mos = new ManagementClass("Win32_OperatingSystem"); foreach (ManagementObject mo in mos.GetInstances()) { if (mo["FreePhysicalMemory"] != null) { availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString()); } } return availablebytes; } } /// /// 获取物理内存 /// public long PhysicalMemory { get { ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if (mo["TotalPhysicalMemory"] != null) { return long.Parse(mo["TotalPhysicalMemory"].ToString()); } } return 0; } } }}
这东西分享不完的,就把我常用的跟大家分享下
4、插件分享
resharper,语法优化、命名检查、单元测试等强大功能你值得拥有。
VisualSVN,svn管理和vs结合挺好用的。
5、最后了
也贴张自己的这个应用靓照。
源码一如即往的不贴的,也不说为什么了。应用放在百度云盘供大家下载 http://pan.baidu.com/s/1mglzMpq 测试账号:1,密码:111。 忘记说了,需要.net4.5。xp系统是运行不来的
服务端放在阿里最低配的云上,不要压力测试啊
如果有兴趣一起改进的或有好的业务愿意使用这个架构大家可以交流交流。