只看标题
第 1 页,共 4 页1234
2012年5月14日,星期一

解决Google Syntax Highlighter与WordPress TinyMCE兼容性问题

给Wordpress安装了Google Syntax Highlighter语法高亮插件,但是发现此插件和Wordpress自带的tinyMCE编辑器冲突。

例如,需要在Wordpress中插入一段C#代码,在编辑器的HTML视图中,需要插入以下内容:

<pre name="code" class="c#">
c# code here.....
</pre>

但是一旦编辑器切换回可视化视图时,编辑器认为pre不应该有name属性,就会过滤掉pre标签的name=”code”属性,而Google Syntax Highlighter插件正是用此属性来识别代码片段。

解决方法是写一个Wordpress的filter给编辑器的pre标签增加一个name属性,是之合法。

将以下代码插入到你的Wordpress主题文件的functions.php文件结尾处:

add_filter('tiny_mce_before_init',
	create_function('$init_array', '$init_array["extended_valid_elements"] = "pre[name|class]";
	return $init_array;'));

C#通过WMI Class获取电脑主板序列号、CPU ID和Bios序列号等硬件信息

很多时候,我们需要获取机器的硬件信息。在.NET平台,我们可以通过WMI Win32 Hardware Classes来轻松的获取你所需要的任何硬件信息。WMI Classes是一个非常庞大的家族,其中的Win32 Classes包含了本机的所有硬件信息,下面的示例代码给出了获取这些信息的一个基本方法,具体的参数可以参考MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/aa389273(v=vs.85).aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Management;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            //MotherBoard SerialNumber
            string motherBoardID = GetDeviceInfo("Win32_BaseBoard", "SerialNumber");
            Console.WriteLine("motherBoardID=" + motherBoardID);

            //Process ID
            string processorID = GetDeviceInfo("Win32_Processor", "processorID");
            Console.WriteLine("processorID=" + processorID);

            //BIOS ID
            string biosID = GetDeviceInfo("Win32_BIOS", "SerialNumber");
            Console.WriteLine("biosID=" + biosID);
        }

        private static string GetDeviceInfo(string wmiClass, string wmiProperty)
        {
            string result = string.Empty;
            ManagementObjectSearcher search = new ManagementObjectSearcher("SELECT * FROM " + wmiClass);
            try
            {
                foreach (ManagementObject service in search.Get())
                {
                    //Only get the first one
                    if (result == string.Empty)
                    {
                        try
                        {
                            result = service[wmiProperty].ToString();
                            break;
                        }
                        catch
                        {
                        }
                    }
                }

                return result.Trim();
            }
            catch
            {
                return string.Empty;
            }

        }
    }
}

在引用此段代码之前,项目必须引入System.Management.dll程序集,然后我们通过创建ManagementObjectSearcher实例通过WMI查询语句来获取所需要的信息。

注意:并不是所有的机器和硬件都支持获取CPUID,主板序列号,Bios序列号等硬件信息,不同的机器和硬件获取的信息可能相同,也可能是空字符串。如果想通过机器硬件信息来生成一个唯一的机器标识,建议使用多个硬件信息的组合。

2007年9月17日,星期一

发现 SQL Server 2005 Reporting Services 的一些BUG

1. Float 参数的BUG

当你在Report中设置某个参数类型是Float时产生此BUG,Reporting Service在显示Float参数时会出现莫名奇妙的四舍五入成两位小数,索性的是这种错误只停留在显示上,报表的内部运算仍旧按照参数的实际小数位数进行运算。

解决方法是将Float 参数改为string类型,然后在用的时候将参数转换为小数。

2.更新Report,其Linked Report参数不能同步更新

Linked Report虽然使用的是Report的Definition,但是它自己有它自己的参数设置。建立Linked Report时,RS会复制Report中的所有参数给Linked Report一份。此问题出现在当你在报表服务器上使用一个Report建立了Linked Report后,修改此Report的参数,例如添加一个下拉列表值,修改参数类型等等操作,随后使用覆盖Update的方式更新报表服务器上的Report时,其所建立的Linked Reports参数不会自动更新,从而出现参数不同步的现象。

目前此问题暂时没有好的解决方法,比较普遍的做法是删除Report的所有Linked Reports,重新建立,或者逐个修改每个Linked Report的Report Definition,使其Link到更新过的Report。我已经就此写了一个自动查找并更新Linked Report的小工具,需要的朋友可以发Email给我。

2006年9月15日,星期五

基于UML和ASP.NET实现三层B/S结构学籍管理系统开发

架构设计是软件开发的基础,并往往决定一个项目的成败。三层结构是目前流行的架构设计模式,它是在由Buschmann等提出的“层模式”[1]基础上发展起来的,由表示层、业务逻辑层和数据访问层三个层次结构组成。它通过分解来管理问题的复杂性,同时还可以有效地重复使用业务逻辑并保留与昂贵资源(如数据库)的重要连接[2,3]。

基于ASP.NET能够充分发挥其完全面向对象的技术特点,实现三层结构B/S系统架构,从而提高开发效率,增强系统的可维护性和扩展性。本文结合一个“学生成绩管理系统”的开发,研究如何基于UML进行三层B/S结构的系统建模,及其在ASP.NET下的应用实现。

1 三层结构系统模型
架构设计是非常高级的设计,也是系统设计的关键,主要是定义和说明包(子系统),以及包与包之间的相互依赖与通信机制。系统构架模型的合理与否将决定系统的可维护性、扩展性和开发效率。

包通常所需要处理的是要么是一个具体的功能区域(业务逻辑),要么是一个具体的技术区域(技术逻辑)。业务逻辑主要考虑的是对系统业务功能的实现,而技术逻辑则是进一步考虑用户界面、数据库或通信机制等形成的技术方案。把技术逻辑和业务逻辑区分开来是极其重要的,这是为了当修改程序的某一部分时不会对另一部分产生影响,更加便于进行“复用”,同时易于应对来自业务逻辑的变更需求。

三层结构是一种成熟、简单并得到普遍应用的应用程序架构,它将应用程序结构划分三层独立的包,包括用户表示层、业务逻辑层、数据访问层。其中将实现人机界面的所有表单和组件放在表示层,将所有业务规则和逻辑的实现封装在负责业务逻辑组件中,将所有和数据库的交互封装在数据访问组件中。其结构如下图1所示:


图1 三层结构示意图

三层结构是一种严格分层方法,即数据访问层只能被业务逻辑层访问,业务逻辑层只能被表示层访问,用户通过表示层将请求传送给业务逻辑层,业务逻辑层完成相关业务规则和逻辑,并通过数据访问层访问数据库获得数据,然后按照相反的顺序依次返回将数据显示在表示层。

2 三层B/S结构的学生管理系统开发
下面通过一个学生管理系统的开发,说明三层B/S结构系统从UML建模到基于ASP.NET进行实现的完整开发过程,UML建模工具采用的是Rational Rose。

 2.1 需求分析
软件需求分析是系统开发的第一步也是最重要的一个环节,其基本任务是准确地回答“系统做什么?”这个问题,这需要在对用户需求进行充分调研的基础上,深入理解并描述出软件的功能、性能、接口等方面的需求,可以使用UML建模作为需求分析和系统设计的有效方法。

分析的目的是为了获得和描述系统中所有的要求,因此分析阶段是一种典型的与用户或客户合作的过程,通常由开发人员同用户或客户共同完成。在这个阶段,开发人员不应该考虑代码或程序实现的细节,而应该把精力放在对现有业务逻辑的理解上,通过与用户之间的充分沟通,逐步理解并描述出得到用户确认的系统模型,包括用例模型和领域(domain,系统中关键的类)模型。

2.1.1 用例模型

软件开发人员在对用户进行需求调研的过程中,用户往往并不能立即准确描述出未来系统应该提供一些什么样的功能。因此,需要开发人员理解和分析需求,并将系统应该具有的功能通过用例图直观的描述出来,方便用户理解并做出评判,开发人员从而可以根据用户的反馈不断调整用例模型,直至完全正确、充分描述清楚系统功能。

用例建模主要是分离出系统的活动参与者(Actor)和用例(Use Case),用例是指对系统提供的功能的一种描述,而活动参与者是那些可能使用这些用例的人或外部系统,通过用例图可以描述出系统外部的执行者、系统的用例,以及它们之间的联系。本学生管理系统的用例图见图2。

用例模型还需要进一步对每个用例进行详细描述,进一步说明用例的名称、基本事件流和备选事件流、前置条件和后置条件等,并形成文档。限于篇幅,这里就不多说了。

 图2 用例图

2.1.2 领域建模
分析过程中还要详细地列举领域(domain ,系统中关键的类),为了进行领域分析,需要充分理解用例模型,也可以与用户及领域专家组织一次集体研讨会谈,尝试找出所有必须处理的关键概念以及它们之间的相互关系,并最终分析出域类图。下图3为本系统的域类图。

 图3 域类图

需要强调的是:在本阶段,对领域进行分析的类图还是处于“草图”状态。定义的操作和属性不是最后的版本,只是在本阶段看来比较合适。后期将通过动态行为分析不断得出新的操作,这是一个逐步完善和发展的过程。

 2.2 系统设计
系统设计的目的是产生一个可用的、完整的解决方案,并且能够比较容易地将方案转换成程序代码。这个阶段在三层结构的架构设计模型基础上,将考虑所有的实现技术问题,对分析阶段的模型进行扩展和细化,分析阶段定义的类进一步扩充,定义新的类来处理技术方面的问题,并形成最后的UML模型。

推动不断进行详细设计的方法是对每个用例进行动态建模,描述如何通过类图中的对象协作实现用例中的功能,由于一开始对系统的认识是很不够的,前面建立的类往往随着动态建模的深入,发现存在缺陷或不够完整,需要对分析中得到的域类图进行不断修正和调整,扩展形成业务逻辑包。同时,随着对用户界面、数据库访问等技术实现的深入建模,不断建立新的用户界面类(如窗体、控件)和数据访问类,形成用户界面包和数据访问包。

本学生管理系统经过详细设计后,在域类图基础上进行扩展后形成的业务逻辑包类图如下图4所示。


图4 业务逻辑包类图

新建立的数据访问包类图如下图5所示。所有的数据访问类都定义了一个基类DBCommon,该基类包含属性DBConnectionString,通过该属性可以获得数据库连接字符串。还包括一个方法GetDataView,可以实现在数据库中执行查询获得一个DataView。这些属性和方法被所有的数据访问类继承,可以直接使用。

图5 数据访问包

关于用户界面包的类图比较简单,主要是通过界面设计,设计出窗体及控件等界面元素,并根据动态建模时需要涉及的用户界面访问动作,定义所引起的相关事件,这些方面都在窗体类中进行定义,并组成用户界面包,这里就不详细介绍。
动态建模通常采用的方法是使用UML中的时序图描述用例,一个时序图针对某个用例中的一个“场景”进行分析。所谓“场景”是指一个用例中事件发展的一条路线。根据活动参与者的不同输入或行为,通常一个用例会有多个“场景”,也就需要分析出多个时序图。通过时序图描述一个场景中各个对象之间所进行的通信,同时可以分析出系统中相应的类需要具备的操作,从而不断扩充和细化类的设计。如果需要进一步描述类的状态变化情况和操作流程,可以使用UML中的状态图和活动图。


 图6 登录场景

动态建模时产生的时序图较多,这里无法一一阐述。图6给出了登录系统场景的时序图,在用户界面包中定义了一个LoginForm类,其对应的Web窗体为用户登录窗体页面Login.aspx,图6描述了在该窗体中实现用户登录的场景。

 2.3 基于ASP.NET的系统实现
前面系统设计动态模型时,通过时序图已经对每个用例的各项功能所涉及的场景进行了详尽的描述,按照时序图的规定把每个用例都分别进行编码实现即可。下面结合学生管理系统中的“登录系统”用例,介绍基于ASP.NET进行系统实现的方法。
首先需要考虑分包,ASP.NET中包对应的就是命名空间。在本学生管理系统中,规定业务逻辑包的命名空间为ResultManage.BusinessRule,数据访问包的命名空间为ResultManage.DataAccess,而用户界面包的命名空间为ResultManage.Web。

然后进行业务逻辑包和数据访问包中相关类的设计,对于“登录系统”用例,从上图6的登录场景时序图中可以看出,相关的类有业务逻辑包的Users类和数据访问包的UsersDB类,分别对这些类的属性和方法进行定义和实现,并设计一些测试用例或测试程序对其进行单元测试。

最后按照用户界面包和上图6的登录场景时序图中的规定,对用户登录窗体页面Login.aspx进行设计实现,其实现登录的代码如下所示:

private void btnLogin_Click(object sender, System.EventArgs e)
{
//获得用户登录信息
string UserName = txbUserName.Text;
string Password = txbPassword.Text;
try
{
if (Users.Login(UserName , Password)) //检查用户登录信息
{
//创建身份验证票
FormsAuthentication.SetAuthCookie(UserName, false);
//显示欢迎信息
ShowWelcomeMessage(UserName);
}
else
{
Message.Text = "用户登录失败!";
}
}
catch (SqlException sqlexception)
{
//提示数据库操作错误信息
Response.Write(sqlexception.Message);
}
}
//代码中对于业务的处理,通过调用业务逻辑包Users类的Login方法实现登录信息的检查,其代码如下:
public static bool Login(string UserName , string Password)
{
if (UserName == "")
{
return false;
}
else
{
//检查数据库中是否存在符合的用户
return UsersDB.CheckLogin(UserName , Password);
}
}

上述Users类的Login方法的代码中,首先进行业务逻辑检查,判断用户名是否为空,涉及数据库访问则通过数据访问类完成,通过数据访问包的UsersDB类的CheckLogin方法从数据库中检查是否存在符合相应登录信息的用户。

前面已经提到,包括UsersDB类在内的数据访问层所有类都从一个基类DBCommon继承,该基类封装了所有数据库访问类公共的特性,其中包括定义了公共属性:数据连接字符串DBConnectionString。UsersDB类的CheckLogin方法中使用DBConnectionString进行数据库的连接,并调用数据库中存储过程CheckLogin查找用户登录信息是否正确。

3 结束语
本文介绍了三层B/S结构系统的UML建模和基于ASP.NET进行实现的过程和方法,实现的三层结构不仅程序逻辑上结构清晰,而且由于容易发生需求变更的业务逻辑部分实现了分离,因此具有更强的可扩展性和可维护性。同时这种系统在部署时具有很强的灵活性,可以将各个包分别编译成.NET组件,安装在多台服务器。较典型的是用户界面包安装在Web服务器,业务逻辑包安装在应用服务器,数据访问包安装在数据库服务器或进一步分离,从而实现多级分布的部署方式,实现更好的可伸缩性和安全性,满足大规模的企业级B/S应用系统的需求。

2006年8月15日,星期二

Windows XP SP2的WRSF安全特性导致IE使用window.open和window.showModalDialog的status=no无法关闭状态栏

前段时间在忙一个asp.net物品管理系统,其中用到了window.showModalDialog()来弹出模态的对话框,其中使用了status=no使对话框不显示难看的状态栏,但是发现在Intranet区域即本地网络(http://localhost)原本使用好好的,但是到了Internet区域状态栏却又显示出来了,怎么改代码都无济于事,似乎status=no失去了作用。后来在Microsoft网站上找到了如下资料:

资料源地址:http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx#E6SAE

Internet Explorer Using Feature Control Registry Settings with Security Zone Settings

What do Feature Control Registry Settings and Security Zone Settings do?

Feature Control registry settings are provided in Windows XP SP 2 so that a specific process can be configured to opt-in to a particular security feature. In the following example, Internet Explorer has been configured to use the Windows Restrictions security feature(WRSF):

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_WINDOWS_RESTRICTIONS] iexplore.exe=1

Once a process has been configured to use a security feature, the security feature is running and security zone settings can be applied for more precision, if implemented for that feature. In the Security Settings tab of Internet Options, the user can adjust these settings for many of the new Windows XP SP2 feature controls. If you selectEnable, it lowers the security settings and allows the behavior to run less securely, or in the same manner as it did in Windows XP Service Pack 1. For example, if Windows Restriction is set to Enable in the Intranet zone, Windows Restrictions will not be applied — script-initiated windows can be opened as freely as in Windows XP SP1. The Windows XP SP2 restrictions can be applied again by setting the security zone setting to Disable, which blocks the less-secure behavior while the feature control is enabled for that process.

For example, if the feature is turned on for Windows Restrictions, this feature:

Forces the status bar to be present in script-initiated Internet Explorer windows with the title bar [those that were created with window.open()].
Constrains the size and positioning of script-initiated Internet Explorer windows that have title and status bars to ensure that the title bar and the status bar in these windows is always visible to the user.

我特意将关键的话语加粗变红,原来这是Windows XP SP2的新安全特性Windows Restrictions security feature(WRSF),为了安全,SP2特意强制将弹出的标题栏和状态栏都显示,让浏览者知道自己正在访问哪个地址哪个网页,防止恶意欺骗。此特性对Internet区域有效,而对本地的Intramet区域无效,就是说在XP SP2下使用代码status=no控制窗口无状态栏已经无效了。解决方法除了上述的修改客户端注册表键值关闭WRSF特性,或者还有一种解决方法就是在客户端上将系统的站点地址加入IE属性“安全”选项中的“本地Intranet”区域。不过这样好像就失去了B/S系统的最大优点,客户端这么多,不可能要求每个使用系统的人都这样设置,所以只能继续让状态栏显示。

只看标题
第 1 页,共 4 页1234