2014-09-26 2 views
0

이 문제로 인해 많은 어려움이 있습니다.정수 배열 및 동작을 사용하는 Webapi 라우팅

내가 정의 ModelBinder를 함께 ID의 배열을 get 메소드를

내가 소개 할

는 행동에 가져옵니다 (나는 http://xckvjl.com/api/results/1,23,34를 호출 할 수 있습니다). (내가 전화 할 수 있도록 http://alskjdfasl.com/api/results/latest)

다음 웹 API 라우팅이 있습니다.

config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional }); 

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}"); 

내가 함께 노력했다 당신이 샘플이 오류를 재현 할 수

config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional }, new {id = @"\d+" }); 

(나는 내 ​​사용자 정의 모델 바인더를 사용하고 있습니다 점에 유의하시기 바랍니다) :

public class TestController: ApiController { 

      [HttpGet] 
      public virtual IHttpActionResult Get([ModelBinder(typeof(CommaDelimitedCollectionModelBinder))]IEnumerable<int> id = null) 
     { } 

      [HttpGet] 
      public virtual IHttpActionResult Latest() 
     { } 

} 

public class CommaDelimitedCollectionModelBinder : IModelBinder 
    { 
     public bool BindModel(HttpActionContext actionContext, 
      ModelBindingContext bindingContext) 
     { 
      var key = bindingContext.ModelName; 
      var val = bindingContext.ValueProvider.GetValue(key); 

      if (val == null) 
      { 
       return false; 
      } 

      var s = val.AttemptedValue; 
      if (s != null && s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Length > 0) 
      { 
       var array = s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(n=>Convert.ToInt32(n)).ToArray(); 
       Type type = bindingContext.ModelType.GetGenericArguments().First(); 

       var typeValue = Array.CreateInstance(type, array.Length); 
       array.CopyTo(typeValue, 0); 

       bindingContext.Model = array; 
      } 
      else 
      { 
       bindingContext.Model = new[] { s }; 
      } 

      return true; 
     } 
    } 

내가 작성하는 경우를 예 :

[HttpGet] 
[Route("Tests/latest")] 
public virtual IHttpActionResult Latest() 
     { } 

그것은 작동합니다. 그러나 나는 글로벌 레벨 라우팅을 원한다. 그렇지 않으면 모든 행동에 대해 똑같이 써야합니다.

알려 주시기 바랍니다.

config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional }); 

당신이 http://alskjdfasl.com/api/results/latest 전화 문자열 int 배열로 변환 할 수 없기 때문에, latest 분명히 오류가 발생합니다 id의 값이된다 :이 경로 정의와

:

답변

0

그래서 여기가 dilimma입니다 .

당신이 주문 처리 나 이제이 때문에 마스크되고 다른 행동에 대한 경로를 정의해야 하나 지금부터

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}"); 

이 도움이되지 않습니다이 경로 정의를 추가.

개별 레벨에서 경로를 선언하지 않으면 다른 옵션은 템플릿을 다르게하거나 배열을 이해하는 자체 경로 제약 조건을 만드는 것입니다.

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}/{id}", new { id = RouteParameter.Optional }); 

// or if all your methods are called latest 

config.Routes.MapHttpRoute("ApiWithAction", "{controller}/latest"); 

아무것도 작동하지 않는 경우

, 나는 속성 경로로 이동 말할 것이다 :

나는 이들에게 먼저 기회를 줄 것이다. 그들은 더 깨끗합니다.

+0

이미 행운을 빕니다 – codebased

+0

만약 당신이 제안했다해도 그것은 다중 경로 예외를 던질 것입니다. local/api/users/1 여기서 1이 액션 이름 인 경우 혼란스러워집니다 ... ID 배열에 대한 제약 조건을 만들 수 있습니까? 방법? – codebased

+0

나는 'ApiWithAction' 경로의 목적이 무엇인지 더 자세히 이해하려고합니다. 문제를 해결하는 중에 문제가되는 것입니까? 또한 IEnumerable 대신 int []로 시도 할 수 있습니까? – Mrchief