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的机器仍然有用。