Access TempData in ExecuteResult Asp.Net MVC Core

2.9k views Asked by At

I wanted to save notification in TempData and shown to user. I create extension methods for this and implement a class which Extends from ActionResult. I need to access TempData in override ExecuteResult method with ActionContext.

Extension Method:

 public static IActionResult WithSuccess(this ActionResult result, string message)
 {
    return new AlertDecoratorResult(result, "alert-success", message);
 }

Extends ActionResult class.

public class AlertDecoratorResult : ActionResult
{
        public ActionResult InnerResult { get; set; }
        public string AlertClass { get; set; }
        public string Message { get; set; }
    public AlertDecoratorResult(ActionResult innerResult, string alertClass, string message)
    {
        InnerResult = innerResult;
        AlertClass = alertClass;
        Message = message;
    }

     public override void ExecuteResult(ActionContext context)
    {
        ITempDataDictionary tempData = context.HttpContext.RequestServices.GetService(typeof(ITempDataDictionary)) as ITempDataDictionary;

        var alerts = tempData.GetAlert();
        alerts.Add(new Alert(AlertClass, Message));
        InnerResult.ExecuteResult(context);
    }
}

Call extension method from controller

return RedirectToAction("Index").WithSuccess("Category Created!");

I get 'TempData ' null , How can I access 'TempData' in 'ExecuteResult' method.

enter image description here

2

There are 2 answers

0
Ahmar On BEST ANSWER

I find out the way to get the TempData. It need to get from ITempDataDictionaryFactory

 var factory = context.HttpContext.RequestServices.GetService(typeof(ITempDataDictionaryFactory)) as ITempDataDictionaryFactory;
 var tempData = factory.GetTempData(context.HttpContext);
5
Dan Pettersson On

I was literally trying to do the exact same thing today (have we seen the same Pluralsight course? ;-) ) and your question led me to find how to access the TempData (thanks!).

When debugging I found that my override on ExecuteResult was never called, which led me to try the new async version instead. And that worked!

What you need to do is override ExecuteResultAsync instead:

public override async Task ExecuteResultAsync(ActionContext context)
{
    ITempDataDictionaryFactory factory = context.HttpContext.RequestServices.GetService(typeof(ITempDataDictionaryFactory)) as ITempDataDictionaryFactory;
    ITempDataDictionary tempData = factory.GetTempData(context.HttpContext);

    var alerts = tempData.GetAlert();
    alerts.Add(new Alert(AlertClass, Message));

    await InnerResult.ExecuteResultAsync(context);
}

However, I have not fully understood why the async method is called as the controller is not async... Need to do some reading on that...