ASP.NET02

本文总阅读量:
  1. 1. 搭建IIS本地服务器
  2. 2. IIS处理用户请求与响应过程
  3. 3. 创建一个简单的ASP.NET

搭建IIS本地服务器

打开服务

https://luox78.github.io/images/IIS01.png

打开IIS管理器

https://luox78.github.io/images/IIS02.png

新建网站

https://luox78.github.io/images/IIS03.png

浏览新建立的网站

https://luox78.github.io/images/IIS04.png

问题:

数据库访问用户权限问题:更改网站用户为netservice

https://luox78.github.io/images/IIS数据库问题改身份.png

目录浏览权限问题

https://luox78.github.io/images/IIS目录浏览权限.png

dotnet版本问题

https://luox78.github.io/images/IIS修改dotnet版本.png

IIS处理用户请求与响应过程

  1. URL封装报文
  2. http.sys内核模块监听对某个端口的请求
  3. 读取注册表获取哪个进程可以处理该请求
  4. inetinfo.exe处理请求启动w3wp.exe,分动态资源与静态资源
  5. 对于静态资源直接找到磁盘上的文件返回
  6. 对于动态资源,找到处理该动态页面的dll,对于aspx找到aspnet.isapi.dll(C++)寄宿在w3wp.exe运行
  7. aspnet.isapi.dll开启dotnet运行时
  8. 获取一个实现了IISAPIRuntime接口的对象ISAPIRuntime,调用ProcessRequest方法(参数之一ecb是传入的数据句柄)
  9. ProcessRequest对请求报文进行简单的封装成ISAPIWorkerRequest(wk)对象
  10. 调用HttpRuntime.ProcessRequest(wk)对wk进行详细封装成HttpContext对象包含HttpRequestHttpResponse
  11. 通过工厂模式【1】创建一个HttpApplication对象后调用ProcessRequest方法
  12. 。。。

https://luox78.github.io/images/相信过程.png

【1】

为什么使用工厂模式

初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有悖于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间耦合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情

如何使用工厂模式:

使用接口派生实体类,通过工厂模式创建不同的对象

简单工厂:

1
2
3
4
5
6
7
8
public class Factory{
public static ISample creator(int which){
if (which==1)
return new SampleA();
else if (which==2)
return new SampleB();
}
}

那么在你的程序中,如果要创建ISample的实列时候可以使用

ISample sampleA=Factory.creator(1);

抽象工厂:

工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).

这两个模式区别在于需要创建对象的复杂程度上。如果我们创建对象的方法变得复杂了,如上面工厂方法中是创建一个对象Sample,如果我们还有新的产品接口Sample2.

这里假设:Sample有两个实体类SampleA和SampleB,而Sample2也有两个实体类Sample2A和Sample2B

那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public abstract class Factory{
public abstract Sample creator();
public abstract Sample2 creator(String name);
}
public class SimpleFactory extends Factory{
public Sample creator(){
.........
return new SampleA
}
public Sample2 creator(String name){
.........
return new Sample2A
}
}

public class BombFactory extends Factory{
public Sample creator(){
......
return new SampleB
}
public Sample2 creator(String name){
......
return new Sample2B
}
}

https://baike.baidu.com/item/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/9852061?fr=aladdin

创建一个简单的ASP.NET

新建html登录界面

1
2
3
4
5
6
7
8
9
<form method="post" action="LoginHandler.ashx">
<label>loginid</label>
<input type="text" name="id">
<br>
<label>password</label>
<input type="password" name="password">
<br>
<input type="submit" value="login"/>
</form>

编写LoginHandler.ashx

从页面获取值的方式:

get:context.Request.QueryString["id"]

post:context.Request.Form["id"]

通用:context.Request["id"] || context.Request.Params["id"]

这里我简单的连接数据库进行判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string id = context.Request["id"];
string password = context.Request["password"];

string constr = "data source=”LUOX78“的WIN;initial catalog=school;integrated security=true";
int res = -1;
using (var con = new SqlConnection(constr))
{
string sql = "select count(*) from Users where loginId=@id and loginPwd=@pwd";
var pms = new SqlParameter[]
{
new SqlParameter("@id",id),
new SqlParameter("@pwd",password)
};
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.AddRange(pms);
con.Open();
res = (int)cmd.ExecuteScalar();
}
}

context.Response.Write(res > 0 ? "登陆成功" : "失败");

登录错误应该重定向,此时response返回的是302,浏览器重新get

1
context.Response.Redirect("login.html");

有时一般处理程序会进行读取返回

获取页面绝对路径使用context.Server.MapPath("login.html");

1
2
3
var html = File.ReadAllText("path");
//todo 添加处理
context.Response.Write(html);