Как вы ссылаетесь на действие, которое принимает массив в качестве параметра (RedirectToAction и / или ActionLink)? - PullRequest
4 голосов
/ 16 марта 2010

У меня есть действие, определенное так:

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

URL-адрес, как это будет работать, как ожидалось:

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

У меня есть другое действие, которое выполняет некоторую работу, а затем перенаправляет на действие Foo выше для некоторых вычисленных значений bar.

Есть ли простой способ указать значения маршрута с помощью RedirectToAction или ActionLink, чтобы URL генерировался, как в примере выше?

Кажется, они не работают:

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 }) %>

Однако для одного элемента в массиве они работают:

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

При установке bar в массив он перенаправляет на следующее:

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

Наконец, это с ASP.NET MVC 2 RC.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 22 ноября 2010

Есть несколько способов сделать это. Если вы хотите сохранить его без сохранения состояния, избегайте использования TempData и создайте фильтр действий.

Что-то вроде этого:

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);
    }
}

Контроллер:

 [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);
    }
1 голос
/ 16 марта 2010
<%= Html.ActionLink("Foo", "Foo", "Foo", 
    new[] { 1, 3, 5 }.Aggregate(string.Empty, (a, x) => a += "bar=" + x + "&"))
%>
1 голос
/ 16 марта 2010

Я не уверен, как это сделать с помощью существующих помощников. Но вы можете написать свой собственный метод для этого.

Вот что-то, что я бросил вместе:

    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);
    }

Пример использования:

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