2013-07-22 10 views
9

Obserwuję ten article on Attribute Routing in Web API 2 spróbować wysłać tablicę poprzez URI:Jak wysłać tablicę za pośrednictwem identyfikatora URI przy użyciu funkcji Routing atrybutów w interfejsie API sieci Web?

[HttpPost("api/set/copy/{ids}")] 
public HttpResponseMessage CopySet([FromUri]int[] ids) 

ta pracowała przy użyciu konwencji opartej ułożenia:

http://localhost:24144/api/set/copy/?ids=1&ids=2&ids=3 

Ale z atrybutu trasy nie jest już działa - Nie znaleziono 404.

Gdy próbuję to:

http://localhost:24144/api/set/copy/1 

Wtedy to działa - mam tablicę z jednym elementem.

Jak korzystać z routingu atrybutów w ten sposób?

Odpowiedz

13

Zachowanie, którego dostrzegasz, jest bardziej związane z wyborem działania. & Wiązanie modelu zamiast wyznaczania atrybutu.

Jeśli spodziewasz „identyfikatory” pochodzić z łańcucha zapytania, a następnie zmodyfikować szablon trasy jak poniżej (bo tak, jak zdefiniowano to sprawia, że ​​„identyfikatory” obowiązkowe w uri ścieżce):

[HttpPost("api/set/copy")] 

Patrząc na twoje drugie pytanie, czy chcesz zaakceptować listę identyfikatorów w samym pliku URI, np. api/set/copy/[1,2,3]? jeśli tak, nie sądzę, że web api ma wbudowane wsparcie dla tego rodzaju wiązania modelu.

Możesz zaimplementować niestandardowe powiązanie parametrów, jak poniżej, aby to osiągnąć (domyślam się, że istnieją inne lepsze sposoby osiągnięcia tego, jak w przypadku modelarzy i dostawców wartości, ale nie jestem ich świadomy ... więc mógłbyś prawdopodobnie trzeba zbadać te opcje zbyt):

[HttpPost("api/set/copy/{ids}")] 
public HttpResponseMessage CopySet([CustomParamBinding]int[] ids) 

Przykład:

[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)] 
public class CustomParamBindingAttribute : ParameterBindingAttribute 
{ 
    public override HttpParameterBinding GetBinding(HttpParameterDescriptor paramDesc) 
    { 
     return new CustomParamBinding(paramDesc); 
    } 
} 

public class CustomParamBinding : HttpParameterBinding 
{ 
    public CustomParamBinding(HttpParameterDescriptor paramDesc) : base(paramDesc) { } 

    public override bool WillReadBody 
    { 
     get 
     { 
      return false; 
     } 
    } 

    public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, 
                CancellationToken cancellationToken) 
    { 
     //TODO: VALIDATION & ERROR CHECKS 
     string idsAsString = actionContext.Request.GetRouteData().Values["ids"].ToString(); 

     idsAsString = idsAsString.Trim('[', ']'); 

     IEnumerable<string> ids = idsAsString.Split(','); 
     ids = ids.Where(str => !string.IsNullOrEmpty(str)); 

     IEnumerable<int> idList = ids.Select(strId => 
      { 
       if (string.IsNullOrEmpty(strId)) return -1; 

       return Convert.ToInt32(strId); 

      }).ToArray(); 

     SetValue(actionContext, idList); 

     TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); 
     tcs.SetResult(null); 
     return tcs.Task; 
    } 
} 
+0

Thanks Kiran. Jestem po prostu zdezorientowany, ponieważ api/set/copy /? Ids = 1 & ids = 2 & ids = 3 działało wcześniej, a mnóstwo moich metod używa tego wzorca:/ – SB2055

+1

Powinno to działać teraz tak długo, jak długo nie masz ' Identyfikatory zdefiniowane w szablonie trasy, takie jak: '[HttpPost (" api/set/copy ")]'. Pamiętaj, że szablon trasy może być używany tylko do definiowania ścieżek URI, a nie do danych ciągów zapytania. –

+0

Idealny. Dziękujemy – SB2055

Powiązane problemy