0

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?

2
  • 6
    Because when IIS detects changes to the config file, it recycles the application pool, which wipes all session data. I can't think of any good reason why you'd want to change your web.config dynamically at runtime though - so I would look at addressing that. Commented Sep 30, 2016 at 20:37
  • @AntP Okay, makes sense. Yeah, it's definitely more of a hack. Can you post that as an answer? Commented Sep 30, 2016 at 20:38

2 Answers 2

3

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?

Sign up to request clarification or add additional context in comments.

Comments

1

TempData stores the values in session and it seems your default session store is InProc which stores the data in server memory which is mainly running under the AppDomain for the Application Pool

By Default, when there is any change in the files under virtual directory, IIS detects that using a File Watcher and recycle the application pool, this will de-allocate all the memory assigned to this web application.

To avoid that, you can change session mode to be either Database or State Server.

But the best thing is to avoid changing the web.config at all, if you have any configuration that is user defined or need to be changed at run time, then you have to store it somewhere else and cache to avoid any performance hits

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.