J'ai une méthode qui retourne un tableau (string []) et j'essaie de passer ce tableau de chaînes dans un lien d'action afin qu'il crée une chaîne de requête similaire à:
/Controller/Action?str=val1&str=val2&str=val3...etc
Mais quand je passe new {str = GetStringArray ()} j'obtiens l'url suivante:
/Controller/Action?str=System.String%5B%5D
Donc, fondamentalement, cela prend ma chaîne [] et exécute .ToString () dessus pour obtenir la valeur.
Des idées? Merci!
Essayez de créer un RouteValueDictionary contenant vos valeurs. Vous devrez donner à chaque entrée une clé différente.
<% 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 ) %>
va vous donner un lien comme
<a href='/Controller/Action?str=val0&str=val1&...'>Link</a>
EDIT: MVC2 a modifié l'interface de ValueProvider pour rendre ma réponse originale obsolète. Vous devez utiliser un modèle avec un tableau de chaînes en tant que propriété.
public class Model
{
public string Str[] { get; set; }
}
Ensuite, le classeur de modèles remplira votre modèle avec les valeurs que vous transmettez dans l'URL.
public ActionResult Action( Model model )
{
var str0 = model.Str[0];
}
Cela m'a vraiment énervé avec l'inspiration de Scott Hanselman j'ai écrit la méthode d'extension suivante (fluide):
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<T>(
this RedirectToRouteResult result,
string key,
IEnumerable<T> 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;
}
Appelle comme ça:
return this.RedirectToAction("Index", "Home")
.WithRouteValue("id", 1)
.WithRouteValue("list", new[] { 1, 2, 3 });
Une autre solution qui m'est venue à l’esprit:
string url = "/Controller/Action?iVal=5&str=" + string.Join("&str=", strArray);
C'est sale et vous devriez le tester avant de l'utiliser, mais cela devrait quand même fonctionner. J'espère que cela t'aides.
Il existe une bibliothèque appelée Unbinder que vous pouvez utiliser pour insérer des objets complexes dans routes/urls.
Cela fonctionne comme ceci:
using Unbound;
Unbinder u = new Unbinder();
string url = Url.RouteUrl("routeName", new RouteValueDictionary(u.Unbind(YourComplexObject)));
Il s'agit d'un tableau de résolution HelperExtension et de problèmes de propriétés IEnumerable:
public static class AjaxHelperExtensions
{
public static MvcHtmlString ActionLinkWithCollectionModel(this AjaxHelper ajaxHelper, string linkText, string actionName, object model, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
{
var rv = new RouteValueDictionary();
foreach (var property in model.GetType().GetProperties())
{
if (typeof(ICollection).IsAssignableFrom(property.PropertyType))
{
var s = ((IEnumerable<object>)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);
}
}