我的Global.asax.cs
文件中有一个函数,如果需要,会对Web.config
文件应用一些更改。该文件保存为:
config.Save(ConfigurationSaveMode.Modified);
我最近发现TempData
无法用于我的应用:它在下一个请求时似乎是空的。我的MCVE:
public ActionResult Foo()
{
TempData["error"] = "testing error passing";
return RedirectToAction("Bar");
}
public ActionResult Bar()
{
throw new Exception(TempData["error"] as string);
}
我已将其添加到我的HomeController
,访问/Home/Foo
会重定向到/Home/Bar
。但是,如果上面的config.Save
行有效,我会得到:
Server Error in '/' Application.
Exception of type 'System.Exception' was thrown.
但如果我注释掉那一行,我会得到:
Server Error in '/' Application.
test error passing
正如我原先期待的那样。
(我有几个实例,我得到了反向结果,但通常是在我评论或取消评论该行后的第一个请求,所以可能是I should blame caching。)
为什么会发生这种情况,我该如何解决?
答案 0 :(得分:3)
基于这个问题:
What happens when I edit web.config?
想象一下,每个ASP.NET应用程序(在IIS中定义)都是一个程序 桌面。保存web.config将执行类似于关闭的操作 该计划并重新开放。 - Dan Goldstein
当运行时对web.config文件应用任何更改时,IIS默认行为会自动重置整个会话状态并回收现有AppDomain
,因此TempData
数组中存储的所有值都将丢失,而是保留空值。
当config.Save
行未注释时,行:
throw new Exception(TempData["error"] as string);
将包含TempData["error"]
的空值:
throw new Exception(null);
如果对象不存在,as
运算符返回null,它会抛出带有空字符串的新Exception
实例,导致显示默认异常消息而不是自定义异常消息。
如果config.Save
行已注释,则配置更改未应用于web.config文件,因此现有AppDomain
仍在运行且TempData
值仍然存在。
可以通过以下步骤更改默认行为:
Disable Recycling for Configuration Changes
(DisallowRotationOnConfigChange
)部分并将其设置为True
。相关问题:How to prevent an ASP.NET application restarting when the web.config is modified?
答案 1 :(得分:1)
TempData将值存储在会话中,并且您的默认会话存储似乎是InProc,它将数据存储在服务器内存中,该内存主要在应用程序池的AppDomain下运行
默认情况下,当虚拟目录下的文件发生任何更改时,IIS会检测到使用文件监视器并回收应用程序池,这将取消分配分配给此Web应用程序的所有内存。
为避免这种情况,您可以将会话模式更改为数据库或状态服务器。
但最好的办法是避免更改web.config
,如果您有任何用户定义的配置或需要在运行时更改,那么您必须将其存储在其他位置并缓存以避免任何表现命中