ASP.NET MVC: passa l’object array come valore di route all’interno di Html.ActionLink (…)

Ho un metodo che restituisce un array (string []) e sto provando a passare questa serie di stringhe in un link di azione in modo che crei una stringa di query simile a:

/Controller/Action?str=val1&str=val2&str=val3...etc 

Ma quando passo nuovo {str = GetStringArray ()} ottengo il seguente url:

 /Controller/Action?str=System.String%5B%5D 

Quindi fondamentalmente mi sta prendendo la mia stringa [] e sto usando .ToString () per ottenere il valore.

Qualche idea? Grazie!

Prova a creare un RouteValueDictionary contenente i tuoi valori. Dovrai assegnare a ciascuna voce una chiave diversa.

 <% var rv = new RouteValueDictionary(); var strings = GetStringArray(); for (int i = 0; i < strings.Length; ++i) { rv["str[" + i + "]"] = strings[i]; } %> <%= Html.ActionLink( "Link", "Action", "Controller", rv, null ) %> 

ti darò un link come

 Link 

EDIT : MVC2 ha cambiato l’interfaccia ValueProvider per rendere obsoleta la mia risposta originale. È necessario utilizzare un modello con una serie di stringhe come proprietà.

 public class Model { public string Str[] { get; set; } } 

Quindi il raccoglitore modello popolerà il modello con i valori che si passano nell’URL.

 public ActionResult Action( Model model ) { var str0 = model.Str[0]; } 

Questo mi ha davvero infastidito così, con l’ ispirazione di Scott Hanselman, ho scritto il seguente (fluente) metodo di estensione:

 public static RedirectToRouteResult WithRouteValue( this RedirectToRouteResult result, string key, object value) { if (value == null) throw new ArgumentException("value cannot be null"); result.RouteValues.Add(key, value); return result; } public static RedirectToRouteResult WithRouteValue( this RedirectToRouteResult result, string key, IEnumerable values) { if (result.RouteValues.Keys.Any(k => k.StartsWith(key + "["))) throw new ArgumentException("Key already exists in collection"); if (values == null) throw new ArgumentNullException("values cannot be null"); var valuesList = values.ToList(); for (int i = 0; i < valuesList.Count; i++) { result.RouteValues.Add(String.Format("{0}[{1}]", key, i), valuesList[i]); } return result; } 

Chiama così:

 return this.RedirectToAction("Index", "Home") .WithRouteValue("id", 1) .WithRouteValue("list", new[] { 1, 2, 3 }); 

Un’altra soluzione che mi è venuta in mente:

 string url = "/Controller/Action?iVal=5&str=" + string.Join("&str=", strArray); 

Questo è sporco e dovresti testarlo prima di usarlo, ma dovrebbe comunque funzionare. Spero che questo ti aiuti.

C’è una libreria chiamata Unbinder , che puoi usare per inserire oggetti complessi in route / urls.

Funziona così:

 using Unbound; Unbinder u = new Unbinder(); string url = Url.RouteUrl("routeName", new RouteValueDictionary(u.Unbind(YourComplexObject))); 

Questo è un array di soluzione HelperExtension e problemi con le proprietà IEnumerable:

 public static class AjaxHelperExtensions { public static MvcHtmlString ActionLinkWithCollectionModel(this AjaxHelper ajaxHelper, string linkText, string actionName, object model, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { var rv = new RouteValueDictionary(); foreach (var property in model.GetType().GetProperties()) { if (typeof(ICollection).IsAssignableFrom(property.PropertyType)) { var s = ((IEnumerable)property.GetValue(model)); if (s != null && s.Any()) { var values = s.Select(p => p.ToString()).Where(p => !string.IsNullOrEmpty(p)).ToList(); for (var i = 0; i < values.Count(); i++) rv.Add(string.Concat(property.Name, "[", i, "]"), values[i]); } } else { var value = property.GetGetMethod().Invoke(model, null) == null ? "" : property.GetGetMethod().Invoke(model, null).ToString(); if (!string.IsNullOrEmpty(value)) rv.Add(property.Name, value); } } return System.Web.Mvc.Ajax.AjaxExtensions.ActionLink(ajaxHelper, linkText, actionName, rv, ajaxOptions, htmlAttributes); } } 

Userei il POST per un array. Oltre ad essere brutto e un abuso di GET, rischi di esaurire lo spazio dell’URL (credici o no).

Supponendo un limite di 2000 byte . L’overhead della stringa di query (& str =) riduce a ~ 300 byte di dati effettivi (supponendo che il resto dell’URL sia 0 byte).