The short version of all this is that I'm using TempData to store feedback messages and after switching to using CookieTempDataProvider they don't show up when using the a PRG pattern, but if I revert back to SessionTempDataProvider they do.
In my MVC4 application I have a pattern of writing an alert message to the temp data for displaying on the screen after a successful Create/Update or when something goes wrong on certain pages and I need to show a failure message. For example...
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Edit(PeopleEditFormModel model)
{
if (!ModelState.IsValid)
return RedirectToAction("Edit", new { id = model.ObjectId });
try
{
var person = personService.UpdatePerson(model); // personService is set via DI in constructor
TempData["message"] = "Person successfully updated.";
TempData["messageType"] = "success"
return RedirectToAction("Details", new { id = person.ObjectId });
}
catch (DomainException ex)
{
//For putting business logic errors in the ModelState
ModelState.AddModelError(string.Empty, ex.Message);
return RedirectToAction("Edit", new {id = model.ObjectId});
}
}
I have a partial view called by my _Layout.cshtml file that is basically a placeholder DIV element (plus some js) that gets filled with my feedback message, and this works fine.
Now this works by default but TempData relies on the session and I'd like to disable it if possible and use a different implementation of the TempDataProvider to get around not having a session. I have to use a different TempDataProvier because if I disable the session without changing the imlementation of TempData, the first time I try to use it I'll get an InvalidOperationException stating
The SessionStateTempDataProvider class requires session state to be enabled.
<system.web>
<sessionState mode="Off"/>
</system.web>
I've registered a new component with my Dependency Injector, StructureMap, and it looks like this.
//I have tried this with and without the HttpContextScoped()
For<ITempDataProvider>().HttpContextScoped().Use<CookieTempDataProvider>();
For<HttpContextBase>().HttpContextScoped().Use(x => new HttpContextWrapper(HttpContext.Current));
I should mention my implementation of the CookieTempDataProvider is from here
Apparently it's been removed.
Now, This solves the exception when I try to use TempData now but my feedback doesn't show up. I thought maybe I broke something in my efforts so I commented out my DI lines and changed my session state mode back to InProc
, and tested it. My feedback shows up as expected (after restarting IISExpress). I uncomment my injection lines, change session state to Off
, and I'm back to no feedback.
I did some further testing and found that if I do the following in my action I get no message
TempData["message"] = "Person successfully updated.";
TempData["messageType"] = "success"
return RedirectToAction("Details", new { id = person.ObjectId });
But if I ignore the PRG pattern, and instead do this then I see my feedback.
TempData["message"] = "Person successfully updated.";
TempData["messageType"] = "success"
return View("Edit", person);
So my question is, is there a flaw with the commonly accepted CookieTempDataProvider or am I doing something wrong?