Search code examples
c#asp.netasp.net-mvctempdata

Why doesn't ASP.NET TempData work when modifying Web.config?


I have a function in my Global.asax.cs file that applies a couple changes to the Web.config file, if needed. The file is saved with:

config.Save(ConfigurationSaveMode.Modified);

I recently discovered that TempData wasn't working for my app: it appeared to be empty on the next request. My MCVE:

public ActionResult Foo()
{
  TempData["error"] = "testing error passing";
  return RedirectToAction("Bar");
}

public ActionResult Bar()
{
  throw new Exception(TempData["error"] as string);
}

I added that to my HomeController, and visiting /Home/Foo would redirect to /Home/Bar. However, with the above config.Save line active, I get:

Server Error in '/' Application.
Exception of type 'System.Exception' was thrown.

But if I comment out that line, I get:

Server Error in '/' Application.
test error passing

as I was expecting originally.

(I had a couple instances where I got the inverse result, but it was usually on the first request after I commented or un-commented the line, so probably I should blame caching.)

Why does this happen, and how can I fix it?


Solution

  • Based from this question:

    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 default behavior automatically reset entire session state and recycles existing AppDomain when any changes applied to web.config file at runtime, thus all values stored on TempData array are lost, leaving null values instead.

    When config.Save line left uncommented, the line:

    throw new Exception(TempData["error"] as string);
    

    will contain null value from TempData["error"]:

    throw new Exception(null);
    

    Since as operator returns null if the object doesn't exist, it throws new Exception instance with null string, causing default exception message to show instead of custom one.

    If config.Save line commented, the configuration changes doesn't applied into web.config file, thus existing AppDomain remains running and TempData values are still in place.

    The default behavior can be changed by these steps:

    1. Open IIS Manager.
    2. Select Application Pools => [your application pool name] => Advanced Settings.
    3. On Recycling area, find Disable Recycling for Configuration Changes (DisallowRotationOnConfigChange) section and set it to True.

    Related problem: How to prevent an ASP.NET application restarting when the web.config is modified?