Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect to an action with parameters from other action without passing parameters?

Below, in CreateTest, uponsuccessful, I want to redirect to Tests from CreateTest.

I want to do something like the following:

    public ActionResult Tests(int ID, string projectName)
    {
        TestModel model = new TestModel (ID, projectName);
        return View(model);
    }

 [HttpPost]
    public ActionResult CreateTest(TestModel model)
    {
        try
        {
            return RedirectToAction("Tests");
        }
        catch (Exception e)
        {
            ModelState.AddModelError("Error", e.Message);
            return View(model);
        }
    }
like image 502
learning Avatar asked Feb 24 '11 08:02

learning


2 Answers

You might need to provide the arguments when redirecting:

return RedirectToAction("Tests", new { 
   ID = model.ID, 
   projectName = model.ProjectName 
});

and the url you will be redirecting to will now look something like this:

/Foo/Tests?ID=123&projectName=abc

like image 171
Darin Dimitrov Avatar answered Sep 29 '22 11:09

Darin Dimitrov


I know this is a bit old but...

What I've done in the past is have a "MessageArea" class exposed as a property on my base controller that all my controllers ultimately inherit from. The property actually stores the class instance in TempData. The MessageArea has a method to Add() which takes a string message and an enum Type (e.g. Success, Error, Warning, Information).

I then have a partial that renders whatever messages are in MessageArea with appropriate styling according to the type of the message.

I have a HTMLHelper extension method RenderMessageArea() so in any view I can simple say @Html.RenderMessageArea(), the method and partial take care of nulls and nothing is output if there are no messages.

Because data stored in TempData only survives 1 request it is ideal for cases where you want your action to redirect but have 1 or more messages shown on the destination page, e.g. an error, not authorised page etc... Or if you add an item but then return to the index list page.

Obviously you could implement something similar to pass other data. Ultimately I'd say this is a better solution to the original question than the accepted answer.

EDIT, EXAMPLE:

public class MessageAreaModel {
   public MessageAreaModel() {
       Messages = new List<Message>();
   }

   public List<Message> Messages { get; private set; }

   public static void AddMessage(string text, MessageIcon icon, TempDatadictionary tempData) {
       AddMessage(new Message(icon, text), tempData);
   }

   public static void AddMessage(Message message, TempDataDictionary tempData) {
       var msgArea = GetAreaModelOrNew(tempData);
       msgArea.Messages.Add(message);
       tempData[TempDataKey] = msgArea;
   }

   private static MessageAreaModel GetAreaModelOrNew(TempDataDictionary tempData) {
       return tempData[TempDataKey] as MessageAreaModel ?? new MessageAreaModel();
   }

The above class can then be used to add messages from your UI layer used by the controllers.

Then add an HtmlHelper extension like so:

public static void RenderMessageArea(this HtmlHelper html) {
    html.RenderPartial("MessageArea", 
        (MessageAreaModel)html.ViewContext.TempData[MessageAreaModel.TempDataKey] ?? MessageAreaModel.Empty);
    html.ViewContext.TempData.Remove(MessageAreaModel.TempDataKey);
}

The above is not fully completed code there are various bells and whistles I've left out but you get the impression.

like image 34
Peter Avatar answered Sep 29 '22 12:09

Peter