ASP.NET Core TempData and Error 400 The size of the request headers is too long

If you develop with ASP.NET Core 2.0 or later and you are using TempData, you may run into a 400 error saying your request headers is too long.  I've recently encountered this while writing a blog post, it happens when I try to preview the post.  Instead of seeing the preview of my content, I see this error :(

Bad Request - Request Too Long

HTTP Error 400. The size of the request headers is too long.

Bad Request - Request Too Long
Bad Request - Request Too Long

The error message itself and the fact that this error happens only on this post does not make sense to me. After googling it, it becomes clear that the cause of this particular error is that you have too many cookies!  Here is a good StackOverflow question on this issue.

To investigate I open up the Chrome devtool and see a list of 5 cookies associated with TempData, from .AspNetCore.Mvc.CookieTempDataProvider to .AspNetCore.Mvc.CookieTempDataProviderC4.  The first cookie has a value of "chunks-4" suggesting there are 4 other cookies, and almost all of these 4 cookies have a size of 4016 bytes which is the max cookie size allowed in Chrome browser.  Furthermore I've learned that to fix this issue you can simply delete these cookies.  However deleting the cookies does not really solve my problem, as soon as I hit the preview button again the error and cookies come back.

TempData Cookies
ASP.NET Core TempData Cookies

Digging deeper into the Compose page where I initiate the preview, I see that I am using TempData to transfer a blog post from the Compose page to the Preview page.  This reminds me of a fact I read about TempData when I first implemented this feature.  In the previous versions of ASP.NET and prior to ASP.NET Core 2.0, the TempData was implemented with session, but starting with ASP.NET Core 2.0 TempData by default is implemented with a cookie provider. Hence when I preview a post ASP.NET serializes my post content via cookies.  As my post gets long the sheer size of my content exceeds the max headers limit.  

The simplest way to fix this issue is to configure TempData using the session provider instead.  For scalability reasons I'm not normally a fan of session, I prefer and have been using IDistributedCache, but here I'm making an exception for just this one feature.  Once the object stored in the TempData is accessed it is removed from TempData, so it should not affect the performance.

ASP.NET does have two other similar mechanisms that could be used to pass data from controller to view, the ViewData and ViewBag.  But these two are used to carry data to the same view which would not work in my situation, because the preview happens on a different page.

Once I figured out why, the fix is very simple.  Open Startup.cs and add 3 lines of code to turn the session provider on and the preview issue is solved.