admin管理员组文章数量:1574528
第一章Web基本原理
webform与asp mvc都是基于asp内核
ViewState不安全,不能存储重要信息,因为是放在浏览器里的,可以被修改.ViewState其实就是xml经过加密了.
编写自己的浏览器
//注意在VS2010中需要写成:new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);//TCP、UDP。 socket.Connect(new DnsEndPoint("127.0.0.1", 8080));//连接服务器。http协议默认的端口号是80。每个服务器软件监听一个端口(别的软件就不能监听这个端口了),发送给这个端口的数据只会被这个服务器软件接收到。 using (NetworkStream netStream = new NetworkStream(socket))//读写socket通讯数据的流 using (StreamWriter writer = new StreamWriter(netStream)) { writer.WriteLine("GET /index.html HTTP/1.1");//每一行指令都回车一下。注意:1)GET后要有空格;2)因为中文文件名需要进行url编码,现在初学的时候不要请求中文文件名的html文件 writer.WriteLine("Host: 127.0.0.1:8080"); writer.WriteLine();//空行回车,表示指令结束 } using (NetworkStream netStream = new NetworkStream(socket)) using (StreamReader reader = new StreamReader(netStream)) { string line; while ((line = reader.ReadLine())!=null) { Console.WriteLine(line); } } socket.Disconnect(false);View Code
编写web服务器
//自己写最简单的Web服务器: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace MyWeb服务器1 { class Program { static void Main(string[] args) { Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//宿舍大妈 serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080)); serverSocket.Listen(10); while (true) { Console.WriteLine("等着请求"); Socket socket = serverSocket.Accept();//男女通讯通道。返回大妈给你的这个人的通讯通道 Console.WriteLine("来了请求"); using(NetworkStream stream = new NetworkStream(socket)) using (StreamReader reader = new StreamReader(stream)) { string line; while ((line = reader.ReadLine()) != null) { Console.WriteLine(line); if (line.Length <= 0) { break;//遇到空行了,请求结束了不用再等了 //如果不break,就一直卡在ReadLine()等着浏览器发后续的数据 } } } using (NetworkStream stream = new NetworkStream(socket)) using(StreamWriter writer = new StreamWriter(stream)) { writer.WriteLine("HTTP/1.1 200 OK"); writer.WriteLine(); writer.WriteLine("welcome to rupeng"); } socket.Disconnect(false); } } } }View Code
web服务器2
namespace MyWeb服务器2 { class Program { static void Main(string[] args) { Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//宿舍大妈 serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080)); serverSocket.Listen(10); while (true) { Console.WriteLine("等着请求"); Socket socket = serverSocket.Accept();//男女通讯通道。返回大妈给你的这个人的通讯通道 Console.WriteLine("来了请求"); string firstLine; using (NetworkStream stream = new NetworkStream(socket)) using (StreamReader reader = new StreamReader(stream)) { firstLine = reader.ReadLine();//读取GET /1.htm HTTP/1.1 string line; while ((line = reader.ReadLine()) != null) { Console.WriteLine(line); if (line.Length <= 0) { break;//遇到空行了,请求结束了不用再等了 //如果不break,就一直卡在ReadLine()等着浏览器发后续的数据 } } } // Regex.Match(firstLine, "GET (.+) HTTP/1\\.1"); string[] strs = firstLine.Split(' '); string url = strs[1];///分析出文件名1.htm Console.WriteLine("url="+url); using (NetworkStream stream = new NetworkStream(socket)) using (StreamWriter writer = new StreamWriter(stream)) { string filePath = @"F:\快盘\NextBig\NET课程\ASP\myweb服务器" + url; Console.WriteLine("filePath=" + filePath); if (File.Exists(filePath)) { writer.WriteLine("HTTP/1.1 200 OK"); writer.WriteLine(); string html = File.ReadAllText(filePath); Console.WriteLine(html); writer.Write(html); } else { writer.WriteLine("HTTP/1.1 404 NOT FOUND"); writer.WriteLine(); writer.Write("没有找到"); } } socket.Disconnect(false); } } } }View Code
web服务器3
namespace MyWeb服务器3 { class Program { static void Main(string[] args) { Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//宿舍大妈 serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080)); serverSocket.Listen(10); while (true) { Console.WriteLine("等着请求"); Socket socket = serverSocket.Accept();//男女通讯通道。返回大妈给你的这个人的通讯通道 Console.WriteLine("来了请求"); string firstLine; using (NetworkStream stream = new NetworkStream(socket)) using (StreamReader reader = new StreamReader(stream)) { firstLine = reader.ReadLine();//读取GET /1.htm HTTP/1.1 string line; while ((line = reader.ReadLine()) != null) { Console.WriteLine(line); if (line.Length <= 0) { break;//遇到空行了,请求结束了不用再等了 //如果不break,就一直卡在ReadLine()等着浏览器发后续的数据 } } } // Regex.Match(firstLine, "GET (.+) HTTP/1\\.1"); string[] strs = firstLine.Split(' '); string url = strs[1];///分析出文件名add?i=1&j=2 string[] strs2 = url.Split('?'); string fileAction = strs[0];//add string qs = strs2[1]; Dictionary<string, string> dict = ParseQueryString(qs); int i = Convert.ToInt32(dict["i"]); int j = Convert.ToInt32(dict["j"]); using (NetworkStream stream = new NetworkStream(socket)) using (StreamWriter writer = new StreamWriter(stream)) { writer.WriteLine("HTTP/1.1 200 OK"); writer.WriteLine(); writer.WriteLine(i+j); } socket.Disconnect(false); } } /// <summary> /// 把i=1&j=2&w=aaa转换为一个Dictionary /// </summary> /// <param name="str"></param> /// <returns></returns> static Dictionary<string, string> ParseQueryString(string qs) { Dictionary<string, string> dict = new Dictionary<string, string>(); string[] strs = qs.Split('&'); foreach (string str in strs) { string[] kv = str.Split('='); string name = kv[0]; string value = kv[1]; dict.Add(name, value); } return dict; } } }View Code
注意:
1、在创建和运行asp项目的时候可能会报如下错误
这个不影响使用,不用管它。
微软出了一个补丁解决这个问题,下载地址是 https://www.microsoft/zh-cn/download/details.aspx?id=44907 不过既然不装他也不影响使用,为了避免引入新的问题,因此不推荐大家装。
2、使用VS2015、VS2017的同学注意,创建项目的过程略有不同,首先要选择
点【确定】然后在后续的对话框中点【空】就可以
vs创建项目 文件->新建->项目->ASP.NET空web
文件->新建->网站.这个是vs为了兼容VB,ASP(这里的ASP, 并非是ASP.NET).这种不推荐
ashx
第二章一般处理程序
响应码:
“200” : OK;
“302” : Found 暂时转移,用于重定向, Response.Redirect()会让浏览器再请求一次重定向的地址,重定向的请求是Get方式; "404" : Not Found 未找到。
500 服务器错误(一般服务器出现异常),通过报错信息找出异常的点。
403:客户端访问未被授权。304(服务器把文件的修改日期通过Last-Modified返回给浏览器,浏览器缓存这个文件,下次向服务器请求这个文件的时候,通过If-Modified-Since问服务器说“我本地的文件的修改日期是。。。”,服务器端如果发现文件还是那个文件,则告诉浏览器(304 Not Modified)文件没修改,还用本地的吧。ctrl+f5)。
总结:2xx:没问题;3xx代表浏览器需要干点啥;4***浏览器的问题;5xx服务器错误
304 Not Modified :图片已经加载过了,加载本地浏览器里缓存图片
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string user = context.Request["username"]; string pwd = context.Request["password"]; if (user == "admin" && pwd == "123456") { context.Response.Redirect("1.html"); //context.Response.Write("<h1>当前用户:" + user + "</h1>"); } else { context.Response.Write("<html><head></head><body>"); context.Response.Write("<img src='img.jpg'/><a href='1.html'>1.html</a>"); } context.Response.Write("</body></html>"); } /// <summary> /// ProcessRequest外的方法调用 context的话一定以参数形式 /// </summary> /// <param name="context"></param> void test(HttpContext context) { }View Code
//Form获取表单里的 string name = context.Request.Form["name"]; string age = context.Request.Form["age"];
//获取URL里参数 string name = context.Request.QueryString["name"]; string age = context.Request.QueryString["age"];
//即可读取Url参数也可以读取POST报文体 //通过反编译查看,是先去URL查找,如果没有去报文体查找 string name = context.Request["name"]; string age = context.Request["age"];
context.Response.End();//结束IHttpHandler执行
context.Server.MapPath("~/imag.jpg");//得到文件在服务器磁盘上的绝对路径,~表示网站根目录
10.文件下载
context.Response.ContentType = "text/plain"; //增加Content-Disposition是告诉浏览器,这个返回的内容是"附件形式"要给用户保存 //filename是建议的文件名 context.Response.AddHeader("Content-Disposition","attachment;filename="+context.Server.UrlEncode("动态文件.txt")); DataTable dt = SQLHelper.ExecuteQuery("select * from T_Persons");
生成验证码
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg"; using (Bitmap bmp = new Bitmap(200, 50)) using (Graphics g = Graphics.FromImage(bmp)) { string vcode = ""; for (int i = 0; i < 4; i++) { vcode += ran.Next(0, 9); } g.DrawString(vcode, new Font(FontFamily.GenericSerif, 30), Brushes.Red, 10, 10); bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg); } }
导出Excel
context.Response.ContentType = "application/ms-excel"; context.Response.AddHeader("Content-Disposition", "attachment;filename=" + context.Server.UrlEncode("动态文件.xlsx")); IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet("人员列表"); DataTable dt = SQLHelper.ExecuteQuery("select * from T_Persons"); for (int i = 0; i< dt.Rows.Count; i++) { IRow excelRow = sheet.CreateRow(i); DataRow dataRow = dt.Rows[i]; ICell cell0 = excelRow.CreateCell(0); cell0.SetCellValue((string)dataRow["name"]); ICell cell1 = excelRow.CreateCell(1); cell1.SetCellValue((int)dataRow["age"]); } workbook.Write(context.Response.OutputStream);
泡妞证下载
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg"; //增加Content-Disposition是告诉浏览器,这个返回的内容是"附件形式"要给用户保存 //filename是建议的文件名 context.Response.AddHeader("Content-Disposition", "attachment;filename=" + context.Server.UrlEncode("动态文件.jpg")); string name = context.Request["name"]; string filePath = context.Server.MapPath("~/paoniu.jpg"); using (Bitmap bmp = new Bitmap(filePath)) using (Graphics g = Graphics.FromImage(bmp)) using (Font font1 = new Font(FontFamily.GenericSerif, 12)) { g.DrawString(name, font1, Brushes.Red, 100, 100); bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg); } }
11.文件上传
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <meta charset="utf-8" /> </head> <body> <form action="FileUploadTest1.ashx" method="post" enctype="multipart/form-data"> <input type="file" name="file1" /> <input type="text"name="name" /> <input type="submit" value="上传" /> </form> </body> </html>
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; HttpPostedFile file1 = context.Request.Files["file1"]; file1.SaveAs(context.Server.MapPath("~/upload/"+file1.FileName)); }
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; HttpPostedFile file1 = context.Request.Files["file1"]; string fileExtension = Path.GetExtension(file1.FileName); if (file1.ContentLength > 1024 * 1024) { context.Response.Write("文件太大"); return; } if (fileExtension != ".jpg" && fileExtension != ".jepg") { context.Response.Write("文件格式错误"); return; } file1.SaveAs(context.Server.MapPath("~/upload/" + file1.FileName)); }
用户上传文件添加水印
public void ProcessRequest(HttpContext context) { HttpPostedFile file1 = context.Request.Files["file1"]; string fileExtension = Path.GetExtension(file1.FileName); if (file1.ContentLength > 1024 * 1024) { context.Response.ContentType = "text/plain"; context.Response.Write("文件太大"); return; } if (fileExtension != ".jpg" && fileExtension != ".jepg") { context.Response.ContentType = "text/plain"; context.Response.Write("文件格式错误"); return; } context.Response.ContentType = "image/jpeg"; string name = context.Request["name"]; //用户上传的文件尽量"不落地",也就是不保存到本地,可以避免,上传文件把服务器撑爆 //上传非法文件造成安全性问题 //只能证明一段代码有漏洞,不能证明代码没有漏洞. using (Image bmp = Bitmap.FromStream(file1.InputStream)) using (Graphics g = Graphics.FromImage(bmp)) using (Font font1 = new Font(FontFamily.GenericSerif, 12)) { g.DrawString(name, font1, Brushes.Red, 100, 100); bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg); } }View Code
Excel上传
注意:讲课中的代码有bug,没有考虑到一些Excel版本的兼容性问题,应该如下修改: private void OutputSheet(HttpResponse response, ISheet sheet) { response.Write("<h1>" + sheet.SheetName + "</h1>"); response.Write("<table>"); for (int i = sheet.FirstRowNum; i <= sheet.LastRowNum; i++) { IRow excelRow = sheet.GetRow(i); if (excelRow == null) continue; response.Write("<tr>"); for (int j = excelRow.FirstCellNum; j <= excelRow.LastCellNum; j++) { ICell cell = excelRow.GetCell(j); string cellValue = (cell==null?"":cell.ToString()); response.Write("<td>" + cellValue + "</td>"); } response.Write("</tr>"); } response.Write("</table>"); } using NPOI.SS.UserModel; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; namespace Web1 { /// <summary> /// WebExcel 的摘要说明 /// </summary> public class WebExcel : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; context.Response.Write("<html><head><title>Excel云</title></head><body>"); HttpPostedFile excelFile = context.Request.Files["excelFile"]; //if (excelFile == null)//不需要别人告诉你结论,你试验的结果就是真理 if (excelFile.ContentLength <= 0) { context.Response.Write("请选择要上传的文件"); OutputHtmlEnd(context.Response); return; } if (excelFile.ContentLength > 1024 * 1024) { context.Response.Write("只允许上传不大于1MB的文件"); OutputHtmlEnd(context.Response); return; } string fileExt = Path.GetExtension(excelFile.FileName); if (fileExt != ".xls" && fileExt != ".xlsx") { context.Response.Write("只允许上传xls、xlsx文件"); OutputHtmlEnd(context.Response); return; } IWorkbook workbook = WorkbookFactory.Create(excelFile.InputStream); for (int i = 0; i < workbook.NumberOfSheets; i++) { ISheet sheet = workbook.GetSheetAt(i); OutputSheet(context.Response, sheet); } OutputHtmlEnd(context.Response); } private void OutputSheet(HttpResponse response, ISheet sheet) { response.Write("<h1>" + sheet.SheetName + "</h1>"); response.Write("<table>"); for (int i = sheet.FirstRowNum; i < sheet.LastRowNum; i++) { IRow excelRow = sheet.GetRow(i); response.Write("<tr>"); for (int j = excelRow.FirstCellNum; j < excelRow.LastCellNum; j++) { ICell cell = excelRow.GetCell(j); string cellValue = cell.ToString(); response.Write("<td>" + cellValue + "</td>"); } response.Write("</tr>"); } response.Write("</table>"); } private void OutputHtmlEnd(HttpResponse response) { response.Write("</body></html>"); } public bool IsReusable { get { return false; } } } }View Code
文件上传按日期保存
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; namespace Web1 { /// <summary> /// UploadLianxi2 的摘要说明 /// </summary> public class UploadLianxi2 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; context.Response.Write("<html><head><title>Excel云</title></head><body>"); HttpPostedFile file1 = context.Request.Files["file1"]; if (file1.ContentLength <= 0) { context.Response.Write("请选择要上传的文件"); OutputHtmlEnd(context.Response); return; } if (file1.ContentLength > 2*1024 * 1024) { context.Response.Write("只允许上传不大于1MB的文件"); OutputHtmlEnd(context.Response); return; } string fileExt = Path.GetExtension(file1.FileName); if (fileExt != ".zip" && fileExt != ".rar") { context.Response.Write("只允许上传zip、rar....文件"); OutputHtmlEnd(context.Response); return; } string dirPath = DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day; string dirFullPath = context.Server.MapPath("~/upload/"+dirPath+"/"); string fileFullPath = Path.Combine(dirFullPath,file1.FileName); if (!Directory.Exists(dirFullPath))//如果文件夹不存在,则先创建文件夹 { Directory.CreateDirectory(dirFullPath); } file1.SaveAs(fileFullPath); } private void OutputHtmlEnd(HttpResponse response) { response.Write("</body></html>"); } public bool IsReusable { get { return false; } } } }View Code
第三章ashx增删改查
模板文件概念的引入
每次返回很多html代码后台拼写很麻烦,引入了模板文件
public class PersonView : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; int id = Convert.ToInt32(context.Request["id"]); DataTable dt = SQLHelper.ExecuteQuery("select * from T_Persons where ID=@ID", new SqlParameter { ParameterName = "@ID", Value = id }); if (dt.Rows.Count <= 0) { OutputHtmlStart("error"); context.Response.Write("undefind"); OutputHtmlEnd(); return; } DataRow row = dt.Rows[0]; string name = (string)row["name"]; int age = (int)row["age"]; OutputHtmlStart(name); context.Response.Write("<table>\n<tr><td>姓名</td><td>" + name + "</td></tr>\n"); context.Response.Write("<tr><td>年龄</td><td>" + age + "</td></tr>\n</table>"); OutputHtmlEnd(); } private void OutputHtmlStart(string title) { //不推荐这种调用,多线程出问题,应该以参数传递HttpContext HttpContext.Current.Response.Write("<html>\n<head>\n<title>"+ title + "</title>\n<body>\n"); } private void OutputHtmlEnd() { HttpContext.Current.Response.Write("</body>\n</html>"); } public bool IsReusable { get { return false; } } }View Code
模板文件调用
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; int id = Convert.ToInt32(context.Request["id"]); DataTable dt = SQLHelper.ExecuteQuery("select * from T_Persons where ID=@ID", new SqlParameter { ParameterName = "@ID", Value = id }); if (dt.Rows.Count <= 0) { context.Response.Write("undefind"); return; } DataRow row = dt.Rows[0]; string name = (string)row["name"]; int age = (int)row["age"]; string personViewHtmlFile = context.Server.MapPath("~/PersonView.html"); string personViewHtml = File.ReadAllText(personViewHtmlFile); personViewHtml = personViewHtml.Replace("@name",name).Replace("@age", age.ToString()); context.Response.Write(personViewHtml); }View Code
重定向
context.Response.Write("<script type='text/javascript'> alert('删除成功');location.href='error.html';</script>");
第四章Cookie和Session
服务器不记忆上次跟浏览器发生了什么,让浏览器记忆是增加还是编辑,再提交给服务器
public class IncDemo1 : IHttpHandler { private int i;//用户每次请求IncDemo1的时候,服务器都new一个IncDemo1的新对象来处理请求 public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string html = CommonHelper.ReadHtml("~/Day4/IncDemo1.html"); if (string.IsNullOrEmpty(context.Request["btn1"])) { html = html.Replace("@number", "0"); i = 0; } else { html = html.Replace("@number", i.ToString()); } context.Response.Write(html); }View Code
cookie设置读取更新
public class CookieTest1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //设置cookie HttpCookie cookie = new HttpCookie("test"); cookie.Value = "baidu"; context.Response.SetCookie(cookie); } public bool IsReusable { get { return false; } } } public class CookieTest2 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //读取cookie HttpCookie cookie = context.Request.Cookies["test"]; context.Response.Write(cookie == null?"没有cookie":cookie.Value); //更新cookie cookie.Value = "baidu"; context.Response.SetCookie(cookie); } public bool IsReusable { get { return false; } } }View Code
cookie设置有效期
如果设置了cookie有效期,1即使浏览器不关闭,到了有效期后cookie也会过期,2如果浏览器关闭重新打开cookie没过期,可以继续使用
DateTime.Now.AddMinutes(30);获取的是你服务器的时间,客户端怎么改都不受影响
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //设置cookie HttpCookie cookie = new HttpCookie("test"); cookie.Value = "baidu"; //DateTime的AddMinutes就是在DateTime基础上增加30分钟,返回新的DateTime对象 //如果不设置 cookie.Expires ,cookie的有效期就是浏览器的运行期间! //设置cookie有效期 cookie.Expires = DateTime.Now.AddMinutes(30); context.Response.SetCookie(cookie); }View Code
cookie是为了辨别用户身份
cookie缺点:不能存储过多信息,机密信息不能存.cookie:是可以被清除,不能把不能丢的数据存到cookie中:cookie尺寸有限制,一般就是几K,几百K
cookie实现记住用户名
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace _04_Cookie实现记住用户名 { /// <summary> /// Login1 的摘要说明 /// </summary> public class Login1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string html = CommHelper.ReadHtml("~/Login1.html"); string btnLogin = context.Request["btnLogin"]; if (string.IsNullOrEmpty(btnLogin))//直接访问Login1.ashx { HttpCookie cookieLastUserName = context.Request.Cookies["LastUserName"]; if(cookieLastUserName!=null) { html = html.Replace("@username", cookieLastUserName.Value); } else { html = html.Replace("@username", "").Replace("@password", ""); } context.Response.Write(html); } else//用户点击登录 { string userName = context.Request["username"]; HttpCookie cookie = new HttpCookie("LastUserName"); cookie.Value = userName; cookie.Expires = DateTime.Now.AddMinutes(30); context.Response.SetCookie(cookie); context.Response.Redirect("ok.html"); } } public bool IsReusable { get { return false; } } } }View Code
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <meta charset="utf-8" /> </head> <body> <form action="Login1.ashx" method="post"> 用户名<input type="text" name="username" value="@username" /> 密码<input type="password" name="password" value="@password" /> <input type="submit" name="btnLogin" /> </form> </body> </html>View Code
写入Cookie时Path的问题:Path为空,当前路径和子文件夹都可以读取。
子域名位:www.qq设置的cookie默认无法被bbs.qq读写,如果想要能够操作,则需要写入cookie的时候设置Domain为.qq
Session
session存储在服务器中,根据你请求的sessionId来识别你请求对应的session数据。sessionId是存储在cookie中的,不同会话的sessionId都不一样是使用session的自动生成的
session有效期设置
<!--web.config配置文件内--> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <!--<sessionState timeout="20"></sessionState>--> <!--<sessionState mode="SQLServer" timeout="20" sqlConnectionString="server=127.0.0.1;uid=sa;password=123456;" ></sessionState>--> </system.web>View Code
设置session
/// <summary> /// SessionTest1 的摘要说明 /// </summary> public class SessionTest1 : IHttpHandler,IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; context.Session["test1"] = "baidu"; context.Session["test2"] = 888; } public bool IsReusable { get { return false; } } }View Code
读取session
/// <summary> /// SessionTest2 的摘要说明 /// </summary> public class SessionTest2 : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string s1=(string)context.Session["test1"]; context.Response.Write(s1 == null ? "没找到" : s1); } public bool IsReusable { get { return false; } } }View Code
session记住登录用户名
html代码
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <meta charset="utf-8" /> </head> <body> <form action="Login1.ashx" method="post"> <input type="text" name="username"/> <input type="password" name="password" /> <input type="submit" /> </form> </body> </html>View Code
Login1.ashx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace _06_Session入门 { /// <summary> /// Login1 的摘要说明 /// </summary> public class Login1 : IHttpHandler,IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string username = context.Request["username"]; string password = context.Request["password"]; if(password=="123") { context.Session["username"] = username; context.Response.Write("ok"); } else { context.Response.Write("密码错误"); } } public bool IsReusable { get { return false; } } } }View Code
Page1.ashx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace _06_Session入门 { /// <summary> /// page1 的摘要说明 /// </summary> public class page1 : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string username = (string)context.Session["username"]; if (username==null) { context.Response.Write("请登录"); } else if(username=="admin") { context.Response.Write("看美丽图片"); } else { context.Response.Write("当前用户名"+username+"没权限查看"); } } public bool IsReusable { get { return false; } } } }View Code
Session记住登录之前页面
Login.ashx
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.SessionState; namespace _07_Session案例登录后返回到之前页面 { /// <summary> /// Login 的摘要说明 /// </summary> public class Login : IHttpHandler,IRequiresSessionState { public const string LOGINUSERNAME = "LoginUserName"; public const string LOGINURL = "LoginUrl";//尝试登录的页面地址 //为了以后方便加处理代码,以后用户都访问ashx,而不直接访问html public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string btnLogin = context.Request["btnLogin"]; string html = CommHelper.ReadHtml("~/Login.html"); if (string.IsNullOrEmpty(btnLogin)) { html = html.Replace("@msg",""); context.Response.Write(html); } else { string username = context.Request["username"]; string password = context.Request["password"]; int count= (int)SQLHelper1.SQLHelper.ExecuteScalar("select count(*) from T_Users where UserName=@UserName and PassWord=@PassWord", new SqlParameter { ParameterName = "@UserName", Value = username }, new SqlParameter { ParameterName = "@password", Value = password }); if (count <= 0) { html = html.Replace("@msg", "登录失败"); context.Response.Write(html); } else { context.Session[Login.LOGINUSERNAME] = username;//当前登录用户名写到Session string url =(string) context.Session[Login.LOGINURL]; if(url!=null) { context.Response.Redirect(url);//重定向登录前的页面 } //context.Response.Redirect("ChangePassword.ashx"); } } } public bool IsReusable { get { return false; } } } }View Code
ChangePassword.ashx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace _07_Session案例登录后返回到之前页面 { /// <summary> /// ChangePassword 的摘要说明 /// </summary> public class ChangePassword : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //如果浏览器提交伪造的session 这里取的username是null //因为session存储在服务器中,根据你请求的sessionId来识别你请求对应的session数据。sessionId是存储在cookie中的,不同会话的sessionId都不一样是使用session的自动生成的 string username =(string) context.Session[Login.LOGINUSERNAME]; if(username==null) { context.Session[Login.LOGINURL] = context.Request.Url.ToString();//把当前地址存到session中 context.Response.Redirect("Login.ashx"); return; } else { context.Response.Write("修改密码"+username + "<a href='Logout.ashx'>退出登录</a>"); } } public bool IsReusable { get { return false; } } } }View Code
yue.ashx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace _07_Session案例登录后返回到之前页面 { /// <summary> /// QueryYuE 的摘要说明 /// </summary> public class QueryYuE : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //如果浏览器提交伪造的session 这里取的username是null //因为session存储在服务器中,根据你请求的sessionId来识别你请求对应的session数据。sessionId是存储在cookie中的,不同会话的sessionId都不一样是使用session的自动生成的 string username = (string)context.Session[Login.LOGINUSERNAME]; if (username == null) { context.Session[Login.LOGINURL] = context.Request.Url.ToString();//把当前地址存到session中 context.Response.Redirect("Login.ashx"); return; } else { context.Response.Write("余额->" + username+"<a href='Logout.ashx'>退出登录</a>"); } } public bool IsReusable { get { return false; } } } }View Code
logout.ashx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace _07_Session案例登录后返回到之前页面 { /// <summary> /// Logout 的摘要说明 /// </summary> public class Logout : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Session.Abandon(); context.Response.Redirect("Login.ashx"); } public bool IsReusable { get { return false; } } } }View Code
login.html
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <meta charset="utf-8" /> </head> <body> <form action="Login.ashx" method="post"> <table> <tr><td>用户名</td><td><input type="text" name="username" /></td></tr> <tr><td>密码</td><td><input type="password" name="password" /></td></tr> <tr><td><input type="submit" name="btnLogin" value="登录"/></td> <td>@msg</td></tr> </table> </form> </body> </html>View Code
第五章ASP.NET WebForm
aspx和ashx关系:aspx就是一个特殊的ashx,aspx对应的类是Page,它是实现了IHttpHandler接口,所以可以说aspx是高级的HttpHandler
反编译看:其实=就相当于Response.Write(),直接写Response.Write()也可以
第六章AJAX
找工作前一定背下来
//找工作之前一定要能把下面的代码背着写出来。 var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //创建XMLHTTP对象,考虑兼容性 xmlhttp.open("POST", "AJAXTest.ashx?i=5&j=10", true); //“准备”向服务器的GetDate1.ashx发出Post请求(GET可能会有缓存问题),Post请求浏览器一定不会缓存。这里还没有发出请求。true代表异步请求。 xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) //readyState == 4 表示服务器返回完成数据了。之前可能会经历2(请求已发送,正在处理中)、3(响应中已有部分数据可用了,但是服务器还没有完成响应的生成) { if (xmlhttp.status == 200) //如果状态码为200则是成功 { alert(xmlhttp.responseText); } else { alert("AJAX服务器返回错误!"); } } } //不要以为if (xmlhttp.readyState == 4) {在send之前执行!!!! xmlhttp.send(); //这时才开始发送请求 //发出请求后不等服务器返回数据,就继续向下执行,所以不会阻塞,界面就不卡了,这就是AJAX中“A”的含义“异步”。试着在ashx加一句Thread.Sleep(3000); 额外提一点,如果要在send方法中发送报文体,比如send("name=5"),则需要设定Content-Type报文头: xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 否则在服务器端是无法通过context.Request["name"]获得值的。View Code
简单ajax封装
简单的ajax封装: function ajax(url,onsuccess,onfail) { var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); xmlhttp.open("POST", url, true); xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) { if (xmlhttp.status == 200) { onsuccess(xmlhttp.responseText); } else { onfail(xmlhttp.status); } } } xmlhttp.send(); //这时才开始发送请求 }View Code
检查用户名是否可用
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //"ok",用户可以用 //"error|含有违禁词汇","error|用户名已被使用" string username = context.Request["username"]; if (string.IsNullOrWhiteSpace(username)) { context.Response.Write("error|用户名必填"); return; } if (username.Length<3||username.Length>10) { context.Response.Write("error|用户名长度必须介于3和10之间"); return; } if (username.Contains("毒品") || username.Contains("手枪")) { context.Response.Write("error|含有违禁词汇"); return; } int c =(int)SqlHelper.ExecuteScalar("select count(*) from T_Users where UserName=@UserName", new SqlParameter("@UserName", username)); if (c > 0) { context.Response.Write("error|用户名已经被使用"); return; } context.Response.Write("ok"); }View Code
<!DOCTYPE html> <html xmlns="http://www.w3/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script type="text/javascript" src="jquery-1.5.2.js"></script> <script type="text/javascript" src="rpajax.js"></script> <script type="text/javascript"> $(function () { $("#username").blur(function () { var username = $("#username").val(); ajax("CheckUserName.ashx?username="+username, function (resTxt) { if (resTxt == "ok") { $("#msg").text("此用户名可用"); } else { var strs = resTxt.split("|"); if (strs[0] == "error") { $("#msg").text(strs[1]); } } }, function (status) { alert("出错"); }); }); }); </script> </head> <body> 傻瓜化只是让我们的工作变得简单,而不是让我们变成傻子!<br /> 用户名:<input type="text" id="username" /><span id="msg"></span> </body> </html>View Code
数据加载到表格
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; DataTable dt = SqlHelper.ExecuteQuery("select * from T_Users"); //1,admin,123|2,rupeng,321 List<string> list = new List<string>(); foreach (DataRow row in dt.Rows) { list.Add(row["Id"]+","+row["UserName"]+","+row["Password"]); } string str = string.Join("|", list); context.Response.Write(str); }View Code
<!DOCTYPE html> <html xmlns="http://www.w3/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script src="jquery-1.5.2.js"></script> <script src="rpajax.js"></script> <script type="text/javascript"> $(function () { ajax("LoadUsers.ashx", function (resTxt) { //alert(resTxt); var users = resTxt.split("|"); for (var i = 0; i < users.length; i++) { var user = users[i]; var fields = user.split(","); var id = fields[0]; var username = fields[1]; var password = fields[2]; $("#tbody1").append($("<tr><td>" + id + "</td><td>" + username + "</td><td>" + password + "</td></tr>")); } }, function (status) { alert("加载错误");}); }); </script> </head> <body> <table> <thead> <tr><th>id</th><th>用户名</th><th>密码</th></tr> </thead> <tbody id="tbody1"> </tbody> </table> </body> </html>View Code
json转js对象
var s="{name:'aaa',age:8}"; var p=eval("("+s+")");
新版浏览器都原生支持JSON.parse,不支持的引用json2.js也就可以了
c#转json
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; /* string[] strs = { "rupeng","baidu","google"}; JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(strs); context.Response.Write(json);*/ Person p1 = new Person(); p1.Name = "rupeng"; p1.Age = 18; p1.Id = 1; Person p2 = new Person(); p2.Name = "baidu"; p2.Age = 3; p2.Id = 2; /* List<Person> list = new List<Person>(); list.Add(p1); list.Add(p2); JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(list); context.Response.Write(json);*/ /* Person[] persons = new Person[] { p1,p2}; JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(persons); context.Response.Write(json);*/ //匿名类型的对象 var p = new { Id=8,Name="rupeng",Height=180}; //Console.WriteLine(p.Name); // p.Name = "";匿名类型的属性是只读的(反编译得出的结论) JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(p); context.Response.Write(json); }View Code
JQuery的AJAX封装
$.ajax({ type: "post", url: "Ajax1.ashx", data: { i1: $("#txt1").val(), i2: $("#txt2").val() }, success: function (data, txtStatus) {alert(data);}, error: function () { alert("错误"); } });
ajax处理json
<script type="text/javascript"> $(function () { /* $.ajax({ type: "post", url: "JQueryAJAXTest1.ashx", data: { i1: 10, i2: 3 }, success: function (resTxt) { //alert(resTxt); var nums = $.parseJSON(resTxt);//json字符串转换为javascript对象 for (var i = 0; i < nums.length; i++) { alert(nums[i]); } }, error:function(){ alert("ajax出错"); } });*/ /* $.ajax({ type: "post", url: "JQueryAJAXTest1.ashx", dataType:"json", data: { i1: 10, i2: 3 }, success: function (nums) { //如果把dataType设置为"json",那么success的第一个参数就是json转换后的JavaScript对象,不需要再手动parseJson for (var i = 0; i < nums.length; i++) { alert(nums[i]); } }, error: function () { alert("ajax出错"); } });*/ $.ajax({ type: "post", url: "JQueryAJAXTest1.ashx", data: { i1: 10, i2: 3 }, success: function (nums) { //如果服务器返回的报文contenttype为:application/json,那么jquery也会自动把报文体转换为JavaScript对象,传递给success指向的匿名方法 for (var i = 0; i < nums.length; i++) { alert(nums[i]); } }, error: function () { alert("ajax出错"); } }); }); </script>
第七章ASP.NET零碎
ServerPush
<!DOCTYPE html> <html xmlns="http://www.w3/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script src="jquery-1.5.2.js"></script> <script type="text/javascript"> var recv = function () { var me = $("#me").val(); $.ajax({ type: "post", url: "ServerPushChat.ashx", data: { action: "receive", me: me }, success: function (data) { $("#ulMsg").append($("<li>" + data.FromUserName + "对我说:" + data.Msg + "</li>")); recv();//收到后再次向服务器请求。再给哥一条消息 }, error: function () { recv();//哪怕网络请求失败(比如说网络短暂的故障),也再次发出请求 } }); }; $(function () { $("#btnSend").click(function () { var me = $("#me").val(); var toUserName = $("#toUserName").val(); var msg = $("#msg").val(); $.ajax({ type: "post", url: "ServerPushChat.ashx", data: { action: "send", me: me, toUserName: toUserName, msg: msg }, success: function (data) { if (data.Status == "ok") { $("#ulMsg").append($("<li>我对" + toUserName + "说:" + msg + "</li>")); $("#msg").val(""); } else { alert("发送出错,返回报文无法识别"); } }, error: function () { alert("发送出错"); } }); }); $("#btnLogin").click(function () { recv(); $(this).attr("disabled", "disabled"); }); /* $("#btnLogin").click(function () { var me = $("#me").val(); $.ajax({ type: "post", url: "ServerPushChat.ashx", data: { action: "receive", me: me }, success: function (data) { $("#ulMsg").append($("<li>" + data.FromUserName + "对我说:" + data.Msg + "</li>")); }, error: function () { } }); });*/ }); </script> </head> <body> 我是:<input type="text" id="me" /><input type="button" id="btnLogin" value="登陆" /><br /> 发给:<input type="text" id="toUserName" /> 说:<input type="text" id="msg" /> <input type="button" id="btnSend" value="发送" /><br /> <br /> <ul id="ulMsg"> </ul> </body> </html>View Code
//浏览器向他发请求“servpushchat.aspx?me=rupeng” //请把发给rupeng的消息发给我一条 public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/json"; string action = context.Request["action"]; if (action == "send") { string me = context.Request["me"]; string toUserName = context.Request["toUserName"]; string msg = context.Request["Msg"]; SqlHelper.ExecuteNonQuery("Insert into T_Msgs(FromUserName,ToUserName,Msg) values(@FromUserName,@ToUserName,@Msg)", new SqlParameter("@FromUserName", me), new SqlParameter("@ToUserName", toUserName), new SqlParameter("@Msg", msg)); context.Response.Write(new JavaScriptSerializer().Serialize(new { Status="ok"})); } else if (action == "receive") { string me = context.Request["me"];//我是:rupeng。 while (true) { DataTable dt = SqlHelper.ExecuteQuery("select top 1 * from T_Msgs where ToUserName=@ToUserName", new SqlParameter("@ToUserName", me)); if (dt.Rows.Count <= 0) { Thread.Sleep(500);//没找到,则休息500秒再查,这样避免对数据库的查询压力 //和占用web服务器cpu资源 continue;//下一次while } else { DataRow row = dt.Rows[0]; long id = (long)row["Id"]; string fromUserName = (string)row["FromUserName"]; //string toUserName = (string)row["ToUserName"]; string msg = (string)row["Msg"]; SqlHelper.ExecuteNonQuery("delete from T_Msgs where Id=@Id", new SqlParameter("@Id", id)); var data = new { FromUserName = fromUserName, Msg = msg }; string json = new JavaScriptSerializer().Serialize(data); context.Response.Write(json); break; } } } else { throw new Exception("action错误"); } }View Code
Global
注意:Global一定要建在项目根目录下 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Security; using System.Web.SessionState; namespace Web1 { public class Global : System.Web.HttpApplication { //自从服务器启动起来,网站第一次被访问的时候Application_Start执行 protected void Application_Start(object sender, EventArgs e) { File.AppendAllText("d:\\1.txt", DateTime.Now+"Application_Start\r\n"); } //Session启动时 protected void Session_Start(object sender, EventArgs e) { File.AppendAllText("d:\\1.txt", DateTime.Now + "Session_Start\r\n"); } //当一个请求过来的时候 //html等静态文件是iis直接把文件给到浏览器,不经过asp引擎的处理。 //所以不会调用Application_BeginRequest方法 protected void Application_BeginRequest(object sender, EventArgs e) { //即使用户访问一个不存在的页面,那么Application_BeginRequest也会被调用 File.AppendAllText("d:\\1.txt", DateTime.Now + "Application_BeginRequest:"+ Context.Request.RawUrl + "\r\n"); //Context.RewritePath("WebExcel.html");//请求重写在服务器内部发生 //File.AppendAllText("d:\\1.txt", DateTime.Now + "Context.Request.Path:" + //Context.Request.Path + "\r\n"); int? count =(int?)Application.Get("Count"); if (count == null) { count = 1; } count++; Application.Lock(); Application.Set("Count", count); Application.UnLock(); //Url重写:UrlRewrite。ViewPerson-1.aspx Match match = Regex.Match(Context.Request.Path, @"^/ViewPerson\-(\d+)\.aspx$"); if (match.Success) { string id = match.Groups[1].Value; Context.RewritePath("/ViewPerson.aspx?id="+id); } } protected void Application_AuthenticateRequest(object sender, EventArgs e) { } //程序中发生未处理异常 protected void Application_Error(object sender, EventArgs e) { File.AppendAllText("d:\\1.txt", DateTime.Now + "Application_Error:"+ Context.Error + "\r\n"); } //(*)Session过期(只有进程内Session,也就是InProc过期的时候才会调用Session_End) protected void Session_End(object sender, EventArgs e) { File.AppendAllText("d:\\1.txt", DateTime.Now + "Session_End\r\n"); } protected void Application_End(object sender, EventArgs e) { File.AppendAllText("d:\\1.txt", DateTime.Now + "Application_End\r\n"); } } }View Code
UrlRewrite
//当一个请求过来的时候 //html等静态文件是iis直接把文件给到浏览器,不经过asp引擎的处理。 //所以不会调用Application_BeginRequest方法 protected void Application_BeginRequest(object sender, EventArgs e) { //即使用户访问一个不存在的页面,那么Application_BeginRequest也会被调用 File.AppendAllText("d:\\1.txt", DateTime.Now + "Application_BeginRequest:"+ Context.Request.RawUrl + "\r\n"); //Context.RewritePath("WebExcel.html");//请求重写在服务器内部发生 //File.AppendAllText("d:\\1.txt", DateTime.Now + "Context.Request.Path:" + //Context.Request.Path + "\r\n"); int? count =(int?)Application.Get("Count"); if (count == null) { count = 1; } count++; Application.Lock(); Application.Set("Count", count); Application.UnLock(); //Url重写:UrlRewrite。ViewPerson-1.aspx Match match = Regex.Match(Context.Request.Path, @"^/ViewPerson\-(\d+)\.aspx$"); if (match.Success) { string id = match.Groups[1].Value; Context.RewritePath("/ViewPerson.aspx?id="+id); } }View Code
asp缓存
//Cache是全局共享的 DataTable dt = (DataTable)HttpRuntime.Cache["persons"]; if (dt == null)//如果Cache中没有,再去数据库中查询 //这样可以降低数据库服务器的压力 { dt = SqlHelper.ExecuteQuery("select * from T_Persons"); //存储缓存,30秒后过期 HttpRuntime.Cache.Insert("persons", dt, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero); } Repeater1.DataSource = dt; Repeater1.DataBind();
shtml更轻量级
<!--#include file="head.html"--> 222222222222222222222222222222222222 <!--#include file="foot.html"-->
IIS配置文档:
1、安装IIS。控制面板→程序→打开关闭Windows功能,Web管理服务和万维网服务都勾上。
2、部署网站:ASP.Net项目的发布:项目中点右键“发布”,选择“文件系统”,发布到一个文件夹下。
3、在IIS中新建网站,设定域名,这样多个域名可以放到一个IIS服务器上。需要绑定域名。
4、模拟域名,如果启用了UAC,则用管理员权限运行记事本,打开
C:\Windows\System32\drivers\etc下的hosts文件
做一下域名协议的欺骗。伪造一些域名出来。
5、如果报错报错“无法识别的属性“targetFramework”,则:
1)、把网站的应用程序池的 framework版本改成“4.0”
2)、C:\Windows\Microsoft.NET\Framework\v4.0.30319下用管理员权限运行( aspnet_regiis.exe -i )
6、默认文档问题,让用户访问www.web2的时候其实是访问www.web2/index.apsx:如果用户没有指定要访问哪个文件,则从上向下,匹配到谁,谁就是默认文档。
如果你修改hosts后不起作用,那么请把电脑管家、360安全卫士之类的所谓“安全软件、杀毒软件”卸载了(不是关了,是卸了)就行了。因为这些软件会阻止修改的hosts起作用。其实Windows7以后的操作系统,只要启用UAC,根本不用装什么“安全软件、杀毒软件”,根本不会中毒。当然如果你不愿意卸载这些软件,那么跳过本节内容就行了,因为工作后的项目中是买真正的域名去搞,不会搞这样的“假域名”。
转载于:https://wwwblogs/wangyinlon/p/7061138.html
版权声明:本文标题:笔记06ASP.NET核心 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1727774545a1128949.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论