将数组传递给Html.ActionLink()

时间:2013-08-27 14:39:55

标签: c# asp.net-mvc razor

我按照这个例子:

ASP.NET MVC - Pass array object as a route value within Html.ActionLink(...)

但是,我总是使用null调用我的Action。我做错了什么?

foreach (OrderDetail od in order.OrderDetails)
{
   rvd.Add("key" + count++, productID);
   rvd.Add("key" + count++, productName);
}

@Html.ActionLink(linkText, "Renew", "Orders", rvd, new Dictionary<string, object>())

正确生成了查询字符串,如?key0=dog&key1=cat&key2=fish...,但我在下面的操作中得到一个空参数:

public ActionResult Renew(RouteValueDictionary rvd)
{
   // 'rvd' is null here!
}

请注意:我事先不知道参数的数量。

2 个答案:

答案 0 :(得分:4)

  

正确生成查询字符串,例如?key0 = dog&amp; key1 = cat&amp; key2 = fish ...

不,这不是一个正确的网址。一个正确的网址看起来像这样:

?%5B0%5D.Key=123&%5B0%5D.Value=dog&%5B1%5D.Key=456&%5B1%5D.Value=cat...

将映射到:

public ActionResult Renew(Dictionary<int, string> rvd)
{
    ...
}

您可以编写自定义ActionLink来生成此网址:

public static class LinkExtensions
{
    public static IHtmlString MyActionLink(
        this HtmlHelper html,
        string linkText,
        string actionName,
        string controllerName,
        IDictionary<string, string> parameters
    )
    {
        var a = new TagBuilder("a");
        var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
        var query = string.Join("&", parameters.Select((x, i) => string.Format("[{0}].Key={1}&[{0}].Value={2}", i, urlHelper.Encode(x.Key), urlHelper.Encode(x.Value))));
        var url = string.Format(
            "{0}?{1}",
            urlHelper.Action(actionName, controllerName, null, html.ViewContext.HttpContext.Request.Url.Scheme),
            query
        );
        a.Attributes["href"] = url;
        a.SetInnerText(linkText);
        return new HtmlString(a.ToString());
    }
}

你可以在你的视图中使用这个:

@Html.MyActionLink(
    linkText, 
    "Renew", 
    "Orders", 
    order.OrderDetails.ToDictionary(x => x.ProductID.ToString(), x => x.ProductName)
)

您可以在this blog post中阅读有关绑定到各种集合的正确有线格式的更多信息。

答案 1 :(得分:1)

我想要发生的事情是你期望模型绑定器将你的数组绑定到RouteValueDictionary,但是模型绑定器不知道key0 = dog&amp; key1 = cat&amp; key2 = fish应该是一个字典。我建议您更改代码以接受字符串数组。为此,您的查询字符串需要如下所示:?rvd=dog&rvd=cat&rvd=fish

你的行动......

public ActionResult Renew(string[] rvd)
{
   // 'rvd' is no longer null here!
}

重要的部分是rvd是您的操作中的参数名称,以及查询字符串中每个元素的名称:?rvd = dog&amp; rvd = cat&amp; { {1}} =鱼。如果你真的想使用字典而不是字符串数组,那么你的查询字符串应如下所示: rvd,给每个项目一个数组索引,但你可能不得不将你的参数从RouteValueDictionary更改为?rvd[0]=dog&rvd[1]=cat&rvd[2]=fish,我不太确定More info here编辑:请参阅Darin关于绑定字典的评论,因为我认为他是正确的。

您可能必须为接受数组(或任何Dictionary<string,string>)的Html.ActionLink编写自己的扩展,并将查询字符串创建为数组。 This看起来是一个非常好的起点。