Creating Your Own "TempBag" in ASP.NET MVC
Some time back during one of my training programs I was asked this question
by a beginner in ASP.NET MVC - "Can we have TempBag wrapper for TempData just as
we have ViewBag for ViewData?"
Whether such a wrapper is needed or not is a different question but if you
wish you can create one using dynamic objects of C# language. Here I am going to
show a quick way to wrap TempData into our own TempBag and then using it in the
controller and view.
The main class that does the trick is this:
public class MyTempBag : DynamicObject
{
TempDataDictionary tempData = null;
public MyTempBag(TempDataDictionary tempdata)
{
this.tempData = tempdata;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
try
{
if (tempData.Keys.Where(k => k == binder.Name).Count() > 0)
{
result = tempData[binder.Name];
return true;
}
else
{
result = "Invalid TempBag Property";
return false;
}
}
catch
{
result = "Invalid TempBag Property";
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
try
{
tempData[binder.Name] = value;
return true;
}
catch
{
return false;
}
}
}
The System.Dynamic namespaces provides DynamicObject class that can be used
to create your own custom dynamic object. In order to create your own dynamic
object using DynamicObject class you need to inherit it from DynamicObject and
override three methods, viz. TryGetMember, TrySetMember and TryInvokeMember. The
first two methods allow you to get and set dynamic properties whereas the last
method allows you to invoke method calls on the dynamic object. In our specific
case we don't need to implement TryInvokeMember because all we need is an
ability to set and get properties.
The MyTempBag inherits from DynamicObject base class and accepts
TempDataDictionary as its constructor parameter. The TrySetMember() method sets
a TempData property value by using tempData variable. On the same lines,
TryGetMember() method retrieves a TempData property value using the tempData
variable.
Once you create MyTempBag class you can use it in the controller as follows:
public class HomeController : Controller
{
dynamic TempBag = null;
public HomeController()
{
TempBag = new MyTempBag(TempData);
}
public ActionResult Index()
{
TempBag.Message = "This is a test message";
return View();
}
}
The above code declares a dynamic variable - TempBag - inside the
HomeController class. In the constructor of the HomeController this variable is
set to a new instance of MyTempBag. Notice that TempData property of the
controller is passed to the constructor of MyTempBag class. Once created the
TempBag can be used as shown in the Index() action method.
In order to read the TempBag property inside a view you would write:
@{
Layout = null;
dynamic TempBag = new MyTempBag(TempData);
}
...
<html>
...
<body>
<h3>@TempBag.Message</h3>
</body>
</html>
The view also creates an instance of MyTempBag and then reads the TempData
property using TempBag object.