Mike Bruno
Mike Bruno

Reputation: 634

Problem adding string value to ViewBag from an MVC Action using TempData

I've inherited an MVC project where the page should display a message indicating success if an invoked Action completes properly. I'm having some trouble as I am very new to MVC and web development in general.

In the cshtml file, we have the following in MainWindow.cshtml, which only renders the table in the conditional if a string named "SavedMessage" exists in the ViewBag and is not null or empty:

@{ string actionResult = ViewBag.SavedMessage; }
@if (!string.IsNullOrEmpty(actionResult))
{
    <tr>
         <td>
             @actionResult
         </td>
    </tr>
}

In the Action method, I'm attempting to use the TempData object to transfer the string value to the Action which generates the view:

public partial class ApproveController : Controller
{
    const string IDX_ACTIONRESULT = @"ActionResult";

    public ActionResult MyAction(FormCollection collection)
     {
         try
         {
             string result_success = @"Action completed successfully";
             //Do stuff
             TempData[IDX_ACTIONRESULT] = result_success;
             return RedirectToAction("MainWindow");
         }
         catch (Exception e)
         {
             Logger.reportException(e);
             throw e;
         }
     }
 }

In the Action which generates the page, we load the value stored in TempData into a variable, and then test to see if the variable contains anything (note: this same Action is used to render the page whether the user just landed here, or they have clicked the button to execute MyAction). If the variable is not null, we load whatever it contains into the ViewBag.

Create View Action:

public partial class ApproveController : Controller
{
    public ActionResult MainWindow()
    {
        //Do Stuff
        var actionResult = TempData[IDX_ACTIONRESULT];
        if (actionResult != null)
        {
            Log.info("Action Result Message: " + actionResult);
            ViewBag.SavedMessage = actionResult;  
        }
        else
            Log.info("Action Result Message is NULL");


        return View();
    }
}

Possible lead: When the MainWindow() method is called through a means other than Redirect from MyAction(), my log indicates that actionResult is null, however, when it is called via Redirection from MyAction(), actionResult is an empty string. This leads me to believe that MyAction() is populating TempData with something but I can't see why it doesn't contain the string I'm assigning. Anyone see a smoking gun here?

Upvotes: 2

Views: 2667

Answers (3)

Win
Win

Reputation: 62260

return RedirectToAction("CreateViewAction", new { @SavedMessage = savedMessage });

Above code will direct the user to CreateViewAction page with message in Query String. The problem is user can see the message in URL which is kind of ugly.

enter image description here

The easiest way to pass data between pages in ASP.NET MVC is to use TempData.

public ActionResult MyAction(FormCollection collection)
{
    TempData["SuccessMessage"] = @"Action completed successfully";
    //Do stuff
    return RedirectToAction("CreateViewAction");
}

public ActionResult CreateViewAction()
{
    ViewBag.SavedMessage = TempData["SuccessMessage"] ?? "Successfully!!!";
    return View();
}

Upvotes: 2

JuanR
JuanR

Reputation: 7783

The RedirectToAction overload being used here is:

protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);

The previous developer is using an anonymous type to create the route values:

new { @SavedMessage = savedMessage }

The code is redirecting to an Action called MyView that takes a parameter called SavedMessage.

There must be another method in your controller that looks more or less like this:

public ActionResult MyView(string SavedMessage)
{
    //Maybe some code here
    ViewBag.SavedMessage = SavedMessage;
    return View();
}

That method will actually set the message and execute the view.

UPDATE:

After reading the additional information provided, you should be using string.IsNullOrWhiteSpace instead:

@if (!string.IsNullOrWhiteSpace(savedMessage))

Everything else should work fine as laid out which means that either you have some other piece of code redirecting somewhere else before this part executes:

ViewBag.SavedMessage = SavedMessage;
return View();

Or the view you are inspecting is not the view that is being used to present the results. Note that because you are redirecting execution, the new view file used will be CreateViewAction.cshtml.

Upvotes: 1

Earpwald
Earpwald

Reputation: 33

The RedirectToAction method is calling another method in the controller and passing in an object which is the route values for that method.

The new {...} creates an anonymous object, so it doesn't need to have a set type defined.

My guess here, is that there is another method in that controller which recreates the view and should be assigning the parameter recieved to the ViewBag

Upvotes: 0

Related Questions