Server对象:
1、Server是Context的一个属性,是HttpServerUtility类的一个对象
2、Server.HtmlDecode()、Server.HtmlEncode() (处理Xss漏洞攻击,如<>这些符号)Server.UrlEncode()(处理非ASCII字符)、Server.UrlDecode()是对HttpUtility类中相应方法的一个代理调用。个人推荐使用HttpUtility,因为有的地方很难拿到Server对象。别把HtmlEncode、UrlEncode、混了,UrlEncode是处理超链接的,HtmlEncode是处理Html代码的。
3、Server.Transfer(path)内部重定向请求,Server.Transfer("JieBanRen.aspx")将用户的请求重定向给JieBanRen.aspx处理,是服务器内部的接管,浏览器是意识不到这个接管的,不是象Response.Redirect哪样经历“通知浏览器请重新访问Url这个网址和浏览器接到命令访问新网址的过程”,是一次Http请求,因此浏览器地址栏不会变化(联想,呼叫中心坐席告诉客户一个号码和帮客户转接的区别,比如我问一个人“美国怎么走?”,这个人不知道,但他打电话问另外一个知道了这个问题然后回答我的问题,如果是Response.Redirect,经过是我问这个人“美国怎么走?”,他回答我“我不知道,你去问某某”,我去问某某解决我的问题)。因为是内部接管,所以在被重定向到的页面中是可以访问到Request、Cookie等这些来源页面接受的参数的,就像这些参数是传递给他的,而Redirect则不行,因为是让浏览器去访问的。注意Transfer是内部接管,因此不能像Redirect哪样重定向到外部网站(常考)。
新建一个新建一个aspx页面你好.aspx:
<form id="form1" runat="server"> <div> 你好!!!!!!!!!!!!!!! </div> </form>
后台代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class _4Server对象_你好 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string q=Request["q"]; Response.Write(q); } }
再新建一个aspx页面,页面中没有什么内容,后台代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class _4Server对象_Transfer : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string q = Request["q"]; if (q == "1") { Response.Write("壹"); } else if (q == "2") { //Server.Transfer("http://www.baidu.com");//这是不行的,因为http://www.baidu.com不是你内部的页面,只能是自己网站内部的页面。 Server.Transfer("你好.aspx"); } else if (string.IsNullOrEmpty(q)) { Response.Write("请输入问题!"); } else { //Response.Redirect("你好.aspx?q="+q); //Response.Redirect("00_43.jpg");//将重定向到图片 //Response.Redirect("你好.aspx"); Response.Redirect("http://www.baidu.com");//可以重定向到另外一个网站 } } }
4、使用Server.Transfer不能直接重定向到ashx,否则会报错“执行子请求出错”。
5、有的时候不能拿到HttpContext对象,比如在Global.asax中(后面讲),可以通过HttpContext.Current拿到当前的HttpContext,进而拿到Response、Resquest、Server等。
6、Server.MapPath
HttpHandler1
1、HttpHandler是对请求的响应,可以输出普通的Html内容,也可以输出图片、也可以输出一个文件(下载 )(如果输出html就用Aspx,输出非html的页面,用HttpHandler)。
2、输出一幅动态创建的图片(能看懂就可以了)
案例1:图片中显示访问者的信息。
新建一般处理程序访问者信息.ashx:
<%@ WebHandler Language="C#" Class="访问者信息" %> using System; using System.Web; public class 访问者信息 : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "image/JPEG"; using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(800, 300)) { using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap)) { g.DrawString("你的IP:" + context.Request.UserHostAddress, new System.Drawing.Font("微软雅黑", 30), System.Drawing.Brushes.Red, 0, 0); g.DrawString("你的操作系统:" + context.Request.Browser.Platform , new System.Drawing.Font("微软雅黑", 30), System.Drawing.Brushes.Red, 0, 50); g.DrawString("你的浏览器版本:" + context.Request.Browser .Type , new System.Drawing.Font("微软雅黑", 30), System.Drawing.Brushes.Red, 0, 100); } bitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); } } public bool IsReusable { get { return false; } } }
网上看到的注册、登录时候的验证码也是动态生成的图片、55.la也是这样实现的原理。
HttpHandler实现文件下载
1、如果HttpHandler输出的是Html、Txt、Jpeg等类型的信息,那么浏览器会直接显示,如果希望弹出保存对话框,则需要添加Header:string encodeFileName=HttpUtility.UrlEncode(“过滤词.txt”);Response.AddHeader("Content-Disposition",string.Format("attachment;filename=\"{0}\"",endodeFileName));其中filename后为编码后的文件名。filename段为建议的保存文件名。
新建一个htm文件:
<head> <title></title> </head> <body> <a href="00_43.jpg">图片1</a><br/> <a href="1.txt">文本1</a><br/> <a href="下载.ashx">图片2</a> </body> </html>
新建一个一般处理程序:
<%@ WebHandler Language="C#" Class="下载图片" %> using System; using System.Web; public class 下载图片 : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "image/JPEG"; string fileName = HttpUtility.UrlEncode("哈哈.jpeg"); context.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); context.Response.WriteFile("../img/160.jpg"); } public bool IsReusable { get { return false; } } }
浏览htm页面,用工具查看,在发送给浏览器的报文头中加了Content-Disposition: attachment;filename=%e5%93%88%e5%93%88.jpg(如果要正常浏览页面,要将图片和txt文件加到项目中)
HTTP/1.1 200 OK Server: ASP.NET Development Server/10.0.0.0 Date: Fri, 31 Aug 2012 14:15:59 GMT X-AspNet-Version: 4.0.30319 Content-Disposition: attachment;filename=%e5%93%88%e5%93%88.jpg Cache-Control: private Content-Type: image/JPEG Content-Length: 159843 Connection: Close
2、动态输出用处,不用再把资源保存到磁盘上再输出(不会有文件重名的问题,文件不生成在服务器端)。案例:点出链接弹出图片下载对话框。Web的原则:能直接将生成的内容以流的形式输出给浏览器,就不要生成临时文件。
练习:用NPOI动态生成一个Excel表然后弹出对话框让用户下载,mdf放到App_data下,Asp.net不用那段设置DataDirectory的代码,用DataReader的方式读取数据,文件名“用户列表.xls”。application/x-excel,application/octet-stream
新建一个Asp.net Web应用程序,在项目中新建一个文件夹lb,把NPOI的八个DLL文件考到文件夹中,添加对这些DLL的引用。新建一个一般处理程序DownloadExcel1.ashx。新建一个Default.aspx文件:
NPOI下载地址:http://npoi.codeplex.com/releases/view/38113
npoi 能够读写几乎所有的Office 97-2003文件格式,至少能够支持Word, PowerPoint, Excel, Visio的格式。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using NPOI.HSSF.UserModel; namespace Excel下载 { /// <summary> /// Summary description for 导出Excel /// </summary> public class 导出Excel : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/x-excel"; string filename = HttpUtility.UrlEncode("动态数据.xls"); context.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename); HSSFWorkbook workbook = new HSSFWorkbook(); var sheet = workbook.CreateSheet(); var row = sheet.CreateRow(0) ; var cell1 = row.CreateCell(0,NPOI.SS.UserModel.CellType.String ); cell1.SetCellValue("hello"); row.CreateCell(1, NPOI.SS.UserModel.CellType.String).SetCellValue(3.14); workbook.Write(context.Response.OutputStream); } public bool IsReusable { get { return false; } } } }
浏览Default.aspx,点下载Excel1,出现保存对话框,可以点打开,打开Excel,可以看到刚才填入的数据。
接下来从数据库中读取数据,输出到Excel中:右击项目选择“添加”“新建项”,选择“数据”,再选择“SQL Server 数据库”,输入名称:DatabaseUser.mdf,出现提示“是否将数据库添加到App_Data文件中”点“是”(最好将数据文件添加到App_Data文件夹中,因为Asp.net默认不会将这个文件夹中的数据给用户下载,这就增加了安全性)。在数据库添加一张表,字段名是UserName和Password,类型为nvarchar(50),简单一点,其它什么都不设置,将表保存为T_User
一般处理程序的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using NPOI.HSSF.UserModel; using System.Data.SqlClient; using System.Data; namespace Excel下载 { /// <summary> /// Summary description for 导出Excel /// </summary> public class 导出Excel : IHttpHandler { public void ProcessRequest(HttpContext context) { //context.Response.ContentType = "application/x-excel"; // string filename = HttpUtility.UrlEncode("动态数据.xls"); // context.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename); // HSSFWorkbook workbook = new HSSFWorkbook(); // var sheet = workbook.CreateSheet(); // var row = sheet.CreateRow(0) ; // var cell1 = row.CreateCell(0,NPOI.SS.UserModel.CellType.String ); // cell1.SetCellValue("hello"); // row.CreateCell(1, NPOI.SS.UserModel.CellType.String).SetCellValue(3.14); // workbook.Write(context.Response.OutputStream); context.Response.ContentType = "application/x-excel"; string fileName = HttpUtility.UrlEncode("用户数据.xls"); context.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); HSSFWorkbook workbook = new HSSFWorkbook(); var sheet = workbook.CreateSheet(); string sqlConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=F:\study\ASP.net 中级\Excel下载\App_Data\UserDB.mdf;Integrated Security=True;User Instance=True"; using (SqlConnection conn = new SqlConnection(sqlConnectString)) { // SqlCommand cc = conn.CreateCommand(); // SqlDataReader sqlre = cc.ExecuteReader(); conn.Open(); using (IDbCommand cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT * FROM T_User"; using (IDataReader reader = cmd.ExecuteReader()) { int rownum = 0; while (reader.Read()) { string username = reader.GetString(reader.GetOrdinal("UserName")); string password = reader.GetString(reader.GetOrdinal("Passsword")); var row = sheet.CreateRow(rownum); row.CreateCell(0, NPOI.SS.UserModel.CellType.String).SetCellValue(username); row.CreateCell(1, NPOI.SS.UserModel.CellType.String).SetCellValue(password); rownum++; } } } } workbook.Write(context.Response.OutputStream); } public bool IsReusable { get { return false; } } } }
浏览Default.aspx页面,占下载Excel1,就可“保存”或“打开”生成的Excel文件。