2008-05-29 17:07
需求:在一个人事管理系统中,所有的照片数据均已image形式保存在数据库。使用image控件在员工个人资料中显示照片。
首先建一个显示图片的文件photo.aspx,其中photo.aspx.cs文件这样写:
private void Page_Load(object sender, System.EventArgs e)
{
string hrid = Request.QueryString["hrid"];
SqlConnection con = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"].ToString());
con.Open();
String select = "Select photo from hrsdb.dbo.EplPersonnelArchives where hrid = " + hrid;
DataSet ds = new DataSet();
byte[] photo = new byte[0];
SqlDataAdapter da = new SqlDataAdapter(select,con);
con.Close();
da.Fill(ds);
DataRow dr;
dr = ds.Tables[0].Rows[0];
if(dr["photo"].ToString() != "")
photo = (byte[])dr["photo"];
Response.ContentType = "image/jpeg";
Response.BinaryWrite(photo);
}
在个人资料页面调用这个页面this.Image1.ImageUrl = "photo.aspx?hrid=" + hRID;
注意:
1. Response.ContentType 为image/jpeg,而不是网上资料中的jpg。不同的ContentType 会影响客户端所看到的效果.默认的ContentType为 text/html 也就是网页格式.application/octet-stream则是以下载文件形式。http://www.7747.net/kf/200801/23224.html
2. 使用Response.BinaryWrite()方法,而不是Response.Write()方法。BinaryWrite 方法在不进行字符转换的情况下直接向输出写数据。http://www.w3school.com.cn/asp/met_binarywrite.asp |
2008-05-02 12:52
-----------------
--in Redhat9
--by Ron
--update 5-2, 2008
-----------------
在安装之前, 请检查QT Designer是否安装. 如果没有, 将安装盘中开发工具包里的QT/KDE开发环境安装. 这种方式下, 一路configure, make, make install就ok了. 否则, 你将面对以下问题:
1. t_x11_p.h 没有这个文件或者目录
//@ Xlib.h库缺失
---------------------
解决办法:安装xlibs-dev,需要到网上下。
代码:
sudo apt-get install xlibs-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
现在没有可用的软件包 xlibs-dev,但是它被其它的软件包引用了。
这可能意味着这个缺失的软件包可能已被废弃,
或者只能在其他发布源中找到
E: 软件包 xlibs-dev 还没有可供安装的候选者
---------------------
1) xlibs-dev
2) apt-get
---------------------
Redhat 9 并没有 apt-get
1- wget http://ftp.freshrpms.net/pub/freshrpms/ ... -0.5.5cnc6-fr1.i386.rpm
2- rpm -ivh apt-0.5.5cnc6-fr1.i386.rpm
3- apt-get update
4- apt-get install portmap
升级 glibc
apt-get install glibc
apt-get dist-upgrade (全面升级)
---------------------
安装xlibs-dev,
因为所由的xlibs-dev均为deb格式, 使用alien, 将deb格式的包转化为rpm格式的.
alien version 8.69
// 安装dpkg, 和dpkg-devel
// dpkg version 1.4.18
alien使用命令: ./alien.pl -r xxx.deb
2. kssl.h:72:18: krb5.h 没有这个文件或目录
//@ openssl库缺失
-----------------------------
As is described in the FAQ and the documentation and as quickly found with
a Google search for "jabber krb5-devel"...
make CPPFLAGS=-I/usr/kerberos/include
because RedHat moved the krb headers and libraries from their expected
location.
http://www.jabberdoc.org/section04.html
-----------------------------
// 安装jabberd
// version 2.2.8
// libidn not found 安装libidn v0.5.18
安装openssl
Openssl openssl-0.9.6-19.src.rpm 编译安装
no rule to make target asm/shal-586.pl --搞不定了...
-----------------------------
openssl是在运行example时用到的库文件, 如果不需要运行QT自带的example, 在make时, 加上-no-openssl即可通过编译.
|
2008-04-27 17:25
本文中的例子来自与《精通正则表达式》,但我需要用vim中的正则方言来实现他们,以学习vim正则语法。每一个例子,我都会尽量给出所使用表达式所代表的意义。
1. 为数值添加逗号。
英文中,通常将1234567890这样的数字用逗号三位一组地分割为1,234,567,890以方便阅读。本例用vim替换功能自动实现逗号的添加。
:%s/\d\@<=\(\(\d\d\d\)\+\>\)\@=/,/g
使用到的语法点包括:
1)零宽断言\@=与负向零宽断言\@<=,用于匹配位置,而不是匹配文本。
2)在所有行进行替换:%s,在当前行进行替换:s,在当前行所有未匹配文本中替换/g
3)因为零宽断言匹配的只是位置,所以/g可以为数值添加多个“,”。
4)\(\(\d\d\d\)\+\>\)表明从匹配点到数值的结尾这个区间内,一共有3的倍数个数字。
5)\d\@<=\(\(\d\d\d\)\+\>\)\@=表明数值在匹配点前面有数字\d\@<=,后有3的倍数个数字。
:%s/\d\@=\(\(\d\d\d\)\+\d\@!\)\@=/,/g
翻译过来就是,如果某个匹配点的前面是数字,匹配点和数值最后一个非数字点之间,有3的倍数个数字,那么就在这个匹配点处,加上","
错误解法:
:%s/\d\@<=\(\d\d\d\)\+\)\@=\d\@!/,/g
2. 贪婪与懒惰
默认情况下,Vim使用贪婪模式进行匹配,也就是尽可能多地吃进字符。比如使用/a.*b可以匹配axbxb中的axbxb。如果指向匹配axb,那么应该将*替换为\{-},即/a.\{-}b,表示尽可能少地吃进字符。
参考资料:
man vim pattern http://man.chinaunix.net/newsoft/vi/doc/pattern.html 这是最完整的学习资料 |
2008-04-27 08:55
本文记录在这次项目中的一些小Tips。
1. 基础的重要性在于,当你需要的时候,它就会蹦达出来和你捣乱。比如那次算百分数数时花费的一天功夫,概因对基础数据类型不熟悉。比如看到这样一个需求,遍历一个控件的所有后代控件,有效率要求,我就不会。
2. 在使用一个对象之前,通常要进行非空判断。我的做法是使用if()来单独判断,但实际上这个判断可以和这个对象的其他判断用&&连接起来。&&会从左向右检查是否非空。
3. 如何在改变下拉框的选项后,刷新子页面?可以在页面的<body>中写一个onload函数,设置下拉框的autoPostBack属性为true,并在onload函数中重新加载子页面,ok了。 |
2008-04-21 22:00
本文总结项目中数据库操作相关的一些经验教训,特别是最近一周以来的。项目集成时,数据库出过几次莫名奇妙的错误,而我自己,也因为数据库表设计不当,而屡尝苦果。
一、数据读取
常用两种方法从数据库读取数据。1. 直接读取。使用SqlConnection建立一个数据库连接con,将con和查询语句select封装到一个SqlCommand对象command中,并使用SqlAdapter对这个command进行包装,包装后得到适配器对象da,使用da.fill()函数,将查询结果读到DataSet中。
2. 使用存储过程。将查询语句保存到存储过程中,以后每次调用数据库中的存储过程。本质上,这种方式和1相同,但将cmd.CommandType = CommandType.StoredProcedure,然后SqlAdapter将会去数据库中查找相应的存储过程,而不是1中的直接使用select查询语句。
对于第2种方式,可以将数据读到DataSet中,然后再对DataSet直接操作。或者使用dataReader = cmd.ExecuteReader();将数据对到DataReader中,然后再从DataReader将数据保存到业务类中。
二、表、视图、存储过程
1. 在设计表的时,应考虑完备。比如备用字段、字段长度等因素。
2. 视图并不能带来效率的改善,但可以很好地让逻辑更清晰。
3. 存储过程不应该存在调用关系。否在在集成时,极易出错。
4. 尽量将数据库连接参数写道web.config里,而不是直接写在程序中。
源代码1
public static int GetQueryList(string strQuery,out DataSet details)
{
SqlConnection con = null;
string select = strQuery;
details = new DataSet();
try
{
if (con == null)
{
con = new SqlConnection(ConfigurationSettings.AppSettings["HrsConnectionString"]);
con.Open();
}
SqlCommand cmd = new SqlCommand(select, con);;
DataSet dsTemp = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dsTemp);
details = dsTemp;
}
catch(Exception e)
{
ComLog.ErrSet("","","EplCheckHistory.cs[GetQueryList()]",e.TargetSite.ToString() + e.Message);
details = null;
return 3;
}
finally
{
if (con != null)
{
con.Close();
con.Dispose();
con = null;
}
}
return 0;
} |
2008-04-17 22:09
合同预警是我在项目组负责的第一个模块,到今天为止,终于完工。回头看,现在的这个版本和我最初的设想有较大的差异。整个模块主要有两个页面组成,预警信息展示和预警条件设定。前者,以列表的形式显示所有符合预警条件的合同,后者,对预警的条件进行编辑。合理好用的编辑条件是这个模块的关键,本文将对预警条件编辑页面的一些设计思路予以回顾。
图一 图二 
将预警条件分为A/B两类。A类预警条件在新增合同时自动检查,包含合同签订年限和合同签订次数两个选项。如已签订3次合同的人员在签新合同时予以提醒。B类预警条件用于本文开篇所述预警信息的展示。可是设置复杂的组合条件,如固定期限型,将在一个月之内到期的合同予以提醒。
预警条件由(HRID,SerialNumble),Brief,Title,Content,EWType,SqlSentence,SharePerson这几项组成。HRID为当前操作员的唯一性编号,也是该预警条件的设立者。SerialNumber为该操作员所拥有的预警条件序号。这两个字段为预警条件表的主键。Brief为预警的简称,Title和Content可以对预警条件详细说明,并且使用@ContractName@的形式来表现合同的具体信息。SqlSentence为根据查询条件生成的查询语句。考虑预警条件编制较为复杂,设立SharePerson字段,将该预警条件共享给其他人使用,也即该预警条件的使用者,默认为预警条件的设立者。在合同预警页面中,读取这个字段的内容,来获取操作员所能够使用的预警条件。(like %hrid%)
预警条件的共享(使用者)设计比较有意思。最初没有考虑到要将预警条件共享给其他人使用,现在即使增加一个字段,存储共享者的hrid,也很麻烦。记录之间高度关联,增加一个共享者,需要在条件设定者里加字符,同时需要将条件赋给共享者,在表中增加一条记录。而删除共享者时,则更为麻烦,所有预警条件没有唯一性编号,很难保持数据一致性。之后考虑新增一张表存储共享关系,但这样对现有程序结构改动太大。最后发现,只要在查询预警信息时使用SharePerson like %hrid%的形式即可,而现有的预警条件编辑页甚至不用作太多变化。这种设计实际上是将条件的编写者和使用者分离,大致实现胡老师所说的预警条件库。
以上合同预警的大致设计思路。在中途多次变更,bug也出现过无数回,最初的原版本甚至花费了一个月的时间。与初次上手不熟悉环境有关,但更多的是一些可避免的原因造成。存在以下问题:
1)程序bug太多。头一个月在原型出来后,改bug就改了一个多星期,自己很疲。其实多数bug细心一些都是可以避免的。写程序,是一门细致的学问,很精确,毛躁不得。写程序之前,先想一想思路,再没有理清楚思路之前,不要动手。
2)设计表的时候,不够合理,昨天甚至发现,存放预警信息的表,甚至连主键都没有。如果都是从页面中对表进行操作自然没有问题,如果有人直接修改数据库呢?再有没有考虑到扩展性,EWType、SharePerson都是后来才加进来的。
3)独学无友,何况我只是一个初学者。事实上,现有的设计很多都是讨论出来的,一个人扛着时总是容易陷入死胡同。
4)不断求精,不要怕麻烦。有时因为程序写起来麻烦,所以在设计时就避重就轻,到头来还得还是自己。
5)嗯,基础很重要,体现了对程序的敏感程度。
6)在设计程序时,可能有很多条路可以达到最终的目标,但应学会选择一条最简洁的路。如共享者选择页面就是直接调用之前的页面,而不是我自己设计的那个页面。
以上! |
2008-04-16 14:16
在《项目回顾(一)权限系统设计》中,我谈及本项目合同管理的权限系统的结构。这篇日志记录一个具体的应用。
在我们这个项目中,有个“合同信息”的页面,用于合同的查询和流程控制。如果没有相关角色,则无法对这个页面进行操作,重定向至重新登陆页面。在进入这个页面之后,出“新增合同”外,其余按钮均不用。选中某一行的合同后,根据该合同的状态,以及当前操作员所具的角色,决定是否将最下面的按钮状态更改为可用。

在实际设计程序时,将合同状态和操作员角色对按钮的影响分开考虑。1)某一种状态下,有几个按钮是可用的。比如对选择一份录入状态的合同,有综合信息、合同增加、删除、修改、依合同创建、请求审批6个按钮可用。将合同状态-按钮状态对应关系用一个二维bool数组status[6,10](第0行为页面初始化)保存起来。2)再考虑角色对按钮的影响。综合信息按钮5个角色都可以使用,而领导审批按钮,则只有审批人、管理员、超管能够使用。用“||”将能够操作某个按钮的角色联系起来。如btnCheck.enabled = checker || manager || superManager。之后将这两个影响因素用“&&”连起来。如一份“录入”状态的合同,其请求审批的按钮可用性用(checker || manager || superManager ) && status[1,5]。本文最开始的问题则基本解决。另外,不同操作员可能对应不同的部门,则一因素放在查询中考虑,即只能查询出所管理部门的合同。
角色对按按钮状态的影响,还可以用上一篇文章中的质数法来解决。比如综合信息对应2,合同增加对应3,删除对应5…合同审核对应11,而将2*3*11作为权限值赋给合同审核人角色,并保存到数据库。在进入本页面时,对某一个角色所具有的权限值解析为单个的质数,也即所能够进行操作的按钮。我这里没有用这种方式,首先因为按钮的状态只在这个页面使用,而不用保存到数据库,再者按钮较多,在对权限值进行解析时,比较费劲,得不偿失。实际上我也正是因为前一天见过这种质数法,才在碰到问题时,想到用bool值来判断,可见其实想通。
这个设计采用表驱动的方法,将合同状态对按钮状态的影响,保存在单独的一张表中,单独处理。程序简洁,逻辑清晰。 |
2008-04-12 23:19
晚上写页面时,碰到个需求。需要光标移动到DataGrid的某一个Cell上时,文字变颜色,移开后回到原来的样子。在网上找了一些资料,可以在给DataGrid绑定数据之前,用ItemDataBound事件进行绑定,但大都是以设置一行或一个单元格的背景颜色为例来讲述,而且我自己也试验成功。但设置字体颜色,需要设置style.color,比较郁闷。后经人指点,发现项目中有的地方已经实现了这个功能。:( 白忙活了!
可以定义一个Css的style,然后在这个style里面,加入javascript的函数的链接(behavior: url(../Css/dataGrid1.htc),在这个里面写鼠标移动后的效果。如果哪一个单元格需要在鼠标滑动时可以变色,设置它的CssClass就行。
觉得有些神奇。费了好大劲的东西,原来可以这样做。再回想起当初那个失败的导航条,真需要好好学习JavaScript。 |
2008-04-11 23:02
考虑到以后发代码的时候,语法高亮会更好看一些。找了一些语法高亮工具,最舒服的,应该是C++2HTML,它在线将C++代码转化为语法高亮后的HTML文件,注意到颜色采用内联的信息嵌在代码里面的,所以可以在需要的地方直接使用。下面是效果图。
#include<iostream>
using namespace std;
int main(int argc, char* argv[]){
cout<<"Hello, World! "<<endl;
}
因为不需要上传数据,所以你可以将这个网页保存到本地,以后每次有需要的时候,直接用浏览器打开,然后就可以使用了。不过遗憾的是只支持C++,所以只能是很好不强大了。
update:在给大文件(3000+)语法高亮时,这个工具变得有些慢。这个慢是对IE而言,如果用Firefox打开,速度之间的差异你几乎体验不到。 |
2008-04-11 20:10
|
|
hawkingliu
男, 23岁
湖北 武汉
上次登录: 2天前
加为好友
|