RedirectToAction from different controller and with parameters/routevalues not working

7.8k Views Asked by At

I’m trying to call a action method from different controller but it´s not working. It simply skips the RedirectToAction

here's my code:

public ActionResult sendPolicy(TempPoliciesUpload TempPolicy)
        {
            return RedirectToAction("Insert", "Policies", new { tempPolicy = TempPolicy });
        }

Please help.

6

There are 6 best solutions below

0
On

If you need to send a complex object you can try just returning the view from another controller like this:

public ActionResult sendPolicy(TempPoliciesUpload TempPolicy) { return View("~Views/Policies/Insert.cshtml", TempPolicy ); }

If you want this view to post back to the correct controller method you will need to specify this in the 'BeginForm' Html Helper:

... @using(Html.BeginForm("Insert", "Policy") { ... }

This really isn't best practice, but it is a workaround that you can use until you fix enough of the rest of your app so that you can use the redirects properly.

0
On

Remove the parameter from the controller you're redirecting to and remove new { tempPolicy = TempPolicy }. See if that works (and then you localized the problem to parameter).

Most likely you need to cast it to the type of the action you redirecting to (hence Mark asked you for that signature) or play with it otherwise, maybe put in quotes (I doubt but good to try)

If even that doesn't work, check your spellings (this is why I do not like magic strings and love T4MVC) - but I doubt that either, naming looks correct.

Another likely possibility is something that solved for others here: RedirectToAction not working

0
On

I hope you have

public ActionResult Insert(TempPoliciesUpload tempPolicy)

action method in PoliciesController class.

Please see the overload of RedirectToAction here

0
On

You cannot send complex objects when redirecting. You will have to include each property as query string parameter. And this works only with simply scalar properties.

public ActionResult sendPolicy(TempPoliciesUpload TempPolicy)
{
    return RedirectToAction("Insert", "Policies", new 
    { 
        id = TempPolicy.Id,
        prop1 = TempPolicy.Prop1,
        prop2 = TempPolicy.Prop2,
        ...
    });
}

If you have complex properties you will have to include them as well so that the default model binder is able to bind the model in the target action from the query string parameters:

public ActionResult sendPolicy(TempPoliciesUpload TempPolicy)
{
    return RedirectToAction("Insert", "Policies", new RouteValueDictionary
    {
        { "id", TempPolicy.Id },
        { "prop1", TempPolicy.Prop1 },
        { "prop2", TempPolicy.Prop2 },
        { "prop3.subprop1", TempPolicy.Prop3.SubProp1 },
        { "prop3.subprop2", TempPolicy.Prop3.SubProp2 },
        ...
    });
}

and your target action:

public ActionResult Insert(TempPoliciesUpload TempPolicy)
{
    ...
}

Another possibility is to persist this object in your backend before redirecting and then pass only the id:

public ActionResult sendPolicy(TempPoliciesUpload TempPolicy)
{
    int id = Repository.Save(TempPolicy);
    return RedirectToAction("Insert", "Policies", new { id = id });
}

and in your target action:

public ActionResult Insert(int id)
{
    TempPoliciesUpload TempPolicy = Repository.Get(id);
    ...
}
0
On

Has anyone tried the first solution with complex objects? I mean this one:

"...and your target action:..."

public ActionResult Insert(TempPoliciesUpload TempPolicy) { ... }

I don't think a RouteValueDictionary will convert or cast into a complex object. (Serialization must be used, I think)

My solution was passing the parameters as a RouteValueDictionary and receiving each parameters individually in the target action.

0
On

For decoupling, @Darin Dimitrov answer would be suited best. However if you do not wish to pass details in the URL, so that for example the user cannot fiddle with the data, you can use the short-lived persistence TempData feature like this:

public ActionResult sendPolicy(TempPoliciesUpload TempPolicy)
{
    TempData["Policy"] = TempPolicy;
    return RedirectToAction("Insert", "Policies");
}

Then retrieve it in the Insert:

public ActionResult Insert()
{
    TempPoliciesUpload TempPolicy = (TempPoliciesUpload)TempData["Policy"];
}