ASP.NET的隐藏功能

292

这个问题之所以存在是因为它具有历史意义,但它不被认为是一个好的、主题相关的问题,所以请不要把它作为你可以在这里问类似问题的证据。

更多信息:https://stackoverflow.com/faq


总有一些特定场景下会非常有用的功能,但正因为这个原因,大多数人并不知道它们的存在。我想请教那些不通常由课本教授的功能和技巧。

你知道哪些呢?


好问题,我希望能够投多次票! - Gavin Miller
1
同意。我喜欢这样的线程。框架有很多深度,有时你会惊讶于从未发现的东西。 - Deane
我从这个帖子的回复中学到了很多很酷的新技巧 - 谢谢! :) - Maxim Zaslavsky
16
与其说“Hidden features of..”,不如将这些内容命名为“Little Known features of..”,因为大多数答案在MSDN或其他地方都有详细记录,只是不常为人所知或使用。 - John K
请参考 http://meta.stackexchange.com/questions/56669/should-hidden-features-of-x-be-removed-closed-locked,http://meta.stackexchange.com/questions/57226/should-we-have-a-list-of-x-close-reason 以及相关的 Meta 帖子,讨论适当性和关闭。 - Roger Pate
53个回答

334

在测试时,您可以将电子邮件发送到计算机上的文件夹,而不是SMTP服务器。请将以下代码放入您的web.config文件中:

<system.net>
    <mailSettings>
        <smtp deliveryMethod="SpecifiedPickupDirectory">
            <specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\" />
        </smtp>
    </mailSettings>
</system.net>

6
真的吗?我正准备安装一个像Dumbster这样的假SMTP服务器。它是一个隐藏的宝石。 - Eduardo Molteni
2
有人知道是否可以指定UNC共享作为目录位置吗? - Mark Sherretta
32
最好将这个设置放在你的开发机器上的 machine.config 文件中,这样你就不需要在每个应用程序中更改 web.config 文件。 - Max Toro
我认为您可以配置SMTP服务器本身将所有内容都放入一个文件夹中,但这是服务器范围的,因此会影响其他应用程序。 - John Sheehan
这真的很有帮助。我们以前在测试时使用真实的SMTP服务器,但经常会出现卡顿的情况。 - Nayana Setty
显示剩余4条评论

210
如果在 Web 应用程序根目录下放置一个名为 app_offline.htm 的文件,ASP.NET 2.0+ 将关闭该应用程序并停止处理任何新的传入请求,仅显示 app_offline.htm 文件的内容 对于所有新请求
这是在重新部署(或回滚)更改到生产服务器时显示“网站暂时不可用”通知的最快最简单的方法。
此外,正如marxidad指出的那样,请确保文件中至少有 512 字节的内容,以便 IE6 正确地呈现它。

10
不要忘记IE“友好”消息的解决方法:http://tinyurl.com/app-offline-friendly。 - Mark Cidade
1
哎呀!在使用MOSS 2007时要小心。它只适用于自上次IIS重启以来已被访问过的页面。因此,如果您将此页面添加到wss虚拟根目录中,然后尝试打开以前未访问过的页面,您将会收到404错误。 - Marc
1
@Marc - 我从Scott Guthrie那里得到了这个提示,如果你感到慷慨的话,你可以在Gu的文章中发表评论,这将帮助很多SharePoint开发人员避免这种情况:http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx - Troy DeMonbreun
此外,这也会触发应用程序域的回收并在所有请求完成后关闭任何打开的数据库连接。 - Bart Verkoeijen
这里有一个需要注意的地方:IIS以404的HTTP状态码返回app_offline.htm内容。如果在离线模式下搜索引擎漫游并尝试索引您的站点,您可能不会喜欢结果。但是对于我的私人企业Web应用程序来说,它非常有效! - Larry Silverman

119
throw new HttpException(404, "Article not found");

这将被ASP.NET捕获,后者将返回customErrors页面。在最近的.NET每日技巧文章中了解到这个问题。


一些开发人员可能会认为,在HttpContext.Response中手动包装东西比在.NET书籍中抛出异常更好,因为后者是一种相当昂贵的操作。 - lubos hasko
这样做不太好吧?您正在显示404错误,而您想要显示一个错误/异常。 - Donnie Thomas
1
我能想到的一种情况是,如果有人恶意更改参数并输入了无效内容,您可能希望显示通用的404错误而不是具体的错误信息。 - John Sheehan
3
感谢点赞,纯粹是因为我现在意识到了.NET每日小技巧网站的存在。 - Kon
只有在 httpModule 或 httpHandler 中抛出时才能正常工作。 - Khaled Musaied

75

以下是最佳方案。将此添加到您的web.config文件中,可以大幅加快编译速度。这是3.5SP1版本后通过此QFE实现的。

<compilation optimizeCompilations="true">

简单概述:我们在ASP.NET中引入了一个新的 optimizeCompilations 开关,它可以在某些情况下大大提高编译速度。但需要注意一些细节,所以请继续阅读。该开关当前作为3.5SP1的 QFE 提供,并将成为VS 2010的一部分。

ASP.NET编译系统采用非常保守的方法,这会导致每当“顶级”文件更改时,它都会清除其之前做的任何工作。 “顶级”文件包括bin和App_Code中的任何内容以及global.asax。虽然对于小型应用程序很好用,但对于非常大型的应用程序来说几乎无法使用。例如,客户遇到了这样的情况:每次更改“bin”程序集后,刷新页面需要花费10分钟。

为了缓解这种痛苦,我们添加了一个“优化”的编译模式,它对重新编译采取了更少保守的方法。

来源:这里


6
在VS 2010中,默认启用此功能吗?还是我需要自己试一下? - M4N

73
  • HttpContext.Current 始终会给你访问当前上下文的请求/响应等信息,即使你没有访问页面属性的权限(例如,来自松耦合的辅助类)。

  • 通过调用 Response.Redirect(url, false) ,可以在将用户重定向到另一页后继续在同一页上执行代码。

  • 如果您只需要编译好的 Page(或任何IHttpHandler),则不需要 .ASPX 文件。只需在web.config文件的 <httpHandlers> 元素 中设置路径和 HTTP 方法即可指向该类。

  • 可以通过调用 PageParser.GetCompiledPageInstance(virtualPath,aspxFileName,Context) 从程序中检索 .ASPX 文件中的 Page 对象。


1
有人能解释一下这个东西该怎么用吗?我知道它有一定的价值,但我想不出来为什么... - Deane
5
如果您想将用户重定向到不同的地址,但仍需要进行一些后端处理(例如生成报告请求,重定向到报告生成状态页面,同时在后台继续生成报告),则可以这样做。 - Mark Cidade
@jdk:我曾在过去使用它来覆盖*.aspx请求的默认处理程序,以便我可以使用动态的内存中的IHttpHandler对象,但也可以使用GetCompiledPageInstance()来处理物理的*.aspx文件。 - Mark Cidade
@Mark Cidade:谢谢你的信息。我还有一个不清楚的问题:你是将它转换为不同的数据类型以有效使用它,还是继续通过IHttpHandler数据类型引用它? - John K
@jdk: 我只是在IHttpHandler接口上调用ProcessRequest()方法。 - Mark Cidade
显示剩余2条评论

70

机器配置文件级别的零售模式:

<configuration>
  <system.web>
    <deployment retail="true"/>
  </system.web>
</configuration>

重写web.config设置以强制调试为false,打开自定义错误并禁用跟踪。不再忘记在发布前更改属性 - 只需将它们全部配置为开发或测试环境,并更新生产零售设置。


1
我有时会忘记在发布之前将编译调试更改为false,这会对性能产生负面影响。现在不再有这个问题了! - Roy Tinker

59

在内容页启用母版页的智能感知功能
我相信这是一项很少人知道的技巧。

大多数情况下,当您想要使用母版页上的控件时,您必须在内容页中使用findcontrol方法并对控件进行强制类型转换,MasterType指令将在您执行此操作后在Visual Studio中启用智能感知。

只需向页面添加一个指令即可。

<%@ MasterType VirtualPath="~/Masters/MyMainMasterPage.master" %>

如果您不想使用虚拟路径,而是使用类名,则

<%@ MasterType TypeName="MyMainMasterPage" %>

在此处获取完整文章


使用FindControl有时可能会很繁琐,感谢这个好建议! - Alexandre Brisebois
4
使用此功能可能会导致意外行为。请参考https://dev59.com/hUvSa4cB1Zd3GeqPbx0_。 - citronas
我个人认为应该将特性留给开发者,因为它会将页面与母版页耦合在一起。如果您最终使用了母版页的属性/方法,然后又更改了母版页,那么您将面临维护方面的噩梦。 - Phill
@Phil:有时候需要静态类型的主页面访问,这比FindControl方法要好得多。至少你可以得到编译器的消息并快速修复它。 - Durden81

58

HttpContext.Items作为请求级别的缓存工具


2
这也是我的观点,我在嵌套控件中使用它来传递/接收请求级别的信息。同时,在MVC中,我使用它来存储js文件列表以进行附加,并基于部分视图进行操作。 - Tracker1
1
我在使用ASP.NET路由时使用它来将从URL中获取的参数传递给我的页面(而不是使用MVC)。它非常适合URL重写并且非常灵活。 - Alexandre Brisebois
哦,我突然想到了一个地方,我可以用这个代替Session - 谢谢! - Mike Kingscott

52

我脑海中有两件事情:

1)你可以在代码中开启或关闭 Trace:

#ifdef DEBUG 
   if (Context.Request.QueryString["DoTrace"] == "true")
                {
                    Trace.IsEnabled = true;
                    Trace.Write("Application:TraceStarted");
                }
#endif

2) 您可以仅使用一个共享的“代码后台”文件来构建多个 .aspx 页面。

构建一个类 .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页面(在删除VS生成的.designer.cs和.cs代码之后):

  <%@ 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中不存在的控件,反之亦然,但是您需要记住检查这些控件是否为null。


我本想点赞的,但是已经没有投票次数了。我会尝试记住回来给这个点赞的。我不知道我们可以为多个页面使用相同的 Code Behind 文件。不确定那该如何运作。 - Vaibhav
5
有人认为从URL激活跟踪功能存在安全风险吗? (#1) 我不会给这个问题投反对票,但是了解那种风险非常重要。 - Kevin Goff
5
当然,你应该把那段代码放在一个#ifdef DEBUG #endif 块中。 - Radu094
很棒的评论,指出了安全方面的问题。 - Vaibhav
2
为什么从URL激活跟踪会存在安全风险?它如何被用来伤害我? - Kamarey

48

你可以使用:

 Request.Params[Control.UniqueId] 

在视图状态初始化之前获取控件的值(此时Control.Text等为空),这对Init中的代码很有用。


视图状态初始化不会处理Request.Params。在调用实现IPostBackDataHandler控件的LoadPostData方法之前使用它。 - chapluck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接