Tuesday, September 25, 2012

How to use Asp.Net MVC TempData Properly ?

What is TempData ?

1. TempData is meant to be a very short-lived instance, and you should only use it
    during the current and the subsequent requests only.

2. Since TempData works this way, you need to know for sure what the next request will be, and
    redirecting to another view is the only time you can guarantee this.

3. Therefore, the only scenario where using TempData will reliably work is when
    you are redirecting.This is because a redirect kills the current request , then creates a
    new request on the server to serve the redirected view.

4. Simply said, Asp.Net MVC TempData dictionary is used to share data between
    controller actions.

5. The value of TempData persists until it is read or until the current user’s session times out.

6. By default, the TempData saves its content to the session state.

7. TempData values are marked for deletion when you read them. At the end of the request,
    any marked values are deleted.

8. The benefit is that if you have a chain of multiple redirections it won’t cause TempData to
     be emptied the values will still be there until you actually use them, then they clear up after
     themselves automatically.

How to use TempData ?

Best Way
There are 2 ways which we can use TempData.

Method 1 :

   We can use it Inside the Redirect Action method like below.

Model

MVC
public class CreditCardInfo
{
    public string CardNumber { get; set; }
    public string Span { get; set; }
    public int ExpiryMonth { get; set; }
 }


Action Methods

    TempData Declared Action Method

        [HttpPost]
        public ActionResult CreateOwnerCreditCardPayments(CreditCard cc, FormCollection frm)
        {
           var providerKey = frm["providerKey"];
           var creditCardInfo = new CreditCardInfo();
            creditCardInfo.CardNumber = cc.Number;
            creditCardInfo.ExpiryMonth = cc.ExpMonth;
            creditCardInfo.Span = cc.Span;

            //persist data for next request
            TempData["CreditCardInfo"] = creditCardInfo;

            return RedirectToAction("CreditCardPayment", new { providerKey = providerKey});
        }

       TempData Used Action Method

        [HttpGet]
        public ActionResult CreditCardPayment(string providerKey)
        {
            if (TempData["CreditCardInfo"] != null)
            {
               var creditCardInfo = TempData["CreditCardInfo"] as CreditCardInfo;
         
            var payPros =(PayPros)PaymentGateway.GetPayment(Enums.PayPros);
            var creditCardResponse = payPros.Ecommerce(creditCardInfo);
            return View();
           }
          else
           {
                return View("error");
           }
        }

Method 2 :

   You can use TempData Inside a Redirected Action Method's View.
    In our example it is :

    CreditCardPayment.cshtml  - View.

@{
      if (TempData["CreditCardInfo"] != null)
         {
           var creditCardInfo = TempData["CreditCardInfo"] as CreditCardInfo;
          }
    }

Good Practice :  Always do null check and do necessary action if TempData is null 
                           (either get data again or exit gracefully).

Bad Way of using TempData

  When using with ViewResult Action method.

     [HttpPost]
    public ActionResult CreateOwnerCreditCardPayments(CreditCard cc, FormCollection frm)
        {
           var providerKey = frm["providerKey"];
           var creditCardInfo = new CreditCardInfo();
            creditCardInfo.CardNumber = cc.Number;
            creditCardInfo.ExpiryMonth = cc.ExpMonth;
            creditCardInfo.Span = cc.Span;

            //persist data
            TempData["CreditCardInfo"] = creditCardInfo;

            return View();
        }

View 
  Related View :

CreateOwnerCreditCardPayments.cshtml - View

@{
      if (TempData["CreditCardInfo"] != null)
         {
           var creditCardInfo = TempData["CreditCardInfo"] as CreditCardInfo;
          }
    }

Why this Method is Bad ?

If your controller action returns a ViewResult, and you are tempted to put data into TempData,
Don’t do That.Use ViewData/ViewBag, instead, in this case.
TempData is meant to be a very short-lived instance, and you should only use it during the current and the subsequent requests only. Since TempData works this way, you need to know for sure what the next request will be, and Redirecting to another View is the only time you can guarantee this.Therefore, the only scenario where using TempData will Reliably work is when you are Redirecting.So Keep in Mind.

Other Usage of TempData

Usage 1 : If you want to keep TempData values even after reading them call Keep().Then those
                 values will keep for next request also.

                TempData.Keep("CreditCardInfo");

Usage 2 : If you want to remove TempData values then call Remove().Then those values
                will remove from current and next request.

               TempData.Remove("CreditCardInfo");

Conclusion

 TempData, is geared specifically for working with data on HTTP redirects, so remember to be
 cautious when using TempData. Always do null check before use TempData.
 If you set the Session State Mode to Out of Process , then the data (model) you put in it must be
 Serializable. (Use   [Serializable] attribute)

       What is the meaning of 'Session State Mode to Out of Process' ?
       Such as State Server mode, which stores session state in a separate process called the
       ASP.NET state service. This ensures that session state is preserved if the Web
       application is restarted and also  makes session state available to multiple Web servers in a
       Web farm or Windows Azure (Cloud) environment.


I hope this helps to You.Comments and feedback greatly appreciated.


Happy Coding.

May Be Use Full To You :
How to Use Git with Visual Studio 2010 ? - PART 1
How to Improve Performance of Entity Framework Query (over 400 times)?
How to Convert Linq Entity Query into T-SQL ?
How to Disable a Button Using Jquery and CSS ?
How to Enable jQuery Intellisense in VS 2010 ?

10 comments:

  1. Like Viewdata,it is also a dictionary type property.It is used to store data at the time of redirection.Its like ASP.Net Session object but of short life span. While redirecting from one controller to another, both ViewBag and ViewData properties cannot be used. Here we can use Tempdata since it works for subsequent requests.
    Lets Explain you by giving small Example
    public class ProductController : Controller
    {
    [HttpPost]

    public ActionResult Save(FormCollection formValues)
    {

    ProductModel productModel = new ProductModel();

    TempData["UpdatePoduct"] = productModel; // set value in Tempdata

    return RedirectToAction("SaveSuccess");
    }


    [HttpGet]
    public ActionResult SaveSuccess()
    {
    ProductModel productModel = TempData["UpdatePoduct"] as productModel; // retrieve data from TempData.
    return View(productModel);
    }
    }
    I am sure that this code will help you lot

    -Romil Gandhi -

    ReplyDelete
    Replies
    1. you explained it very well .Thanks for sharing!..

      Delete
    2. Hi,

      Your welcome.
      Do keep in touch.

      Delete
    3. This comment has been removed by the author.

      Delete
  2. I was using TempData "correctly" (ex 1). It started acting weird on one qa server. It would always come back null. After many attempts to correct it, this SOF article came up.

    http://stackoverflow.com/questions/218057/httpcontext-current-session-is-null-when-routing-requests

    I put the setting(s) in:


    ...

    ...



    ...




    And now no environment has an issue.

    Go figure.

    ReplyDelete
  3. Nice explanation.Keep it up!

    ReplyDelete

Thanks for your Feedback.