为什么 ASP.NET TempData 在修改 Web.config 时不起作用?
Why doesn't ASP.NET TempData work when modifying Web.config?
如果需要,我的 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。)
为什么会发生这种情况,我该如何解决?
基于这个问题:
What happens when I edit web.config?
Imagine each ASP.NET application (as defined in IIS) is a program on
the desktop. Saving web.config will do something similar to closing
the program and reopening it. - Dan Goldstein
IIS 默认行为会在运行时对 web.config 文件应用任何更改时自动重置整个会话状态并回收现有 AppDomain
,因此存储在 TempData
数组中的所有值都将丢失,留下取而代之的是空值。
当 config.Save
行未注释时,行:
throw new Exception(TempData["error"] as string);
将包含来自 TempData["error"]
:
的空值
throw new Exception(null);
由于 as
operator returns null 如果对象不存在,它会抛出带有空字符串的新 Exception
实例,导致显示默认异常消息而不是自定义异常消息。
如果 config.Save
行被注释,配置更改不会应用到 web.config 文件,因此现有的 AppDomain
仍然是 运行 和 TempData
值是还在原地。
可以通过以下步骤更改默认行为:
- 打开 IIS 管理器。
- Select 应用程序池 => [您的应用程序池名称] => 高级设置。
- 在回收区,找到
Disable Recycling for Configuration Changes
(DisallowRotationOnConfigChange
) 部分并将其设置为 True
。
相关问题:How to prevent an ASP.NET application restarting when the web.config is modified?
TempData 将值存储在会话中,您的默认会话存储似乎是 InProc,它将数据存储在服务器内存中,服务器内存主要 运行ning 在应用程序池的 AppDomain 下
默认情况下,当虚拟目录下的文件发生任何变化时,IIS 会检测到使用文件观察器并回收应用程序池,这将取消分配分配给该 Web 应用程序的所有内存。
为避免这种情况,您可以将会话模式更改为数据库或状态服务器。
但最好完全避免更改 web.config
,如果您有任何用户定义的配置或需要在 运行 时更改,则必须存储它在其他地方缓存以避免任何性能影响
如果需要,我的 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。)
为什么会发生这种情况,我该如何解决?
基于这个问题:
What happens when I edit web.config?
Imagine each ASP.NET application (as defined in IIS) is a program on the desktop. Saving web.config will do something similar to closing the program and reopening it. - Dan Goldstein
IIS 默认行为会在运行时对 web.config 文件应用任何更改时自动重置整个会话状态并回收现有 AppDomain
,因此存储在 TempData
数组中的所有值都将丢失,留下取而代之的是空值。
当 config.Save
行未注释时,行:
throw new Exception(TempData["error"] as string);
将包含来自 TempData["error"]
:
throw new Exception(null);
由于 as
operator returns null 如果对象不存在,它会抛出带有空字符串的新 Exception
实例,导致显示默认异常消息而不是自定义异常消息。
如果 config.Save
行被注释,配置更改不会应用到 web.config 文件,因此现有的 AppDomain
仍然是 运行 和 TempData
值是还在原地。
可以通过以下步骤更改默认行为:
- 打开 IIS 管理器。
- Select 应用程序池 => [您的应用程序池名称] => 高级设置。
- 在回收区,找到
Disable Recycling for Configuration Changes
(DisallowRotationOnConfigChange
) 部分并将其设置为True
。
相关问题:How to prevent an ASP.NET application restarting when the web.config is modified?
TempData 将值存储在会话中,您的默认会话存储似乎是 InProc,它将数据存储在服务器内存中,服务器内存主要 运行ning 在应用程序池的 AppDomain 下
默认情况下,当虚拟目录下的文件发生任何变化时,IIS 会检测到使用文件观察器并回收应用程序池,这将取消分配分配给该 Web 应用程序的所有内存。
为避免这种情况,您可以将会话模式更改为数据库或状态服务器。
但最好完全避免更改 web.config
,如果您有任何用户定义的配置或需要在 运行 时更改,则必须存储它在其他地方缓存以避免任何性能影响