Actions du contrôleur ASP.NET MVC avec conversion de paramètre personnalisé?

Je souhaite configurer un itinéraire ASP.NET MVC ressemblant à:

routes.MapRoute( "Default", // Route name "{controller}/{action}/{idl}", // URL with parameters new { controller = "Home", action = "Index", idl = UrlParameter.Optional } // Parameter defaults ); 

Cela route les demandes qui ressemblent à ceci …

 Example/GetItems/1,2,3 

… à l’action de mon contrôleur:

 public class ExampleController : Controller { public ActionResult GetItems(List id_list) { return View(); } } 

La question est la suivante: qu’est-ce que je configure pour transformer le paramètre idl url d’une ssortingng en List et appeler l’action de contrôleur appropriée?

J’ai vu une question connexe ici qui utilisait OnActionExecuting pour prétraiter une chaîne, mais ne modifiait pas le type. Je ne pense pas que cela fonctionnera pour moi ici, car lorsque je substitue OnActionExecuting dans mon contrôleur et inspecte le paramètre ActionExecutingContext , je vois que le dictionnaire ActionParameters a déjà une clé idl avec une valeur null, probablement une tentative de idl d’une chaîne en chaîne. List … c’est la partie du routage que je veux contrôler.

Est-ce possible?

Une bonne version consiste à implémenter votre propre classeur. Vous pouvez trouver un échantillon ici

J’essaie de vous donner une idée:

 public class MyListBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ssortingng integers = controllerContext.RouteData.Values["idl"] as ssortingng; ssortingng [] ssortingngArray = integers.Split(','); var list = new List(); foreach (ssortingng s in ssortingngArray) { list.Add(int.Parse(s)); } return list; } } public ActionResult GetItems([ModelBinder(typeof(MyListBinder))]List id_list) { return View(); } 

Comme le dit slfan, un classeur de modèle personnalisé est la voie à suivre. Voici une autre approche de mon blog qui est générique et prend en charge plusieurs types de données. Il retombe également avec élégance la mise en œuvre de la liaison de modèle:

 public class CommaSeparatedValuesModelBinder : DefaultModelBinder { private static readonly MethodInfo ToArrayMethod = typeof(Enumerable).GetMethod("ToArray"); protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) { if (propertyDescriptor.PropertyType.GetInterface(typeof(IEnumerable).Name) != null) { var actualValue = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name); if (actualValue != null && !Ssortingng.IsNullOrWhiteSpace(actualValue.AttemptedValue) && actualValue.AttemptedValue.Contains(",")) { var valueType = propertyDescriptor.PropertyType.GetElementType() ?? propertyDescriptor.PropertyType.GetGenericArguments().FirstOrDefault(); if (valueType != null && valueType.GetInterface(typeof(IConvertible).Name) != null) { var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(valueType)); foreach (var splitValue in actualValue.AttemptedValue.Split(new[] { ',' })) { list.Add(Convert.ChangeType(splitValue, valueType)); } if (propertyDescriptor.PropertyType.IsArray) { return ToArrayMethod.MakeGenericMethod(valueType).Invoke(this, new[] { list }); } else { return list; } } } } return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); } }