8

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

Ahmar
  • 3,717
  • 2
  • 24
  • 42

2 Answers2

10

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...

Dan Pettersson
  • 713
  • 5
  • 17
  • 1
    Yes we watch same course. My ExecuteResult called but it did not persist the Alerts in TempData. I tried with async method as well but problem still same. Alerts did not persist and not shown in view. Did you able to do this ? – Ahmar Dec 30 '16 at 17:55
  • (Sorry about the delay, new year came in between :-) Yes, it's working for me, I can access the TempData.GetAlerts in my view and get data back from there... Not sure what could be different :-/ I had to enable session which involved adding the nuget packages "Microsoft.AspNetCore.Session" and "Microsoft.Extensions.Caching.Memory" and then add "services.AddMemoryCache(); services.AddSession();" in ConfigureServices method in Startup.cs. And "app.UseSession();" in the Configure method. – Dan Pettersson Jan 03 '17 at 11:43
  • I'm doing the same, but when accessing TempData in a view, it is always empty? – Cocowalla Feb 13 '17 at 11:47
  • Anyone ever figure this one out? Same problem, TempData is always empty. – Jake Shakesworth Oct 28 '17 at 00:07
  • 6
    I think you guys are watching my course! :) I just published a new blog showing the basics of using the alert message technique with ASP.NET Core: http://www.trycatchfail.com/2018/01/22/easily-add-bootstrap-alerts-to-your-viewresults-with-asp-net-core/ I hope that helps! – Matt Honeycutt Jan 22 '18 at 21:54
3

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);
Ahmar
  • 3,717
  • 2
  • 24
  • 42