ASP.NET的隐藏特性
这个问题的存在是因为它具有历史意义,但是这个网站对于这个网站来说不是一个很好的话题, 所以请不要把它当作你在这里可以提出类似问题的证据。
更多信息: https : //stackoverflow.com/faq
在边缘情况下,总有一些特征是有用的,但是正因为如此,大多数人都不了解它们。 我所要求的function通常不是教科书所教的。
你知道什么?
在testing时,您可以将电子邮件发送到计算机上的文件夹而不是SMTP服务器。 把这个放在你的web.config中:
<system.net> <mailSettings> <smtp deliveryMethod="SpecifiedPickupDirectory"> <specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\" /> </smtp> </mailSettings> </system.net>
如果将名为app_offline.htm的文件放在Web应用程序目录的根目录中,ASP.NET 2.0 +将closures该应用程序,并停止正常处理该应用程序的任何新传入请求,只显示app_offline.htm的内容为所有新的请求文件。
这是在将更改重新部署(或回滚)到生产服务器时显示“站点临时不可用”通知的最快和最简单的方法。
另外,正如marxidad所指出的那样 ,确保文件中至less有512字节的内容,这样IE6才能正确显示它。
throw new HttpException(404, "Article not found");
这将被ASP.NET返回,它将返回customErrors页面。 在最近的.NET Tip of the Post中了解到这个
这是最好的一个。 添加到你的web.config为更快的编译。 这是通过这个QFE后3.5SP1。
<compilation optimizeCompilations="true">
快速总结:我们在ASP.NET中引入了一个新的optimizeCompilations开关,在某些情况下可以大大提高编译速度。 有一些捕获,所以阅读更多的细节。 此开关目前可用作3.5SP1的QFE,并将成为VS 2010的一部分。
ASP.NET编译系统采取了非常保守的方法,使得它消除了以前任何时候“顶级”文件更改所做的工作。 “顶级”文件包括bin和App_Code中的任何内容以及global.asax。 虽然这适用于小应用程序,但对于非常大的应用程序几乎不可用。 例如,一个客户正在运行一个案例,在更改“bin”程序集后,刷新页面需要10分钟。
为了减轻这种痛苦,我们增加了一个“优化的”编译模式,它采用了一种不那么保守的重新编译方法。
通过这里 :
-
HttpContext.Current将始终允许您访问当前上下文的Request / Response /等,即使您无法访问Page的属性(例如,从松散耦合的助手类)。
-
通过调用Response.Redirect( url , false )将用户redirect到另一个页面后,可以继续在同一页面上执行代码。
-
如果你想要的只是一个编译的页面 (或任何IHttpHandler ),你不需要.ASPX文件。 只需将path和HTTP方法设置为指向web.config文件
<httpHandlers>
元素中的类<httpHandlers>
。 -
可以通过调用PageParser.GetCompiledPageInstance(virtualPath,aspxFileName,Context)以编程方式从.ASPX文件中检索Page对象。
在machine.config级别的零售模式:
<configuration> <system.web> <deployment retail="true"/> </system.web> </configuration>
重写web.config设置以将debugging强制为false,打开自定义错误并禁用跟踪。 在发布之前不要再忘记更改属性 – 只需将其全部configuration为开发或testing环境,并更新生产零售设置即可。
在内容页面启用MasterPages的智能感知
我相信这是一个非常罕见的黑客
大多数情况下,您必须使用findcontrol方法,并在您想要使用它们时从内容页面的母版页中将控件强制转换 , MasterType指令将启用Visual Studio中的intellisense。
只需添加一个指令到页面
<%@ MasterType VirtualPath="~/Masters/MyMainMasterPage.master" %>
如果你不想使用虚拟path并使用类名来代替
<%@ MasterType TypeName="MyMainMasterPage" %>
在这里获取完整的文章
HttpContext.Items作为请求级别的caching工具
我头脑中有两件事情突出:
1)您可以打开和closures跟踪代码:
#ifdef DEBUG if (Context.Request.QueryString["DoTrace"] == "true") { Trace.IsEnabled = true; Trace.Write("Application:TraceStarted"); } #endif
2)您只能使用一个共享的“代码隐藏”文件来构build多个.aspx页面。
构build一个类.cs文件:
public class Class1:System.Web.UI.Page { public TextBox tbLogin; protected void Page_Load(object sender, EventArgs e) { if (tbLogin!=null) tbLogin.Text = "Hello World"; } }
然后你可以有任意数量的.aspx页面(在删除了.designer.cs和.cs代码之后,VS已经生成了):
<%@ Page Language="C#" AutoEventWireup="true" Inherits="Namespace.Class1" %> <form id="form1" runat="server"> <div> <asp:TextBox ID="tbLogin" runat="server"></asp: TextBox > </div> </form>
您可以在ASPX中拥有不在Class1中的控件,反之亦然,但是您需要记住检查控件是否为空值。
您可以使用:
Request.Params[Control.UniqueId]
为了得到一个控件的值BEFORE的viewstate被初始化(Control.Text等在这一点上是空的)。
这对于Init中的代码很有用。
的WebMethods。
您可以使用ASP.NET AJAXcallback来放置在ASPX页面中的Web方法。 您可以使用[WebMethod()]和[ScriptMethod()]属性修饰静态方法。 例如:
[System.Web.Services.WebMethod()] [System.Web.Script.Services.ScriptMethod()] public static List<string> GetFruitBeginingWith(string letter) { List<string> products = new List<string>() { "Apple", "Banana", "Blackberry", "Blueberries", "Orange", "Mango", "Melon", "Peach" }; return products.Where(p => p.StartsWith(letter)).ToList(); }
现在,在你的ASPX页面中,你可以这样做:
<form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" /> <input type="button" value="Get Fruit" onclick="GetFruit('B')" /> </div> </form>
并通过JavaScript调用你的服务器端方法:
<script type="text/javascript"> function GetFruit(l) { PageMethods.GetFruitBeginingWith(l, OnGetFruitComplete); } function OnGetFruitComplete(result) { alert("You got fruit: " + result); } </script>
在开始长时间运行的任务之前,请检查客户端是否仍然连接:
if (this.Response.IsClientConnected) { // long-running task }
一个鲜为人知并且很less使用的ASP.NET特性是:
标签映射
它很less使用,因为只有一个特定的情况,你需要它,但是当你需要的时候,它是如此的方便。
一些关于这个小知识的文章:
ASP.NET中的标记映射
在ASP.NET 2.0中使用标记映射
并从最后一篇文章:
标记映射允许您在编译时在Web应用程序的每个页面上交换兼容的控件。 一个有用的例子是,如果你有一个股票的ASP.NET控件,如DropDownList,并且你想用一个从DropDownList派生的自定义控件来replace它。 这可以是自定义的控件,以提供更优化的查找数据caching。 而不是编辑每个Web窗体,并用您的自定义版本replace内置的DropDownLists,你可以通过修改web.config让ASP.NET有效地为你做:
<pages> <tagMapping> <clear /> <add tagType="System.Web.UI.WebControls.DropDownList" mappedTagType="SmartDropDown"/> </tagMapping> </pages>
HttpModules 。 build筑是疯狂的优雅。 也许不是一个隐藏的function,但酷炫的。
您可以使用.aspx页面中的ASP.NET注释将包括服务器控件在内的整个页面部分注释掉。 而被注释掉的内容将永远不会发送给客户端。
<%-- <div> <asp:Button runat="server" id="btnOne"/> </div> --%>
代码expression式生成器
示例标记:
Text = '<%$ Code: GetText() %>' Text = '<%$ Code: MyStaticClass.MyStaticProperty %>' Text = '<%$ Code: DateTime.Now.ToShortDateString() %>' MaxLenth = '<%$ Code: 30 + 40 %>'
代码expression式生成器的真正之处在于,您可以在非数据绑定情况下使用数据绑定类似的expression式。 您也可以创build其他执行其他function的expression式构build器。
web.config中:
<system.web> <compilation debug="true"> <expressionBuilders> <add expressionPrefix="Code" type="CodeExpressionBuilder" />
使这一切都发生的CS类:
[ExpressionPrefix("Code")] public class CodeExpressionBuilder : ExpressionBuilder { public override CodeExpression GetCodeExpression( BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { return new CodeSnippetExpression(entry.Expression); } }
ASHX文件types的用法:
如果您只想输出一些基本的html或xml而不通过页面事件处理程序,那么您可以以简单的方式实现HttpModule
将该页命名为SomeHandlerPage.ashx,并将下面的代码(只是一行)放在其中
<%@ webhandler language="C#" class="MyNamespace.MyHandler" %>
然后是代码文件
using System; using System.IO; using System.Web; namespace MyNamespace { public class MyHandler: IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/xml"; string myString = SomeLibrary.SomeClass.SomeMethod(); context.Response.Write(myString); } public bool IsReusable { get { return true; } } } }
基于目标浏览器等设置服务器控制属性 。
<asp:Label runat="server" ID="labelText" ie:Text="This is IE text" mozilla:Text="This is Firefox text" Text="This is general text" />
这一点让我吃了一惊。
System.Web.VirtualPathUtility
我曾参与过一家领先的安全公司进行安全审计的asp.net应用程序,并且学习了这个简单的技巧,以防止一个鲜为人知的重要安全漏洞。
下面的解释是: http : //www.guidanceshare.com/wiki/ASP.NET_2.0_Security_Guidelines_-_Parameter_Manipulation#Consider_Using_Page.ViewStateUserKey_to_Counter_One-Click_Attacks
考虑使用Page.ViewStateUserKey来反击一击攻击。 如果您对呼叫者进行身份validation并使用ViewState,请在Page_Init事件处理程序中设置Page.ViewStateUserKey属性以防止一次单击攻击。
void Page_Init (object sender, EventArgs e) { ViewStateUserKey = Session.SessionID; }
将该属性设置为您知道的每个用户唯一的值,例如会话ID,用户名或用户标识符。
当攻击者创build一个网页(.htm或.aspx)时,就会出现一次单击攻击,该网页包含一个名为__VIEWSTATE的隐藏表单字段,该隐藏表单字段已经被ViewState数据填充。 ViewState可以从攻击者以前创build的页面生成,例如具有100个项目的购物车页面。 攻击者诱使不知情的用户浏览页面,然后攻击者将页面发送到ViewState有效的服务器。 服务器无法知道ViewState是从攻击者发起的。 ViewStatevalidation和HMAC不会抵消这种攻击,因为ViewState是有效的,并且页面是在用户的安全上下文下执行的。
通过设置ViewStateUserKey属性,当攻击者浏览页面来创buildViewState时,属性被初始化为他或她的名字。 当合法用户将页面提交给服务器时,它将以攻击者的名字进行初始化。 因此,ViewState HMAC检查失败,并生成exception。
HttpContext.Current.IsDebuggingEnabled
这对于确定要输出哪些脚本(最小或完整版本)或其他任何您可能想要在开发中但不活动的情况非常有用。
包含在ASP.NET 3.5 SP1中:
- customErrors现在支持具有“ResponseRewrite”值的“redirectMode”属性。 显示错误页面而不更改URL。
- 表单标签现在可以识别action属性。 当你使用URL重写时非常有用
面板中的DefaultButton属性。
它为特定面板设置默认button。
使用configSource来分割configuration文件。
例如,您可以使用web.config文件中的configSource属性将configuration元素推送到其他.config文件,而不是:
<appSettings> <add key="webServiceURL" value="https://some/ws.url" /> <!-- some more keys --> </appSettings>
…可以将整个appSettings部分存储在另一个configuration文件中。 这里是新的web.config
:
<appSettings configSource="myAppSettings.config" />
myAppSettings.config
文件:
<appSettings> <add key="webServiceURL" value="https://some/ws.url" /> <!-- some more keys --> </appSettings>
这对于将应用程序部署到客户的情况非常有用,并且您不希望它们干扰web.config文件本身,只希望它们能够更改一些设置。
ref: http : //weblogs.asp.net/fmarguerie/archive/2007/04/26/using-configsource-to-split-configuration-files.aspx
Page指令中的MaintainScrollPositionOnPostback属性。 它用于保持跨回发的aspx页面的滚动位置。
HttpContext.IsCustomErrorEnabled是一个很酷的function。我发现它不止一次有用。 这是一个简短的文章 。
默认情况下,自定义控件的标记之间的任何内容都将作为子控件添加。 这可以在AddParsedSubObject()覆盖中进行截取,以进行过滤或附加parsing(例如,LiteralControls中的文本内容):
protected override void AddParsedSubObject(object obj) { var literal = obj as LiteralControl; if (literal != null) Controls.Add(parseControl(literal.Text)); else base.AddParsedSubObject(obj); }
…
<uc:MyControl runat='server'> ...this text is parsed as a LiteralControl... </uc:MyControl>
如果您有ASP.NET生成一个RSS提要,它有时会在页面的顶部放置一个额外的行。 这不会与通用的RSSvalidation器validation。 您可以通过将页面指令<@Page>
放在页面的底部来解决这个问题。
在ASP.NET v3.5添加路由之前,您可以简单地通过编写HTTPModule来在页面pipe道中及早重写请求(如BeginRequest事件)来创build自己的友好URL。
像http:// servername / page / Param1 / SomeParams1 / Param2 / SomeParams2这样的url会被映射到下面的其他页面(通常使用正则expression式)。
HttpContext.RewritePath("PageHandler.aspx?Param1=SomeParms1&Param2=SomeParams2");
DotNetNuke有一个非常好的HttpModule,它为他们的友好的url做了这个。 对于无法部署.NET v3.5的机器仍然有用。