RSS 2.0 Feed
C#
摘要:秋天到了,坐在自己摩托上感觉到阵阵的凉意。前段时间我从Web 组调往了 Win32 组,从事了一个企业软件的设计与开发的工作。现在已经正式提交客户运行了。运行状况还不错,借我朋友的一句话“没有什么消息,那本身就是一个好消息!”就在这次开发中的问题,我做了一下总结: 1. 关于数据类型在开发初期,我们在设计数据结构时,有一些数据使用了 float 与 double 数据类型,用来记录一些数值。刚开始还好,但到了测试阶段就出现了一些问题。当数据层提交了一个 66.6 到数据库,然后取出数据就变为 66.600000001 。 浮点数的近拟性就突示出来了,其实如果只是显示那还问题不大,但把这些数一进行运算那笑话可就大了。大家也许也能体会到在项目中期修改数据结构的痛苦:(。 但有一点还是不明白,同一张表中,同一个字段 有时 66.6 就能正确显示,而有时就只能显示为 66.60000001 所以大家在设计数据结构时,如果要进行运算的数据最好使用 decimal类型。只要预设好精度,那会非常好用。 2. Self -Update Application应用开发完成后,更新也是非常的重要的。如果你的程序有一个 AutoUpdate 功能那是很酷的。我们的项目主要实现方法是: a. 使用 IIS 站点做为 服务器端。(当然了你也可以使用 FTP 等) b. 使用一个 AppVersion.xml 文件来保存最新的程序信息(主要信息为 当前版本,文件列表,文件大小,以及文件完整性验证码)。(当然使用 Web Service 会更加安全) <?xml version="1.0" encoding="utf-8" ?>  <SBS> <Ver>1688</Ver>  <Files >   <File FileName="File1"  size="1212121" key="8a7c5e5a6c4d2e3f2a3" ></File>   <File FileName="File2"  size="1212121" key="8a7c5e5a6c4d2e3f2a3" ></File>  </Files> </SBS> c. AppMain.exe 是我们程序的主要启动程序,它的主要任务是确定比较服务器端与客户端之间的版本差异,如果一致就启动应用程序。如果有新的版本出现就就下载并验证新版本文件。并启动新的版本。(AppMain.exe 要控制一下,只能让系统中有一个实例存在,不然可能会出现IO问题) d. 应用程序中也要添加一个查询模块,对给定的服务器定时验证版本,最好用一个独立的进程进行,性能会好一点。如果有新的版本了,那就启动AppMain.exe 程序,并退出主程序。(我们的程序有这个必要,大部分应用不会要求怎么高的。) e. 这样一个基本的自动更新程序就完成了。这个思想比较简单。如果你对自动更新感性趣,MS有一个 Microsoft.ApplicationBlocks.ApplicationUpdater ,你可以参考一下。 还有一些其它的,下次写吧!...[阅读全文]

posted @ | Feedback (10) | Filed Under [ C# MS DotNET ]

摘要:续上次浅谈了一下passport 的实现。在自己的项目中也进行了运用。 就对于开发中发现的问题进行一下说明。 想达到的目的: 在多个应用系统共享一个用户身份验证系统,而用户在各应用系统中的权限由应用系统自己处理。 主要流程: 应用程序->当用户访问受限页面 -> 由MyPassport 进行身份验证 -> 用户注册 MyPassport 帐号 -> 登录 MyPassport  -> 返回应用程序 -> 应用程序得到用户信息 -> 分析角色或权限 -> 访问受限页面 主要的类: MYPassportAuthentication  -- 提供为操作身份验证票提供帮助器实用工具的静态方法MYPassportAuthenticationModule : IHttpModule - 模块初始化和处置事件MYPassportAuthenticationEventArgs  : EventArgs  -  事件参数类MYPassportAuthenticationTicket - 验证票MYPassportConfiguration  - 配置类MYPassportConfigurationHandler : IConfigurationSectionHandler  - 配置分配MYPassportIdentity :IIdentity - 用户验证信息 与 HttpContext.User.Identity 统一 有了上面几个类的设计,就可以进行开发了。我们选用的数据传送方式是:"查询字符串",即"查询字符串" 做为应用程序间 Ticket 信息的信道 当一个应用程序需要登录时,转向MYPassport 的地址是 : http://mypassport.net/login.aspx?appId=11&ru=http://myapplication.com/somepage.aspxru为返回应用程序的地址, 其中的 AppId 为应用程序的ID号,用于当ru 信息丢失时使用。 当完成登录:返回应用程序,地址为: http://myapplication.com/somepage.aspx?ticket=%%^^&&( 这里的ticket 为加密后的票,在返回到 应用程序的 MYPassportAuthenticationModule 时,对request.url 进行分析,把ticket 分离出来,生成真正的 ticket,取得 用户信息,取得权限。完成注册。   一,MYPassportAuthentication 类 由于 Ticket 在网络上传送时,要对数据进行一下加密。等到达应用程序时再进行解密。得到我们想要的票信息。 public static MYPassportAuthenticationTicket Decrypt(string strTicket) // 进行解密 public static string Encrypt(MYPassportAuthenticationTicket ticket) // 加密  这些都是公共的方法,没有什么好说的。 二,MYPassportAuthenticationModule : IHttpModule 注册验证事件与处理   public event MYPassportAuthenticationEventHandler Authenticate;    public void Init(HttpApplication context)  {   context.AuthenticateRequest +=new EventHandler(OnEnter);   context.EndRequest += new EventHandler(this.OnLeave);     } 对ticket 进行处理。  web.config  <httpModules>         <add type="MYCom.Security.KK7PassportAuthenticationModule,MYCom.Security"               name="MYPassport"/>    </httpModules>  三, MYPassportAuthenticationEventArgs  验证事件参数。当发生验证时,取得用户的MYPassportIdentity 信息 四,MYPassportAuthenticationTicket......[阅读全文]

posted @ | Feedback (18) | Filed Under [ ASP.Net C# ]

摘要:今天看到mmkk 的回复,就试着安装了一下 这个 AspForum 2.0 . 第一步: 安装数据库: 在自己的Sql Server 里创建一个库: AspForumDB Create Database AspForumDB 然后运行几个 .Sql  脚本文件.(请注意顺序)  文件都在: (forums_latest_source\ASP.NET Forums\Data Providers\SqlDataProvider\sql) 中 2003.10-Tables.sql 2003.10-Functions.sql 2003.10-Procedures.sql 2003.10-Data.sql 2003.10.Alpha.sql forums_alpha_to_beta.sql 第二步 创建 Forum 2.0 工程(你的机器上一定要IIS, VS 2003)  把 forums_latest_source\ASP.NET Forums\Web 目录全部copy 到 你的web 目录 (一般为C:\Inetpub\wwwroot) 的 Forums 目录中. 打开你的IIS 管理器,为这个Forums 目录创建一个虚拟目录 找到 \forums_latest_source\ASP.NET Forums 目录中的 ASP.NET Forums.sln 文件,双击, 应该没什么问题就可以打开了 由于编码的问题. 工程一开始是不能编译的. 有一个地方要改一下. orums_latest_source\ASP.NET Forums\Controls\Navigation\JumpDropDownList.cs  中的69,75,81 行的“?”号,改为 “引号” , 这样就可以正常编译了 第三步 修改Web.config 文件 因为我们使用的是Sql Server 数据库,只要把providers>SqlForumsProvider > ^SqlConnectionString^ 字段修改一下.也就是你的数据库连接字符串 (如ata source=192.168.0.1;user id=sa;password=password;initial catalog=ASPForumDB;Connect Timeout=30) 修改compilation 中的 debug 为 true ,后面我们要调试工程 到这里,已经可以运行了. 把 Defualt.aspx 设为启动文件, 按下F5 , 应该看到界面了. 第四步 处理一些BUG 运行后我们发现,注册用户很正常, 但注册的用户就是登录不上. 为什么呢?可能是作者发布的比较急有些地方没有处理好. 找到 forums_latest_source\ASP.NET Forums\Components \users.cs 文件的843 行 user.Password = Encrypt(Globals.GetSiteSettings().PasswordFormat, password, user.Salt); 修改为 user.Password = Encrypt(Globals.GetSiteSettings().PasswordFormat, password, "") ;......[阅读全文]

posted @ | Feedback (49) | Filed Under [ ASP.Net C# MS DotNET 工作日记 ]

摘要:我们在编写一些文档管理的项目时一定会有这样的问题。想控制客户下载的文件和下载次数,以及下载的时段。 比较好的方法是:使用ActiveX 控件就象 http://www.gotdotnet.com 中的代码共享。 通常我们不会选择怎么复杂的方案。 我的解决方案是: 在系统的 非Web 目录中存放文件,文件名已经经过了编码(主要是安全的考虑),当然我们也可以对文件内容进行加密。把真实的文件名放在数据库中(这样比把文件放在数据库上,如果客户有一个1G的文件,那你只有哭了 )。 用户下载的链接如下: http://www.test.org/filedownload.aspx?e6feeccd90a9463d93b9dc231115bbb9  (是不是很象MS 的下载中心) 代码:   private void Page_Load(object sender, System.EventArgs e)  {   //读取文件   if (null!=Page.Request.Url.Query )    // 请求字符串为     FileGuid = Page.Request.Url.Query.Substring (1); // fileGuid= e6feeccd90a9463d93b9dc231115bbb9    // Globals.fileLibDir 就是那个我们存放文件的目录   if (!File.Exists(Globals.fileLibDir + FileGuid))   {    // 文件没有找到    Page.Response.Redirect ("error.aspx?msg=文件不存在",true );     return;   }    // 真实的文件名   string fileName = getFileNameByStorageName(FileGuid);   if (fileName == string.Empty  )   {    //文件没有找到    Page.Response.Redirect ("error.aspx?msg=链接错误,请与管理员联系!",true );     return;   }    Page.Response.ContentType="APPLICATION/OCTET-STREAM";   // 注意下面的Encode 编码,不然无法处理中文文件名   Page.Response.AddHeader("Content-Disposition","attachment; filename=" + HttpUtility.UrlEncode(fileName,Encoding.UTF8 ) );   Page.Response.WriteFile ( Globals.fileLibDir + FileGuid);     }  ...[阅读全文]

posted @ | Feedback (20) | Filed Under [ ASP.Net C# ]

摘要:最近公司一直在开发几个系统.因为是几个团队并行开发. 有专门一个团队开发各系统的公共部分. 其它都有自己的开发项目。这个公共项目组人数是最多的,我现在就在领导这个公共项目组。 项目的开发初期,在其它团队还没有组建之前,我们所有的程序员都是公共项目组成员。进行平台级的开发,当平台开发到一定的进度(也就是一个里程碑阶段),从公共项目组分离出第一个独立项目组.慢慢其它两个项目组也产生了.测试团队也跟着开发团队进行分离. 我们内部这了进行有效的交流,也使用了博客系统.来做为个人的开发日志与开发白板.每个人都有一个SharpReader , 里面有所有人员博客的 RSS . 用以保证交流的通畅.在每天的立会(其实是例会,但因为大家都站着,所以就叫"立"会了)中会就大家的日志进行讨论. 刚刚开始都是开发技术上的讨论,慢慢得大家都会汇聚到系统结构方面.这样就会大大影响开发进程,因为前期我们的需求做得比较充分,一般不会有太大的结构问题.所以,我们规定了在博客中不要谈及系统结构问题.有建议可以用Project Email 的方式,提交项目管理组. 这样, 开发团队与博客系统可以比较好的结合了(至少现在它们还是很合目的 ).  ...[阅读全文]

posted @ | Feedback (10) | Filed Under [ C# 软件工程 ]

摘要: /// <summary>  /// 数据流转换为十六进制字符串  /// </summary>  /// <param name="bytes"></param>  /// <returns></returns>  private static string ByteArrayToHexString(byte[] bytes)   {    if ( bytes == null || bytes.Length == 0 )     throw new ArgumentException( "bytes [] 参数出错" );    StringBuilder hexString = new StringBuilder( 2 * bytes.Length );    for ( int i = 0; i < bytes.Length; i++ )    hexString.AppendFormat( "{0:X2}", bytes[i] );    return hexString.ToString();   }   /// <summary>  /// 十六进制字符串转换为数据流  /// </summary>  /// <param name="strHexString"></param>  /// <returns></returns>  private static byte[] HexStringToByteArray(string strHexString)  {      int len = strHexString.Length ;    if ( (len % 2) !=0)    throw new Exception("HexString 字符出错!!");    int byteLen = len /2 ;    byte[] bytes = new byte [byteLen];    for (int i=0;i<byteLen ;i++ )   {    bytes[i] = Convert.ToByte( strHexString.Substring( i*2,2),16);   }    return bytes;  }   可以在加密数据时使用。 在 Util  里有实现 ...[阅读全文]

posted @ | Feedback (6) | Filed Under [ C# MS DotNET ]

摘要:看了思归的文章,感觉很有挑战性.就以Demo 的形式做了一个简单的实现. 自己来写一个Passport 服务器.  第一个问题:     用户的信息的处理.Passport 服务器来处理这些信息,当然了只会是一些简单的用户信息. 比如说性别,电话等 第二个问题:     Passport 服务器与 应用程序之间的数据交换. 看了 MS 的Passport SDK ,发现远没有我们想象的简单.MS 使用了COM 与 Passport 服务进行数据交流, 我们在短时间内也不太可能编写一个 COM 组件来处理.  当然想到了WEB 程序常用的cookie ,因为在DotNet 中的(From 验证模式)中也使用了cookie , 可是因为域的问题.在两个不在同一台机器上的程序是无法共享cookie 的(我没有找到过好的方法).所以我想到了 查询字符串. 第三个问题: Ticket 的生成.当Passport 生成验证 Ticket 后,把Ticket 信息回发(使用“查询字符串“给请求应用程序.应用程序把Ticket 写入cookie (这是应用程序的cookie ,当应用程序使用它时不会有域的问题).  这个 MyPassportAuthenticationTicket 类要自己来写. 如果你想用 FormsAuthenticationTicket 不代替的话也是可以的,但要自己来对它进行加密传送.如果你想用FormsAuthentication.Encrypt方法 那是不行的.因为它的加密算法中加入了服务器machineKey . 第四个问题: 自己来实现一个PassportIdentity ,把功能进行一个封装.实现其中的 LogoTag2 方法.来生成一个登录链接. 最后一个问题: 就是不断完善了,不过有系统还有一个点问题,明眼人一看就知道了,返回链接参数的保持问题.   不知道,有没有更好的方法. 大家一起来讨论一下....[阅读全文]

posted @ | Feedback (18) | Filed Under [ ASP.Net C# ]

摘要:       FxCop(代码警察)  很COOL 的名字。如果你看过MSDN TV 的"Code Correctness with FxCop" 你一定已经知道了它是什么. 我在Tech2003 第一次接到它。当时Zhanbo Sun 非常推荐这个工具,说以后Microsoft 代码质量的提高将依靠这个工具(还听说编写这个工具的团队得到不少的奖励股份喔)。 以前一个在MS 的朋友说,在他们那里(Microsoft 总部)的狂人, 一分钟打 80 个英文单词,好象不多呀,但你要知道他们是以这个速度在写程序(:X 我的天!!)。以前很多公司都是依靠这样的天才的开发人员, 可现在这种事已经一去不复返了。"可信赖计算" 已经成为MS 这样的大公司最重要的事情。       软件的工业级开发:尽最大可能在最短时间内得到功能最强大,系统最安全,性能最好的应用程序,最后利润最大化。       我们来看看 FxCop 怎么和 VS.NET 进行整合。在FxCop(当前版本为1.23) 中有一个命令行工具 FxCopCmd.exe ,利用它就能让FxCop 与 VS.Net 整合运行。在安装完 FXCop1.23(有FX1.0 与 FX1.1版本 ),在安装目录(x:\Program Files\Microsoft FxCop 1.23\Docs\UsingFxCopCmd.htm) 有一篇帮助。设定很容易,但要注意你的 /f 参数,我在Web 工程上使用就碰到不能分析的问题,最后才发现是路径的问题。最Cool 的是 FxCop 有代码引导功能,当你的代码有问题时只要双击出错信息就能跳转到出问题的行(当然必须是在Debug 模式)。      使用这个工具并不是我们想要的,毕竟那是人家的Rules,而且Microsoft 提供的一些Rules 不适合我们的要求; 对于我们 SDK 才是"宝山",自己编写自己的 Rules 。如果你是一个开发主管,把程序员签入的代码用自己的 Rules 一扫描, 这样就完成了代码的常规检查。是不是很省力又踏实呢?...[阅读全文]

posted @ | Feedback (6) | Filed Under [ C# 工作日记 ]

摘要:  现在做的一个程序中要求ASP.net 程序可以使用已经存在的域用户来登录(而且为了与其它程序界面一致一定要使用 Forms 登录),查找了一些相关的资料发现还是可以实现的。    主要还是依靠 advapi32.dll 中的 LogonUser API 函数。 using System.Web.Security;using System.Runtime.InteropServices;[DllImport("advapi32.dll", CharSet=CharSet.Auto)]public static extern int LogonUser(String lpszUserName,String lpszDomain,String lpszPassword,int dwLogonType,int dwLogonProvider,ref IntPtr phToken);public const int LOGON32_LOGON_INTERACTIVE = 2;public const int LOGON32_PROVIDER_DEFAULT = 0;void Login_Click(Object sender, EventArgs E){IntPtr token = IntPtr.Zero;if(LogonUser(UserName.Value,UserDomain.Value,UserPass.Value,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,ref token) != 0){FormsAuthentication.RedirectFromLoginPage(UserName.Value,PersistCookie.Checked);}else{lblResults.Text = "Invalid Credentials: Please try again";}}     其它方面的使用与普通的forms 程序没有太大的区别,也许还有更好的方法。...[阅读全文]

posted @ | Feedback (10) | Filed Under [ ASP.Net C# ]

摘要:   在以前想过这样一个问题:是不是可以动态地改变程序运行的顺序,比如一个流程要经过不确定的几步才能完成。而在设计的时间你基本无法确定它们的顺序。在以前的VC++ 会使用函数指针,而在C#中,我们可以使用Delegate (委托)队列来实现。自己写了一个例子,大概是这样的。       public class Workflow{   public delegate void DoSomething();   public DoSomething[10] somethings;   int stepNum=0;   public DoSomething Run =new DoSomething(run);   public DoSomething Walk = new DoSomething(walk);   public DoSomething Fly = new DoSomething(fly);   public Add(DoSomething something){    if (stepNum < 10){     somethings[stepNum++]= something;    }   }   public static void run{  //run   }   public static void walk{  //walk   }   public static void fly{  //fly   }   public void go{     for (int i=0;i<stepNum ;i++){      somethings[i]();   //运行     }   }} ==================使用时================Workflow workflow = new Workflow();   // 一个小鸟起飞的过程:)workflow.Add(workflow.Walk);workflow.Add(workflow.Run);workflow.Add(workflow.Fly);workflow.Add(workflow.Run);workflow.Add(workflow.Walk);workflow.go();...[阅读全文]

posted @ | Feedback (2) | Filed Under [ C# 工作日记 ]

Full C# Archive