浪漫骑士必胜

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

asp.net-模拟登陆

今天我们继续上一次文章当中的内容: ASP.NET(get和post比较)讲解一下模拟登陆的情况.新建两个页面.

                       

一、画好用户登录界面

同时换下请求的地址。

获取用户信息及判断代码插入位置:

View Code
 1 <%@ WebHandler Language="C#" Class="_06_login" %>
 2 
 3 using System;
 4 using System.Web;
 5 
 6 public class _06_login : IHttpHandler {
 7     
 8     public void ProcessRequest (HttpContext context) {
 9         context.Response.ContentType = "text/plain";
10         //在服务其上获取用户输入的用户名和密码判断是否正确。
11         string name=context.Request.Form["name"];
12         string pwd=context.Request.Form["pwd"];
13 
14         if (name=="admin"&&pwd=="admin")
15         {
16             context.Response.Write("登录成功");
17         }
18         else
19         {
20             context.Response.Write("登录失败");
21         }
22     }
23  
24     public bool IsReusable {
25         get {
26             return false;
27         }
28     }
29 
30 }

二、登录演示

如果用户登录失败了,用户想重新登录,为什么要把判断写到服务器上面呢?JS判断没法判断数据库去,所以只能放到服务器上面。

还想在用户登录失败之后,返回登录页面怎么做呢?

第一种解决办法拼html。

登录失败显示登录界面代码插入位置:

View Code
 1 <%@ WebHandler Language="C#" Class="_06_login" %>
 2 
 3 using System;
 4 using System.Web;
 5 using System.Text;
 6 
 7 public class _06_login : IHttpHandler {
 8     
 9     public void ProcessRequest (HttpContext context) {
10         context.Response.ContentType = "text/html";
11         //拼html
12         StringBuilder sb = new StringBuilder();
13         sb.Append("<html>");
14         sb.Append("<body>");
15         //action就是提交给自己
16         sb.Append("<form action='06-login.ashx' method='post'>");
17         //双引号改成单引号
18         sb.Append("用户名:<input type='text' name='name' /><br/>");
19         sb.Append("密码:<input type='text' name='pwd'/><br/>");
20         sb.Append("<input type='submit' value='login'/>");
21         sb.Append("</form>");
22         sb.Append("</body>");
23         sb.Append("</html>");
24         
25         //在服务其上获取用户输入的用户名和密码判断是否正确。
26         string name=context.Request.Form["name"];
27         string pwd=context.Request.Form["pwd"];
28 
29         if (name=="admin"&&pwd=="admin")
30         {
31             context.Response.Write("登录成功");
32         }
33         else
34         {
35             context.Response.Write("登录失败");
36         }
37         //输出登录
38         context.Response.Write(sb.ToString());
39     }
40  
41     public bool IsReusable {
42         get {
43             return false;
44         }
45     }
46 
47 }

三、登录失败提示用户演示

想下登录失败之后怎么就更省事儿,更方便?

登录失败之后就把用户输入的用户名和密码清空了,这样不好,用户就不知道自己输入的是什么了。

GIF动画录制工具绿色版本,下载即可用:

我们做个把用户名显示出来的界面。

刚才登录之后,为什么输入的信息都没了呢?

 

四、为什么文本框里面没有值

 

五、给文本框返回值的写法

 

六、返回值的演示

我们都是运行html,要是直接运行一般处理程序会直接显示登录失败。

这样写特别的不舒服,得不停的拼html字符串。

 

七、不拼html,直接运行一般处理程序

 

八、再改下html页

运行html和一般处理程序,我们发现都有问题,先看下运行html。只有第一次运行的时候有问题,怎么解决呢?

只能再ashx里面来完成,第一次的时候替换成空,什么时候是第一次呢?

以表单的方式,读取的时候是空,说明是第一次。第一次请求时get请求。

 

九、帮我们判断是第几次

 

十、判断页面是否是首次加载

写完之后,运行一般处理程序就行了。

Snagit图片处理软件:

 

十一、最终效果演示

 

十二、登录过程图

为什么用隐藏域呢?如果这不放占位符,通过JavaScript的方式呢?演示原理的,演示webform里面的一个内容,这个内容就叫做隐藏域。

 

十三、第一次是get请求

 

十四、post请求

现在我们再按F5

 

十五、提示信息

 

十六、这是怎么回事儿

这样会给我们带来什么不方便的地方呢?交易的时候post会带来错误的,点击重试又买了一次。添加的时候,点击F5提交到数据库,点击F5又提交到数据库一次。怎么解决呢?跳转到成功页面。跳转的时候是get请求,再按F5就不会出这个问题了。

下面我们看下做什么事情的时候用get请求,做什么事情的时候用post请求。

还可以设定<form>的method属性指定表单提交方式,get(默认值)是通过URL传递表单值,post传递的表单值是隐藏到http报文体中,url中看到不。

get和post的区别(常考):get是通过url传递表单值post通过url看不到表单域的值;get传递的数据量是有限的,如果要传递大数据量不能用get,比如type=“file”上传文章、type=“password”传递密码或者<textarea>发表大段文章,post则没有这个限制;post会有浏览器提示重新提交表单的问题,get则没有(加分的回答)。对于Post的表单重新敲地址栏再刷新就不会提示重新提交了,因为重新敲地址就没有偷偷提交的数据了。Post方式的正确的地址很难直接发给别人。

Get方式URL数据格式。服务端文件名后跟着“?”,由于客户端可能向服务器端提交多个键值对,键值对之间用“&”进行分割,如果URL中有汉字、特殊符号等,则需要对URL进行编码。

表单域只有设定了name的才会被提交给服务器(用get方式看的清楚)。如果给submit按钮设定name,那么按钮的value也会被提交给服务器

【刷新】。

 

十七、对URL进行编码

下面我们做个数字自增的练习:

要求:页面上放一个文本框,一个按钮,文本框默认是0,点一次按钮文本框加1.

写好的html页面插入位置:

View Code
 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 
 3 <html xmlns="http://www.w3.org/1999/xhtml">
 4 <head>
 5     <title></title>
 6 </head>
 7 <body>
 8     <form action="07-数值自增.ashx" method="post">
 9         <input type="text" value="@name" />
10         <input type="submit" value="click" />
11     </form>
12 </body>
13 </html>

初步写好的ashx插入位置:

View Code
 1 <%@ WebHandler Language="C#" Class="_07_数值自增" %>
 2 
 3 using System;
 4 using System.Web;
 5 
 6 public class _07_数值自增 : IHttpHandler {
 7     //1.定义一个变量
 8     int n = 0;
 9     public void ProcessRequest (HttpContext context) {
10         context.Response.ContentType = "text/plain";
11         //3.把页面输出出来
12         string path = context.Request.MapPath("07-数值自增.htm");
13         string html=System.IO.File.ReadAllText(path);
14         //2.输出
15         n++;
16         context.Response.Write(n);
17         context.Response.Write(html);
18     }
19  
20     public bool IsReusable {
21         get {
22             return false;
23         }
24     }
25 
26 }

httpwatch_pro_6.1.46下载地址:

HttpWatch_Pro_7.1.37 下载地址:

Fiddler2Setup下载地址:

这个时候写成这个样子,数值不会自增,这是什么原因呢?第一次请求是一,服务器不会把值存起来的.怎么解决呢?

初始化的时候,让文本框的值等于0,再点按钮的时候,post回来了,把文本框的值取出来,进行++,重新放回去。每一次执行完成之后,都把上一次的值重新放到文本框里面来,下一次请求的时候会把值post给服务器,服务器读取完++再重新放回来。什么时候给它的值付成0呢?第一次的时候,点按钮的时候++。所以用到隐藏域。

                       

十八、放个隐藏域

读取隐藏域并判断是否是第一次加载

View Code
 1 <%@ WebHandler Language="C#" Class="_07_数值自增" %>
 2 
 3 using System;
 4 using System.Web;
 5 
 6 public class _07_数值自增 : IHttpHandler {
 7    
 8     public void ProcessRequest (HttpContext context) {
 9         context.Response.ContentType = "text/html";
10         //1.定义一个变量
11         int n = 0;
12         //3.把页面输出出来
13         string path = context.Request.MapPath("07-数值自增.htm");
14         string html=System.IO.File.ReadAllText(path);
15         //读取隐藏域,判断是否是第一次加载
16         string viewstate=context.Request.Form["_viewstate"];
17         if (!string.IsNullOrEmpty(viewstate))
18         {
19           //post
20             string txt=context.Request.Form["txtNum"];
21             n = int.Parse(txt);
22             n++;
23             
24         }
25         //给文本框赋值
26         html = html.Replace("@num", n.ToString());
27         //2.输出
28         context.Response.Write(html);
29     }
30  
31     public bool IsReusable {
32         get {
33             return false;
34         }
35     }
36 
37 }

十九、同时,我还修改了一下html代码。

 二十、数值自增演示

现在我们做的这个是刷新页面的数值自增,后面我们还要带领大家做无刷新。

下面我们再做几个练习:

练习:用ashx实现加法计算器。常见错误:type=submit才会自动提交表单,type=button不会自动提交。从ashx启动和从html启动的区别

 

二十一、做好准备工作

计算加法的一般处理程序代码插入位置:

View Code
 1 <%@ WebHandler Language="C#" Class="_08_add" %>
 2 
 3 using System;
 4 using System.Web;
 5 
 6 public class _08_add : IHttpHandler {
 7     
 8     public void ProcessRequest (HttpContext context) {
 9         context.Response.ContentType = "text/html";
10         //1.读取静态模板
11         string path = context.Request.MapPath("08-add.htm");
12         string html = System.IO.File.ReadAllText(path);
13         
14         //2.判断页面是否是首次加载
15         string viewstate=context.Request.Form["_viewstate"];
16         if (!string.IsNullOrEmpty(viewstate))
17         {
18             string num1=context.Request.Form["txtNum1"];
19             string num2=context.Request.Form["txtNum2"];
20 
21             int num3 = int.Parse(num1) + int.Parse(num2);
22             
23             //把两个文本框的值重新替换回去,还有计算之后的值也返回去。
24             html = html.Replace("@num1", num1).Replace("@num2", num2).Replace("@num3", num3.ToString());
25         }
26         //如果是第一次加载的时候把文本框的值付成空。
27         else
28         {
29             html = html.Replace("@num1", "").Replace("@num2", "").Replace("@num3", "");
30         }
31         //3.输出
32         context.Response.Write(html);
33     }
34  
35     public bool IsReusable {
36         get {
37             return false;
38         }
39     }
40 
41 }

二十二、加法计算演示

如果出问题了,而且在代码里面一眼看不出来,这个时候要设个断点调试.一般处理程序怎么进行调试呢?

 

二十三、这样调试进不去断点

 

二十四、调试过程

练习:实现div内文本的自增。因为服务器不记得上次给浏览器的值是什么,而且不像input那样会将上次的值重新提交回来,因此浏览器需要用一个隐藏字段将上一次的值保存下来。代码见备注

 

二十五、写好html页

 

二十六、实现div内文本的自增代码

 

二十七、div内文本自增演示

http无状态,每次请求都是由一个新的页面对象来处理请求。如果把value搞成static可以实现,但是两个用户访问的话就会串了。而用Input方式的话两个人各自点各自的,不会互相影响。

非表单元素无法将客户端的元素值传递给服务器端,即使是表单元素也只能传递value值,对于其他属性值比如背景颜色、大小等也是无法传递的,因此对于这些值都要存在隐藏字段中

 

下面我们通过之前我们讲解的三层,做个照片列表。

 

二十八、新建解决方案

这样做方便管理三层里面的几个项目。

 

二十九、对应生成文件夹

下面创建三层那几个项目,从下往上创建。

                     

三十、model

 

三十一、再创建DAL

再创建BLL

 

三十二、新建网站

这块在浏览的时候要找对文件夹

 

三十三、找对文件夹

这个命名空间不好看,中间加个点。这里学习微软起个顶级的命名空间。

 

三十四、属性

这样再添加一个model类的时候就有点了。

 

三十五、把没用的类都删掉

下面我们添加引用:

 

三十六、添加引用一

 

三十七、添加引用二

 

三十八、添加引用三

建好之后先写model,我们这里就不写了,直接把以前写好的拷贝过来。

 

三十九、直接拷贝过来

检查下命名空间就行了。

先写dal写个SQLHelper。这里我们用什么写什么,就去做那个照片列表。

 

四十、别忘了添加引用

建个配置文件,建到UI,运行谁,配置文件就放到哪个里面。我们发现配置文件有了,打开它。

                       

四十一、忘了的话打开这儿

 

四十二、写好配置文件

 

四十三、写好SqlHelper

下面我们操作那个photos表,把表中所有的数据查询出来,生成一个照片列表。

 

四十四、再创建一个类操作photo表

拿数据的DAL代码插入位置:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 using System.Data;
 7 using MyPhotos.Model;
 8 
 9 namespace MyPhoto.DAL
10 {
11     public class PhotosDAL
12     {
13         //1.拿到照片数据
14         public List<Photos> GetAllPhotos()
15         {
16             List<Photos> list = new List<Photos>();
17             string sql = "select*from photos";
18             //2.执行
19             SQLHelper helper = new SQLHelper();
20             DataTable dt = helper.GetTable(sql);
21             //把关系转换成对象
22             foreach (DataRow dr in dt.Rows)
23             {
24                 Photos p = RowToPhotos(dr);
25                 list.Add(p);
26             }
27             return list;
28         }
29         //3.写个方法
30         private Photos RowToPhotos(DataRow dr)
31         {
32             Photos p = new Photos();
33             p.PClicks = Convert.ToInt32(dr["PClicks"]);
34             p.PDes = dr["PDes"].ToString();
35             p.PDown = Convert.ToInt32(dr["PDown"]);
36             p.PId = Convert.ToInt32(dr["PId"]);
37             p.PTime = Convert.ToDateTime(dr["PTime"]);
38             p.PTitle = dr["PTitle"].ToString();
39             p.PTypeId = Convert.ToInt32(dr["PTypeId"]);
40             p.PUp = Convert.ToInt32(dr["PUp"]);
41             p.PUrl = dr["purl"].ToString();
42             p.PUserId = Convert.ToInt32(dr["PUserId"]);
43             return p;
44         }
45     }
46 }

一句话写完BLL层。

 

四十五、写好BLL

我们底层的代码就写完了,大家可以参考我们之前的关于三层的知识进行复习。

我们主要的任务就是写UI层的代码。

添加个一般处理程序:

为了好看一点再建个模板。

 

四十六、做好静态页

写好一般处理程序后我们运行一下,发现报错了。

 

四十七、常见的报错一

编译一下,就是重新生成解决方案。

 

四十八、常见的报错二

 

四十九、看到照片列表

给表格加个边框。

五十、加个边框

在数据库建题目中表的SQL:

View Code
 1 create database MyPhotos
 2 go
 3 use MyPhotos
 4 go
 5 create table PhotoType   --相册
 6 (
 7     TypeId int identity(1,1) primary key,
 8     TypeName nvarchar(50) not null,
 9     TypeDes nvarchar(500)
10 )
11 go
12 create table Photos
13 (
14     PId int identity(1,1) primary key,
15     PTypeId int not null,
16     PUserId int not null,        --User表的主键
17     PTitle nvarchar(100) not null,
18     PUrl nvarchar(100) not null,    --图片的名称
19     PDes nvarchar(1000),        --描述
20     PClicks int,            --点击次数
21     PTime datetime,            --录入时间
22     PUp int,            --支持
23     PDown int            --反对
24 )
25 go
26 create table Comments
27 (
28     CId int identity(1,1) primary key,
29     CPhotoId int not null,        --照片的id
30     CText nvarchar(1000),        --评论内容
31     CTime datetime,            --评论时间
32     CUp int,
33     CDown int
34 )
35 go
36 create table [User]
37 (
38     UId int identity(1,1) primary key,
39     UName varchar(8),
40     UPwd varchar(20)
41 )
42 go
43 
44 create view v_Photo
45 as
46     SELECT     dbo.Photos.PId, dbo.Photos.PTypeId, dbo.Photos.PUserId, dbo.Photos.PTitle, dbo.Photos.PUrl, dbo.Photos.PDes, dbo.Photos.PClicks, 
47                       dbo.Photos.PTime, dbo.Photos.PUp, dbo.Photos.PDown, dbo.PhotoType.TypeId, dbo.PhotoType.TypeName, dbo.PhotoType.TypeDes
48     FROM         dbo.Photos INNER JOIN
49                       dbo.PhotoType ON dbo.Photos.PTypeId = dbo.PhotoType.TypeId
50 go    
51 alter table Photos
52 add constraint DF_pClicks default(0) for pClicks
53 alter table Photos
54 add constraint DF_PUp default(0) for PUp
55 alter table Photos
56 add constraint DF_PDown default(0) for PDown
57 
58 alter table Photos
59 add constraint DF_pTime default(getdate()) for pTime
60 
61 alter table Comments
62 add constraint DF_cTime default(getdate()) for cTime
63 alter table Comments
64 add constraint DF_CUp default(0) for CUp
65 alter table Comments
66 add constraint DF_CDown default(0) for CDown
67 
68 alter table Photos
69 add constraint FK_PTypeId
70 foreign key(PTypeId) references PhotoType(TypeId) 
71 
72 alter table Comments
73 add constraint FK_CPhotoId
74 foreign key(CPhotoId) references Photos(PId) 
75 
76 use MyPhotos
77 insert into phototype values('人物','人物')
78 insert into phototype values('风景','风景')
79 insert into phototype values('卡通','卡通')
80 insert into phototype values('家庭','家庭')
81 insert into phototype values('自拍','自拍')
82 
83 insert into [user] values('admin','admin')
84 insert into [user] values('zs','00000')
85 insert into [user] values('ls','00000')
86 insert into [user] values('ww','00000')
87 
88 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(1,1,'图片1','01.jpg','图片one')
89 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(1,2,'图片2','02.jpg','图片two')
90 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(1,2,'图片3','03.jpg','图片three')
91 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(1,1,'图片4','04.jpg','图片four')
92 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(1,1,'图片5','05.jpg','图片five')
93 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(2,1,'图片6','06.jpg','图片six')
94 insert into photos(PTypeId,PUserId,ptitle,purl,pdes) values(2,2,'图片7','07.jpg','图片seven')

五十一、表格样式

 

五十二、最终美图

我们可以用之前学过的东西加个隔行变色,加个高亮显示。

 

回到起始位置

作者近期文章列表:

C#中级进阶教程(完全免费,献给代码爱好者的最好礼物。注:本作者分享自己精心整理的C#中级进阶教程,无任何商业目的。希望与更多的代码爱好者交流心得,也请高手多多指点!!!)
ASP.net项目 图书商城项目总论
ASP.net系列 ASP.NET(get和post比较)
三层及其它内容 递归
三层(一)
三层相关案例(及常见的错误)
三层实例(内涵Sql CRUD)
手写代码生成器
SQL数据库 ADO.net 数据库的应用图解一
数据库的应用详解二
ADO.NET(内涵效率问题)
ADO.NET实例教学一
ADO.NET实例教学二
数据库的应用详解三
ADO.NET(内含存储过程讲解)
面向过程,面向对象中高级 面向过程,面向对象的深入理解一
面向过程,面向对象的深入理解二
面向对象的深入理解三
正则表达式
无处不在的XML
winform基础 Winform基础
winform中常用的控件
面向过程 三种循环的比较
C#中的方法(上)
我们常见的数组
面向对象 思想的转变
C#中超级好用的类
C#中析构函数和命名空间的妙用
C#中超级好用的字符串
C#中如何快速处理字符串
值类型和引用类型及其它
ArrayList和HashTable妙用一
ArrayList和HashTable妙用二
文件管理File类
多态
C#中其它一些问题的小节
GDI+ 这些年我收集的GDI+代码
这些年我收集的GDI+代码2
HTML概述以及CSS 你不能忽视的HTML语言
你不能忽视的HTML语言2精编篇
你不能忽视的HTML语言3
html-综合篇
CSS基本相关内容--中秋特别奉献
CSS基本相关内容2
JavaScript基础 JavaScript基础一
javascript基础二JavaScript DOM编程
jQuery jQuery(内涵: jquery选择器)
jquery实例教学一
新春快乐,本博主祝大家每天都有好心情!合家团圆,吃好,玩好,喝好!!!
posted on 2013-02-03 23:15  小事好  阅读(4677)  评论(19编辑  收藏  举报