Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you link to an action that takes an array as a parameter (RedirectToAction and/or ActionLink)?

Tags:

I have an action defined like so:

public ActionResult Foo(int[] bar) { ... }

Url's like this will work as expected:

.../Controller/Foo?bar=1&bar=3&bar=5

I have another action that does some work and then redirects to the Foo action above for some computed values of bar.

Is there a simple way of specifying the route values with RedirectToAction or ActionLink so that the url's get generated like the above example?

These don't seem to work:

return RedirectToAction("Foo", new { bar = new[] { 1, 3, 5 } });
return RedirectToAction("Foo", new[] { 1, 3, 5 });

<%= Html.ActionLink("Foo", "Foo", new { bar = new[] { 1, 3, 5 } }) %>
<%= Html.ActionLink("Foo", "Foo", new[] { 1, 3, 5 }) %>

However, for a single item in the array, these do work:

return RedirectToAction("Foo", new { bar = 1 });
<%= Html.ActionLink("Foo", "Foo", new { bar = 1 }) %>

When setting bar to an array, it redirects to the following:

.../Controller/Foo?bar=System.Int32[]

Finally, this is with ASP.NET MVC 2 RC.

Thanks.

like image 990
Andrew Avatar asked Mar 15 '10 22:03

Andrew


People also ask

What is difference between redirect and RedirectToAction?

RedirectToAction is meant for doing 302 redirects within your application and gives you an easier way to work with your route table. Redirect is meant for doing 302 redirects to everything else, specifically external URLs, but you can still redirect within your application, you just have to construct the URLs yourself.

Which is correct syntax for RedirectToAction?

RedirectToAction(String, String, RouteValueDictionary) Redirects to the specified action using the action name, controller name, and route values.

What is the usage of a RedirectToAction?

The RedirectToAction() Method This method is used to redirect to specified action instead of rendering the HTML. In this case, the browser receives the redirect notification and make a new request for the specified action. This acts just like as Response.

Can we pass model in RedirectToAction?

By including a NuGet package called MvcContrib you can easily pass model or form data through a simple RedirectToAction function call inside of your controllers.


2 Answers

There are a few ways to do this. If you want to keep it stateless avoid using TempData and create a action filter.

Somthing like this:

ActionFilter:

public class BindArrayAttribute:ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var keys = filterContext.HttpContext.Request.QueryString.AllKeys.Where(p => p.StartsWith("id"));

        var idArray = new int[keys.Count()];

        var counter = 0;
        foreach (var key in keys)
        {
            var id = filterContext.HttpContext.Request.QueryString[key];
            idArray[counter] = int.Parse(id);
            counter++;
        }

        filterContext.ActionParameters["id"] = idArray;

        base.OnActionExecuting(filterContext);
    }
}

Controller:

 [HttpPost]
    public ActionResult Index(ItemModel model)
    {
        var dic = new RouteValueDictionary();

        var counter = 0;
        foreach (var id in model.SelectedItemIds)
        {
            dic.Add("id" + counter, id);
            counter++;
        }

        return RedirectToAction("Display", dic);
    }

    [HttpGet]
    [BindArray]
    public ActionResult Display(int[] id = null)
    {
        return View(id);
    }
like image 151
Lee Smith Avatar answered Oct 12 '22 22:10

Lee Smith


I'm not sure how to accomplish that using the existing helpers. But you could write your own method to do so.

Here's something I threw together:

    public static string EnumerableActionLink(this HtmlHelper htmlHelper, string linkText, string controllerName, string actionName, IEnumerable enumerable, string variableName)
    {
        var builder = new StringBuilder(string.Format("/{0}/{1}?", controllerName, actionName));

        foreach (var item in enumerable)
            builder.Append(string.Format("{0}={1}&", variableName, item));

        return string.Format("<a href=\"{0}\">{1}</a>", builder, linkText);
    }

Usage example:

<%= Html.EnumerableActionLink("Foo", "Foo", "Foo", new[] { 1, 3, 5 }, "bar")%>
like image 39
reustmd Avatar answered Oct 12 '22 22:10

reustmd