2008.09.30 / 标签:
HttpHandler / 分类:
ASP.NET
应该算是ACCP5.0 ASP.NET中的有技术含量的最后一课了吧,为什么要说是ACCP5.0 ASP.NET中的有技术含量的最后一课,因为知识无尽头嘛!嘿嘿~ 打开VS2005新建一个Web站点,然后在“添加新项”中选择“一般处理程序”接着点击“添加”。HttpHandler程序是以ashx为后缀名的,新创建的HttpHandler的默认内容为:
<%@ WebHandler Language= "C#" Class= "Handler" %>
using System;
using System.Web;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain" ;
context.Response.Write( "Hello World" );
}
public bool IsReusable {
get {
return false ;
}
}
}
<%@ WebHandler Language="C#" Class="Handler" %>//WebHandler指令,标记该处理程序的语言和类名称using System;using System.Web;public class Handler : IHttpHandler {//继承自IHttpHandler接口 public void ProcessRequest (HttpContext context) {//最终处理方法 context.Response.ContentType = "text/plain"; context.Response.Write("Hello World"); } public bool IsReusable {//是否用于其他的IHttpHandler的实例 get { return false; } }}
这段代码说明了context对象可以用来控制输出的内容和类型。 ContentType用于设置程序的输出类型,这段代码可以在页面上出处一段文本“Hello World”(不禁悄悄问一句:为啥无论什么程序语言,写的第一个小程序都是输出Hello World?)且次ashx文件是可以直接访问的。 注意: 实现HttpHandler得功能就必须实现IHttpHandler接口,而且,任何实现了该接口的类都可以用于处理输入的HTTP请求。 从上面的代码我们可以看到,实现该接口需要实现IsReusable属性和ProcessRequest方法。 IsReusable可以用来设置是否可以重用此实例。 ProcessRequest方法是整个HTTP请求最终的处理方法。如下图所示: 这个方法需要一个HttpContext类型的参数,即“http上下文”。它封装了有关一些HTTP请求的所有HTTP特定的信息。在这里,它被用在不同的HttpModule和HttpHandler之间进行数据传递,也可以用于保持某一个完整的请求的相应的一些信息。
2008.09.28 / 标签: / 分类:
ASP.NET
验证码大家应该经常看到吧,比如你在给网站留言,或者注册时就经常可以看到验证码的身影,验证码是很有必要的,因为现在灌水机,信息群发等严重扰乱正常的网站信息管理。 水印应该也都见过吧?它就好比一个我们日常生活中的印章印下的章子。它能够很好的保护发布人的著作权,防止他人盗用。这两个东西如此有用,你想不想知道如何自己动手做呢?想知道就继续看下去吧。 注:需要懂得ASP.NET技术。 1.首先使用VS2005新建一个WEB站点并添加Web用户控件(名为MyCode,语言选择Visual C#)。 2.进入MyCode.ascx文件的设计模式,分别拖入一个Image控件和一个LinkButton控件并将LinkButton控件的
Text属性改为:“我看不清,给我换一张”(你当然可以随便写什么)。 3.双击LinkButton控件进入后置代码中,在该文件中写一个私有的无返回类型的GetCode()方法,其代码如下:
private void GetCode()
{
Bitmap myCode = new Bitmap(500, 150);
string codePath = Server.MapPath( "~" ) + "\\code.jpg" ;
Random rd = new Random();
string line = "" ;
for ( int j = 0; j < 6; j++)
{
int i = rd.Next(3);
if (i == 0)
{
line += char .ConvertFromUtf32(rd.Next(65, 92));
}
else if (i == 1)
{
line += char .ConvertFromUtf32(rd.Next(97, 123));
}
else
{
line += rd.Next(10);
}
}
Graphics g = Graphics.FromImage(myCode);
g.DrawString(line, new Font(FontFamily.Families[rd.Next(2)], 90), new SolidBrush(Color.Red), 0, 0);
for ( int i = 0; i < 10; i++)
{
g.DrawLine( new Pen( new SolidBrush(Color.LightGreen), 3), new Point(rd.Next(500), rd.Next(150)), new Point(rd.Next(500), rd.Next(150)));
}
&
nbsp; System.Drawing.Image water = System.Drawing.Image.FromFile(Server.MapPath( "~" ) + "\\water.jpg" );
g.DrawImage(water, new Point(500-water.Width,150-water.Height));
g.Dispose();
myCode.Save(codePath, System.Drawing.Imaging.ImageFormat.Jpeg);
myCode.Dispose();
this .Image1.ImageUrl = "code.jpg" ;
}
private void GetCode() { //创建验证码位图,宽为500个像素,高为150个像素 Bitmap myCode = new Bitmap(500, 150); //获取位图物理路径 string codePath = Server.MapPath("~") + "\\code.jpg"; //创建随机数 Random rd = new Random(); //验证码字符串 string line = ""; for (int j = 0; j < 6; j++) { //随即产生大于等于0小于3的数 int i = rd.Next(3); if (i == 0) { //若为0则生成A-Z的字符并追加到line line += char.ConvertFromUtf32(rd.Next(65, 92)); } else if (i == 1) { //若为1则生成a-z的字符串并追加到line line += char.ConvertFromUtf32(rd.Next(97, 123)); } else { //其他则生成0-9的数字并追加到line line += rd.Next(10); } } //创建Graphics对象 Graphics g = Graphics.FromImage(myCode); //画上字符串line,且字体随机,大小为90,采用红色实线,从位图的左上角开始画 g.DrawString(line, new Font(FontFamily.Families[rd.Next(2)], 90), new SolidBrush(Color.Red), 0, 0); //给验证码画上10条随机线条加以干扰,黄绿实线,粗度为2,起始位置,终止位置均为不超过位图大小的随机数 for (int i = 0; i < 10; i++) { g.DrawLine(new Pen(new SolidBrush(Color.LightGreen), 3), new Point(rd.Next(500), rd.Next(150)), new Point(rd.Next(500), rd.Next(150))); } //获得水印图片 System.Drawing.Image water = System.Drawing.Image.FromFile(Server.MapPath("~") + "\\water.jpg"); //将水印画至位图右下角 g.DrawImage(water, new Point(500-water.Width,150-water.Height)); //销毁Graphics g.Dispose(); //保存验证码 myCode.Save(codePath, System.Drawing.Imaging.ImageFormat.Jpeg); //销毁位图对象 myCode.Dispose(); //显示至网页 this.Image1.ImageUrl = "code.jpg"; }
4.在LinkButton1_Click事件中调用GetCode()方法,在Page_Load事件中写入: if (!IsPostBack) { GetCode(); } 其意是当第一次打开网页的时候调用GetCode()方法。 5.新建一个Web窗体文件TestMyCode.aspx并进入其设计模式,将刚才创建的用户控件MyCode.ascx文件拖入其中
。 6.运行TestMyCode.aspx文件即可看到如下图中的效果,当单击“我看不清,给我换一张”时便会更换一张新的
验证码。
注:code.jpg为位图文件由编写的代码生成,water.jpg文件为自备水印文件。
2008.09.25 / 标签: / 分类:
ASP.NET
找资料,看看如何实现使用正则表达式屏蔽垃圾信息,找来找去找出来的都不怎么好,有不详细的,有代码缺失的。最后还是找到了微软,先摘过来,大概思路已经有了,只需把下面微软给的样例代码修改一下即可,具体能不能行还不知道,先睡一觉,起来再慢慢研究。 Regex 类 表示不可变的正则表达式。
命名空间:System.Text.RegularExpressions
Regex 类包含若干 static(在 Visual Basic 中为 Shared)方法,使您无需显式创建 Regex 对象即可使用正
则表达式。在 .NET Framework 2.0 版中,将缓存通过调用静态方法而编译的正则表达式,而不会缓存通过调
用实例方法而编译的正则表达式。默认情况下,正则表达式引擎将缓存 15 个最近使用的静态正则表达式。因
此,在过度地依赖一组固定的正则表达式来提取、修改或验证文本的应用程序中,您可能更愿意调用这些静态
方法,而不是其相应的实例方法。IsMatch、Match、Matches、Replace 和 Split 方法的静态重载可用。
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main ()
{
Regex rx = new Regex(@ "^-?\d+(\.\d{2})?$" );
string [] tests = { "-42" , "19.99" , "0.001" , "100 USD" ,
".34" , "0.34" , "1,052.21" };
foreach ( string test in tests)
{
if (rx.IsMatch(test))
{
Console.WriteLine( "{0} is a currency value." , test);
}
else
{
Console.WriteLine( "{0} is not a currency value." , test);
}
}
}
}
using System;using System.Text.RegularExpressions;public class Test{ public static void Main () { // Define a regular expression for currency values. Regex rx = new Regex(@"^-?\d+(\.\d{2})?$"); // Define some test strings. string[] tests = {"-42", "19.99", "0.001", "100 USD", ".34", "0.34", "1,052.21"}; // Check each test string against the regular expression. foreach (string test in tests) { if (rx.IsMatch(test)) { Console.WriteLine("{0} is a currency value.", test); } else { Console.WriteLine("{0} is not a currency value.", test); } } } }
2008.09.24 / 标签:
zblog / 分类:
ASP.NET
自从我给尼克技术博客 换上J-Spring模板加上了点小修改后在IE核心的浏览器下都很正常,自己也没有装FF就没注意去测试是否效果一样好。多亏长河 同学的提醒,FF下文章排行严重错位了,在此感谢一下长河同学,哎~突然不禁感慨,每天来我这里的人也上百人呢,怎么按说用FF来的应该也不少(从流量统计能看到),怎么就没人给我提醒一下呢?郁闷~ 牢骚发完了,我们看看是怎么个回事,为什么IE下显示正常,而FF下就严重错位了。学过HTML的人应该都知道网页默认情况下是流式布局的—从上到下,从左到右。 现在来看看我原先的模板代码:
< ul class = "msg trackback" >
< li class = "tbname" > 文章排行: </ li >
< div class = "function" >
< h3 > 最新文章 </ h3 >
< ul id = "ulRandomsortnew" >
< script language = "JavaScript" type = "text/javascript" > strBatchInculde+=" ulRandomsortnew = randomsortnew ," </ script >
</ ul >
</ div >
< div class = "function" >
< h3 > 评论排行 </ h3 >
< ul id = "ulRandomsortcommonth" >
< script language = "JavaScript" type = "text/javascript" > strBatchInculde+=" ulRandomsortcommonth = randomsortcommonth ," </ script >
</ ul >
</ div >
< div class = "function" >
< h3 > 随机推荐 </ h3 >
< ul id = "ulRandomsortallrand" >
< script language = "JavaScript" type = "text/javascript" > strBatchInculde+=" ulRandomsortallrand = randomsortallrand ," </ script >
</ ul >
</ div >
</ ul >
< ul class = "msg mutuality" >
< li class = "tbname" > < #ZC_MSG231# > : </ li >
< li class = "msgarticle" > < #template:article_mutuality# > </ li >
</ ul >
<ul class="msg trackback"> <li class="tbname">文章排行:</li><div class="function"> <h3>最新文章</h3> <ul id="ulRandomsortnew"> <script language="JavaScript" type="text/javascript">strBatchInculde+="ulRandomsortnew=randomsortnew,"</script> </ul></div><div class="function"> <h3>评论排行</h3> <ul id="ulRandomsortcommonth"> <script language="JavaScript" type="text/javascript">strBatchInculde+="ulRandomsortcommonth=randomsortcommonth,"</script> </ul></div><div class="function"> <h3>随机推荐</h3> <ul id="ulRandomsortallrand"> <script language="JavaScript" type="text/javascript">strBatchInculde+="ulRandomsortallrand=randomsortallrand,"</script> </ul></div></ul><ul class="msg mutuality"> <li class="tbname"><#ZC_MSG231#>:</li> <li class="msgarticle"><#template:article_mutuality#></li></ul>
试了好几下终于找到了办法,把<ul class="msg trackback">…</ul>这段HTML标签用<div style="float:right"></div>套起来,这样一来文章排行就会靠右漂浮,将<ul class="msg mutuality">挤下去并靠左,于是乎FF下也都整齐了。
为什么需要数据验证
数据的插入和更新涉及到用户的操作,难免有用户不了解你的系统,或者用户手误,输入格式不正确的数据。比如价格本来应该是数字“0”,而用户不小心输入了个字符“o”进去,就会出错。所以我们有必要通过技术手段,尽量减少一些可能发生的错误,这就需要数据验证。
阅读全文>>
在之前的[SiteMapPath控件 ] 中其实就已经用到过数据源控件了。
所有的数据源控件都是派生自System.Web.UI.DataSourceControls类。下面是一些常用数据源控件以及它们各自的作用。
阅读全文>>
1, 业务畅想
1) 发表信息:发表各种类别的分类信息(实效性强)
2) 搜索信息:各种分类信息的快速搜索,按照分类的搜索(分类科学)
3) 订阅感兴趣的信息:使用(信息通)可以进行信息订阅
4) 信息评论,信息评级: 对信息可以进行自己的分享的感觉
5) 发表收费信息:通过付费,能够获得置顶等推广
6) 在线沟通(信息通): 所有用户都可以在线等待自己信息的订阅。
基础流量大约500 人/ 天:产生和消费信息:5 条/ 人 30 天最长有效期,
月数据量 30*500*5 = 75000 条(保守估计)
月人流量 (50 + 500)*30 / 2 = 8250 IP
2, 网站架构
采用SQL2000 与 ASP.NET 技术进行开发。
架构采用微软的N 层架构: 简单工厂+ 反射
【工作01 】建立三层架构工程
1, 业务分析与设计
1, 业务名词分析: 信息 用户 评论 信息类别
2, 业务讨论并划出用例图(客户用我们系统能够做什么事情):
【工作02】创建用例图
[ 普通用户用例图 ]
[ 注册用户用例图 ]
[ 管理用户用例图 ]
1, 寻找名词的属性并创建类图
【工作03】创建类图并建立关系
1, 根据类图建立数据库(注意 类之间的关系是用外键的方式在数据库中表示)
【工作04】创建数据库表并建立关系
1, 代码编写
1) Models 层编写, 实体类的撰写
【工作05 】编写Models
2) IDAL 层编写,主要是定义数据访问层的对象都应该具有哪些方法,所以应该定义接口, 名为[I+ 对象名+Service]; ( 注:接口中方法名前不能有public)
【工作06 】编写IDAL
3) SqlServerDAL 编写,实现IDAL 中定义的接口,名为[ 对象名+Service];
【工作07 】编写SqlServerDAL
2, 工具使用
3, 文档撰写
2008.09.09 / 标签:
gridview数据绑定 / 分类:
ASP.NET
在以前的Winform中我们使用DataGridView控件来直接指定数据源就可以显示数据内容。
那么在ASP.NET中,也可以指定控件的数据源来绑定数据。
在ASP.NET中,我们有两种方式可以绑定数据源。
阅读全文>>
2008.09.08 / 标签: / 分类:
ASP.NET
最近开始学ASP.NET了,Mr.Liu给了一个新的用于数据库访问的公共类。 看了一下和以前的公共类的区别: 1.此类的各个属性和方法都静态化了,可以直接通过类名访问了,不再需要去new了。 2.没有了以前的全局的SqlCommand和SqlDataReader了,取而代之的是using (SqlCommand cmd = new SqlCommand(sql, conn))。 3.没有了以前的CloseConnection()方法了。 有些不明白,QQ上问了一下Mr.Liu。 问:是不是少了个关闭链接的方法?查询完也要关闭啊 。 Mr.Liu答:不用,这里使用了CommandBehavior。 问:就是这? using (SqlCommand comm = new SqlCommand(sql, conn)用完就消失? Mr.Liu答:对。 还是有些疑问,不过不问Mr.Liu了,我改问百度大叔了。 问:using (SqlCommand comm = new SqlCommand(sql, conn) 百度大叔说了一大堆给,可是我没发现我想要的。 继续问:CommandBehavior 百度大叔说:我给你两个地方,一个Microsoft,一个CSDN。 告别百度大叔,俺就分别拜访了Microsoft和CSND。 以下分别是这两位大牛给俺的解释: Microsoft
.NET Framework 类库 CommandBehavior 枚举 提供对查询结果和查询对数据库的影响的说明。
此枚举有一个 FlagsAttribute 属性,该属性使其成员值按位组合。
命名空间: System.Data 程序集: System.Data(在 System.Data.dll 中)
C#语法: [FlagsAttribute] public enum CommandBehavior
成员:
成员名称 说明
Default 此查询可能返回多个结果集。执行查询可能会影响数据库状态。Default 不设置 CommandBehavior 标志,因此调用 ExecuteReader(CommandBehavior.Default) 在功能上等效于调用 ExecuteReader()。 SingleResult 查询返回一个结果集。 SchemaOnly 查询仅返回列信息。当使用 SchemaOnly 时,用于 SQL Server 的 .NET Framework 数据提供程序将在要执行的语句前加上 SET FMTONLY ON。 KeyInfo 此查询返回列和主键信息。 SingleRow 查询应返回一行。执行查询可能会影响数据库的状态。一些 .NET Framework 数据提供程序可能(但不要求)使用此信息来优化命令的性能。用 OleDbCommand 对象的 ExecuteReader 方法指定 SingleRow 时,用于 OLE DB 的 .NET Framework数据提供程序使用 OLE DB IRow 接口(如果可用)执行绑定。否则,它使用 IRowset 接口。如果您的 SQL 语句应该只返回一行,则指定 SingleRow 还可以提高应用程序性能。在执行返回多个结果集的查询时,可以指定 SingleRow。在这种情况下,仍返回多个结果集,但每个结果集只有一行。 SequentialAccess 提供一种方法,以便 DataReader 处理包含带有大二进制值的列的行。SequentialAccess 不是加载整行,而是使 DataReader 将数据作为流来加载。然后可以使用 GetBytes 或 GetChars 方法来指定开始读取操作的字节位置以及正在返回的数据的有限的缓冲区大小。 CloseConnection 在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。(这个是我们想要的,其他就当是知识拓展)
CSDN给出的解释:
当 DataReader 处于使用中时,关联的 DbConnection 正忙于为 DataReader 服务。当处于此状态时,除了关闭 Connection 外,不能对其执行其他任何操作。除非调用 DataReader 的 Close 方法,否则会一直处于此状态。如果创建了 DataReader 并将 CommandBehavior 设置为 CloseConnection,则关闭 DataReader 会自动关闭此连接。
OK了,还是CSDN解释的一针见血啊!俺这下完全明白了。 最后给贴出这个数据库访问类:
ASP.NET中的表示层负责内容的展现和与用户的交互。它给予用户直接的体验。当今的许多项目往往表示层是项目成败的关键,而这往往被程序员所忽视。
阅读全文>>