ASP.Net MVC RouteDataと配列 質問する

ASP.Net MVC RouteDataと配列 質問する

次のようなアクションがあるとします。

public ActionResult DoStuff(List<string> stuff)
{
   ...
   ViewData["stuff"] = stuff;
   ...
   return View();
}

次の URL でヒットできます:

http://mymvcapp.com/controller/DoStuff?stuff=hello&stuff=world&stuff=foo&stuff=bar

しかし、私の ViewPage には次のコードがあります:

<%= Html.ActionLink("click here", "DoMoreStuff", "MoreStuffController", new { stuff = ViewData["stuff"] }, null) %>

残念ながら、MVC は、アクションが配列を受け取り、リストを展開して適切な URL ルートを形成することを認識できるほど賢くありません。代わりに、リストの場合はデータ型をリストするだけのオブジェクトに対して .ToString() を実行します。

宛先アクションのパラメータの 1 つが配列またはリストである場合に、Html.ActionLink で適切な URL を生成する方法はありますか?

- 編集 -

Josh が以下で指摘したように、ViewData["stuff"] は単なるオブジェクトです。問題を単純化しようとしましたが、関係のないバグが発生しました。実際には専用の ViewPage<T> を使用しており、密結合された型認識モデルがあります。ActionLink は実際には次のようになります。

<%= Html.ActionLink("click here", "DoMoreStuff", "MoreStuffController", new { stuff = ViewData.Model.Stuff }, null) %>

ViewData.Model.Stuffがリストとして入力されている場合

ベストアンサー1

カスタム HtmlHelper が適切だと考えています。

 public static string ActionLinkWithList( this HtmlHelper helper, string text, string action, string controller, object routeData, object htmlAttributes )
 {
     var urlHelper = new UrlHelper( helper.ViewContext.RequestContext );


     string href = urlHelper.Action( action, controller );

     if (routeData != null)
     {
         RouteValueDictionary rv = new RouteValueDictionary( routeData );
         List<string> urlParameters = new List<string>();
         foreach (var key in rv.Keys)
         {
             object value = rv[key];
             if (value is IEnumerable && !(value is string))
             {
                 int i = 0;
                 foreach (object val in (IEnumerable)value)
                 {
                     urlParameters.Add( string.Format( "{0}[{2}]={1}", key, val, i ));
                     ++i;
                 }
             }
             else if (value != null)
             {
                 urlParameters.Add( string.Format( "{0}={1}", key, value ) );
             }
         }
         string paramString = string.Join( "&", urlParameters.ToArray() ); // ToArray not needed in 4.0
         if (!string.IsNullOrEmpty( paramString ))
         {
            href += "?" + paramString;
         }
     }

     TagBuilder builder = new TagBuilder( "a" );
     builder.Attributes.Add("href",href);
     builder.MergeAttributes( new RouteValueDictionary( htmlAttributes ) );
     builder.SetInnerText( text );
     return builder.ToString( TagRenderMode.Normal );
}

おすすめ記事