创建缩略图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var file = context.Request.Files[0];
using (var bigImage = Image.FromStream(file.InputStream)) { using (var smallImage = new Bitmap(200, 200 * bigImage.Height / bigImage.Width)) { using (var graphics = Graphics.FromImage(smallImage)) { graphics.DrawImage(bigImage, 0, 0, smallImage.Width, smallImage.Height); } bigImage.Save(context.Server.MapPath(Guid.NewGuid() + "_big.jpg")); smallImage.Save(context.Server.MapPath(Guid.NewGuid() + "_small.jpg")); } }
|
WebForm分为两个文件aspx和aspx.cs
aspx是页面模板,是页面描述文件,就是html+js+css的内容,和aspx.cs结合的更好,不用像一般处理程序那样程序员自己去输出HTML字符串或读取填充模板,控件都是定义在aspx中,内联的JavaScript、CSS也是写在aspx中的
前台页面上的@Page指令集。
服务端的C#代码是定义在aspx.cs中。aspx控制页面长相,cs控制程序逻辑,这种“前aspx后cs”的方式就被称为CodeBehind(代码后置)。
强调:后台页面可以把Page_Load看成是WinForm里的Load事件(“最先运行”)。
1.直接在后台通过Response.Write(“内容”);
- aspx中也可以访问cs中定义的非私有的成员
- 缺点:全都输出在页面的最上面。
2.使用<%%>在前台页面指定输出。
- 可以编写复杂的C#代码, for等所有C#代码都可以写在aspx中
如:<%=UserName %><%=SayHello(); %><%if (UserName == “aaa”) { UserName = “bbb”; } %>
深入理解aspx
创建一个webform,对应的aspx.cs:
1 2 3 4 5 6 7
| public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } }
|
可以看到它集成System.Web.UI.Page,转到page元数据看到
1
| public class Page : TemplateControl, IHttpHandler
|
Page继承自IHttpHandler,可以得出其实Page就是一个进一步封装的类,这时候我向class WebForm1中添加protected字段
1
| protected int _num = 10;
|
aspx页面添加一句
运行可以看到10出现在html页面,为什么aspx可以访问cs里面的内容呢,看aspx头部有一个Inherits="_43.WebForm1"
从字面上看,它是再说继承自_43.WebForm1,事实上aspx编译之后确实如此,
为了证明这一点,我向aspx里添加一句并拖一个控件进去,为了获取页面编译完成后dll的位置
1 2
| <asp:Button ID="Button1" runat="server" Text="Button" /> <%=System.Reflection.Assembly.GetExecutingAssembly().Location %>
|
同时往pageload中添加
1 2 3 4
| protected void Page_Load(object sender, EventArgs e) { Response.Write(System.Reflection.Assembly.GetExecutingAssembly().Location); }
|
html显示的是
1 2
| C:\Users\luox78\AppData\Local\Temp\Temporary\ASP.NET\Files\root\2d000352\67fdd243\assembly\dl3\fd7cca4a\cf2ad37e_aea1d301\43.dll 10 Button C:\Users\luox78\AppData\Local\Temp\Temporary\ASP.NET\Files\root\2d000352\67fdd243\App_Web_amvk3cjo.dll
|
分别用reflector打开,看到cs派生类里是ASP.webform1_aspx,而page页面程序集ASP命名空间下就是webform1_aspx,所以aspx页面可以访问cs里面的字段可以解释了,这时候打开ASP.webform1_aspx里面有一个方法


1 2 3 4 5 6 7 8
| [DebuggerNonUserCode] protected override void FrameworkInitialize() { base.FrameworkInitialize(); this.__BuildControlTree(this); base.AddWrappedFileDependencies(__fileDependencies); base.Request.ValidateInput(); }
|
this.__BuildControlTree(this);这句代表aspx里面的所有空间都被编译成了控件树,点开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [DebuggerNonUserCode] private void __BuildControlTree(webform1_aspx __ctrl) { this.InitializeCulture(); LiteralControl control = this.__BuildControl__control2(); IParserAccessor accessor = __ctrl; accessor.AddParsedSubObject(control); HtmlHead head = this.__BuildControl__control3(); accessor.AddParsedSubObject(head); LiteralControl control2 = this.__BuildControl__control6(); accessor.AddParsedSubObject(control2); HtmlForm form = this.__BuildControlform1(); accessor.AddParsedSubObject(form); LiteralControl control3 = this.__BuildControl__control7(); accessor.AddParsedSubObject(control3); }
|
貌似里面创建很多html元素对象,这里我们就知道,所有的aspx页面里面的东西都会被编译成对应的对象,这时候回顾一下aspx页面body里面的内容
1 2 3 4 5 6 7 8 9 10
| <body> <form id="form1" runat="server"> <div> <%=_num %> <asp:Button ID="Button1" runat="server" Text="Button" /> <%=System.Reflection.Assembly.GetExecutingAssembly().Location %> </div> </form> </body>
|
显示body,然后form,form里面有button,__BuildControlTree
,里面也印证了这一点,我们打开创建form的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| [DebuggerNonUserCode] private HtmlForm __BuildControlform1() { HtmlForm form = new HtmlForm() base.form1 = form form.ID = "form1" Button button = this.__BuildControlButton1() IParserAccessor accessor = form accessor.AddParsedSubObject(button); form.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1)) object[] parameters = new object[5] parameters[0] = form parameters[2] = 0x131 parameters[3] = 0x20 parameters[4] = false this.__PageInspector_SetTraceData(parameters) return form }
|
里面设置了form的一些属性同时创建了button,此时我们往html添加新的代码
1 2 3 4 5 6 7 8 9 10 11 12 13
| <body> <% for (int i = 0; i < 10; i++) {%> <h1>nihao</h1> <% } %> <form id="form1" runat="server"> <div> <%=_num %> <asp:Button ID="Button1" runat="server" Text="Button" /> <%=System.Reflection.Assembly.GetExecutingAssembly().Location %> </div> </form> </body>
|
添加了一个循环以便我们查看dll里面如何处理C#代码的,编译之后发现__BuildControlTree里面多了一句
__ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Render__control1));
点开 _Render_control1
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 26 27 28 29 30 31 32 33 34 35 36 37 38
| private void __Render__control1(HtmlTextWriter __w, Control parameterContainer) { int num2; object[] parameters = new object[] { __w, "/WebForm1.aspx", 160, 0x44, true }; this.__PageInspector_BeginRenderTracing(parameters); __w.Write("\r\n\r\n<!DOCTYPE html>\r\n\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n"); object[] objArray2 = new object[] { __w }; this.__PageInspector_EndRenderTracing(objArray2); parameterContainer.Controls[0].RenderControl(__w); object[] objArray3 = new object[] { __w, "/WebForm1.aspx", 0x162, 14, true }; this.__PageInspector_BeginRenderTracing(objArray3); __w.Write("\r\n<body>\r\n "); object[] objArray4 = new object[] { __w }; this.__PageInspector_EndRenderTracing(objArray4); object[] objArray5 = new object[] { __w, "/WebForm1.aspx", 0x170, 0x2c, false }; this.__PageInspector_BeginRenderTracing(objArray5); for (int i = 0; i < 10; i = num2 + 1) { object[] objArray6 = new object[] { __w }; this.__PageInspector_EndRenderTracing(objArray6); object[] objArray7 = new object[] { __w, "/WebForm1.aspx", 0x19c, 0x1a, true }; this.__PageInspector_BeginRenderTracing(objArray7); __w.Write("\r\n <h1>nihao</h1>\r\n "); object[] objArray8 = new object[] { __w }; this.__PageInspector_EndRenderTracing(objArray8); object[] objArray9 = new object[] { __w, "/WebForm1.aspx", 0x1b6, 7, false }; this.__PageInspector_BeginRenderTracing(objArray9); num2 = i; } object[] objArray10 = new object[] { __w }; this.__PageInspector_EndRenderTracing(objArray10); parameterContainer.Controls[1].RenderControl(__w); object[] objArray11 = new object[] { __w, "/WebForm1.aspx", 0x2c1, 20, true }; this.__PageInspector_BeginRenderTracing(objArray11); __w.Write("\r\n</body>\r\n</html>\r\n"); object[] objArray12 = new object[] { __w }; this.__PageInspector_EndRenderTracing(objArray12); }
|
看到for循环直接在里面,原来C#是直接和html元素一起编译成方法,最后转换成元素对象的,这时候或许你会有疑问cs里面是如何访问这些控件的,查看cs的dll可以看到
1 2 3 4 5 6 7 8 9 10 11
| public class WebForm1 : Page { protected int _num = 10; protected Button Button1; protected HtmlForm form1;
protected void Page_Load(object sender, EventArgs e) { base.Response.Write(Assembly.GetExecutingAssembly().Location); } }
|
一旦你在aspx中创建了控件,cs里面就会有对应的protected字段(在designer.cs中),cs里对控件属性的修改继承自他的aspx的那个类会进行相应的更改,并将它反应到最终生成的页面上
总结:

IsPostBack
用于判断是第一次get页面还是post回发
验证
cs里pageload时
1 2 3 4
| protected void Page_Load(object sender, EventArgs e) { Response.Write(this.IsPostBack); }
|
aspx中(aspx中form里面的button控件只会生成submit不会生成button)
1 2 3
| <form id="form1" runat="server"> <asp:Button ID="Button1" runat="server" Text="Button" /> </form>
|
浏览会看到只有第一次get是false,回发的都是true
如何实现的
既然服务器控件生成的是html form那我自己写一个
1 2 3
| <form id="form1" method="post" action="WebForm3.aspx"> <input type="submit" name="name" value="tijiao" /> </form>
|
cs里面跟上面一样,这时候运行会发现永远都是false,浏览器查看source我们就可以看出问题,runat serve的html里面多出了很多隐藏域,先将结果 IsPostBack是通过form中的隐藏域提交给服务器,如果没有接受到,那就是第一次请求,收到了肯定是回发。同时引出我们的下一部分viewstate
总结
1.IsPostBack用来判断表单是否是回发。(不是第一次请求),是点击表单的提交按钮回发过来的。是否是回发与get请求还是Post请求无关。但是一般情况下回发都是Post请求。一般Get请求都是第一次加载。
2.只有当使用服务器端表单<form runat="server">
IsPostBack才可以使用。如果使用客户端表单,则IsPostBack永远都是False.因为当使用服务器端表单的时候会自动生成一个隐藏域,才该隐藏域中,服务器写入了一些内容,通过这些内容就可以判断是否是回发。如果使用的是普通html表单,则需要自己写代码来判断是否是回发。
3.IsPostBack的使用方式,为什么要使用IsPostBack
4.用处:使用IsPostBack可以知道是不是第一次请求,通过viewstate可以将第一次加载的数据停留在页面中减少数据加载的次数。避免了每次点击按钮回发都重新加载一次数据。
ViewState
viewstate(视图状态),顾名思义就是view的aspx空间的值状态
pageload中添加
1
| ViewState["key"] = "nihao"
|
生成html里面有一个隐藏域为viewstate
1
| <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="P2yIH8jxqJKNyRGQn/BloDXHiGVvbfXBTzveFGTePfqct88mOSTSDiAJmfi3kLBaX+RRjSBf0RgEBmgfYTh1nQOXlqCGoRY2ccoHhM5M+buITfYkgxbsmXLRjBckuKji" />
|
value里面的值中就包含了nihao,下次解析的时候,我们不需要再次向页面传值也会显示,cs中的事件里面的改值就是通过这样实现的
缺点: 加大网站的流量、降低访问速度、机密数据放到表单中会有数据欺骗等安全性问题。
禁用ViewState :在asp顶部添加EnableViewState=”false”
1
| <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="_43.WebForm2" EnableViewState="false"%>
|