Reputation: 28248
How do I add to the TempData dictionary from a non controller class?
Upvotes: 4
Views: 10571
Reputation: 14503
You do not need the ControllerContext, you only need the current HttpContext.
And you do not need to pass anything, you can create a new SessionStateTempDataProvider and use this, because the only thing the SaveTempData-method of this class is doing is setting a IDictionary on a specific key in the current session.
(If your application is not using any custom ITempDataProvider. If you do, you obviously have to rely on that instead.)
The SessionStateTempDataProvider is a very simple class:
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc.Properties;
namespace System.Web.Mvc
{
public class SessionStateTempDataProvider : ITempDataProvider
{
internal const string TempDataSessionStateKey = "__ControllerTempData";
public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
{
HttpSessionStateBase session = controllerContext.HttpContext.Session;
if (session != null)
{
Dictionary<string, object> tempDataDictionary = session[TempDataSessionStateKey] as Dictionary<string, object>;
if (tempDataDictionary != null)
{
// If we got it from Session, remove it so that no other request gets it
session.Remove(TempDataSessionStateKey);
return tempDataDictionary;
}
}
return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
}
public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
HttpSessionStateBase session = controllerContext.HttpContext.Session;
bool isDirty = (values != null && values.Count > 0);
if (session == null)
{
if (isDirty)
{
throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
}
}
else
{
if (isDirty)
{
session[TempDataSessionStateKey] = values;
}
else
{
// Since the default implementation of Remove() (from SessionStateItemCollection) dirties the
// collection, we shouldn't call it unless we really do need to remove the existing key.
if (session[TempDataSessionStateKey] != null)
{
session.Remove(TempDataSessionStateKey);
}
}
}
}
}
}
Thus we can do:
var httpContext = new HttpContextWrapper(HttpContext.Current);
var newValues = new Dictionary<string, object> {{"myKey", myValue}};
new SessionStateTempDataProvider().SaveTempData(new ControllerContext { HttpContext = httpContext }, newValues);
Note that this is overriding the existing Dictionary every time, so if you want to add data sequentially, you obviously have to rely on an intermediate container or write some extra logic to merge the existing values with the new values.
My case where I need to do this is for error page handling, where I do redirect, but where I need to to have the logic of persisting temporary data outside of the scope of the controller.
Upvotes: 4
Reputation: 81
ControllerBase.TempData Property
System.Web.Mvc.TempDataDictionary
You can use public TempDataDictionary TempData { get; set; }
to use TempData
e.g. Like TempData.Clear(); // Clear TempData in other class
Upvotes: 1
Reputation: 5368
You would have to pass the TempDataDictionary to the other class. I do this quite a bit and there is nothing wrong with it as long the other class is related to presentation (which it sounds like it is).
Upvotes: 4
Reputation: 9108
To do so you'd need the current controller context, otherwise you cannot.
ViewContext.Controller.TempData["whatever"] = whatever
Upvotes: 0