2012-02-29 13 views
58

Mam kontroler ASP.net MVC nazwie Designs, który ma działanie z następującym podpisem:Jak mogę zaakceptować tablicę jako parametr działania kontrolera ASP.NET MVC?

public ActionResult Multiple(int[] ids) 

Jednak gdy próbuję nawigować do tego działania za pomocą adresu URL:

http://localhost:54119/Designs/Multiple?ids=24041,24117 

Parametr ids jest zawsze pusty. Czy istnieje sposób na przekonwertowanie przez MVC parametru zapytania ids = URL do tablicy dla akcji? Widziałem mówić o użyciu filtra akcji, ale o ile mogę powiedzieć, że będzie działać tylko dla POSTs, gdzie tablica jest przekazywana w danych żądania, a nie w samym URL.

Odpowiedz

110

Domyślna modelu spoiwo oczekuje URL:

http://localhost:54119/Designs/Multiple?ids=24041&ids=24117 

aby skutecznie wiążą się z:

public ActionResult Multiple(int[] ids) 
{ 
    ... 
} 

A jeśli chcesz to do pracy z wartościami rozdzielonymi przecinkami można napisać niestandardowy model spoiwa:

public class IntArrayModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     if (value == null || string.IsNullOrEmpty(value.AttemptedValue)) 
     { 
      return null; 
     } 

     return value 
      .AttemptedValue 
      .Split(',') 
      .Select(int.Parse) 
      .ToArray(); 
    } 
} 

, a następnie można zastosować ten model spoiwa do konkretnego argument akcji ar:

public ActionResult Multiple([ModelBinder(typeof(IntArrayModelBinder))] int[] ids) 
{ 
    ... 
} 

lub zastosować ją globalnie do wszystkich parametrów tablicowych całkowitą w swojej Application_Start w Global.asax:

ModelBinders.Binders.Add(typeof(int[]), new IntArrayModelBinder()); 

a teraz twoje działanie kontroler może wyglądać następująco:

public ActionResult Multiple(int[] ids) 
{ 
    ... 
} 
+0

Brakowało mi "[FromUri]". 'public ActionResult Multiple ([FromUri] int [] ids) {}' ** (GET) ** – C0d1ngJammer

+0

@ Darin Czy istnieje sposób na zastosowanie niestandardowego powiązania globalnie, ale po prostu zignoruj ​​konkretne działanie? Nie mogłem znaleźć sposobu na to: https: //stackoverflow.com/questions/45379040/how-to-override-global-model-binder-for-speacific-post-action-mvc5 – akd

8

Możesz także użyć tego formatu adresu URL, a ASP.NET MVC zrobi wszystko za Ciebie. Pamiętaj jednak, aby zastosować kodowanie adresów URL.

?param1[0]=3344&param1[1]=2222 
4

nie wiem gdzie URL ciąg Groky została pochodzi, ale miałem ten sam problem z pewnym javascript wywołującego mojego kontrolera/działania. Utworzono by URL o adresie null, 1 lub wiele "identyfikatorów" z listy wielokrotnego wyboru (która jest unikalna dla rozwiązania, które zamierzam udostępnić).

Kopiuję/wklejałem niestandardowy segregator modelu Darina i dekoruję moje działanie/parametr, ale nie zadziałało. Wciąż mam null o wartości int[] ids. Nawet w "bezpiecznym" przypadku, w którym faktycznie miałem wiele identyfikatorów.

skończyło się na zmianę javascript, aby wytworzyć przyjazną tablicę parametrów ASP.NET MVC jak

?ids=1&ids=2 

musiałem zrobić trochę głupie rzeczy, choć

ids || []     #=> if null, get an empty array 
[ids || []]    #=> if a single item, wrap it in an array 
[].concat.apply([], ...) #=> in case I wrapped an array, flatten it 

Tak, był pełny blok

ids = [].concat.apply([], [ids || []]) 
id_parameter = 'ids=' + ids.join('&ids=') 

To nieprzyjemne, ale po raz pierwszy musiałem zhakować w ten sposób w javascript.

+1

Po prostu ciekawy, czy istnieje brakuje "nie" przed "pierwszym razem" w tym ostatnim zdaniu. W przeciwnym razie, masz szczęście! – DCShannon

+1

@DCShannon: haha, widzę twój punkt widzenia! Ale to był mój pierwszy raz. Nie jestem pewien, czy takie rzeczy są normalne, czy też wybieram za burtę. –

7

Aby przedłużyć na Darin Dimitrov's answer, coś można uciec z akceptuje prosty string w parametrze URL i przekształcenie go do tablicy siebie:

public ActionResult Multiple(string ids){ 
    int[] idsArray = ids.Split(',').Select(int.Parse).ToArray(); 
    /* ...process results... */ 
} 

Jeśli pojawi się błąd składniowy podczas gdy to robi (bo ktoś przekazał ci zniekształconą tablicę), możesz spowodować, że twój menedżer wyjątków zwróci błąd 400 Bad Request zamiast domyślnego, bardziej nieprzyjaznego błędu 404 Not Found, który MVC zwraca, gdy punkt końcowy nie zostanie znaleziony.

Powiązane problemy