2014-09-26 42 views
0

這個問題讓我感到非常緊張。帶整數數組和操作的Webapi路由

我有一個get方法,該方法ID陣列定製模型綁定器(我可以叫http://xckvjl.com/api/results/1,23,34

我要介紹的獲取上的動作。 (所以我可以打電話http://alskjdfasl.com/api/results/latest

我有以下web 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() 
     { } 

有用。但是,我想要全局級別路由。否則,對於每一個行動,我將不得不寫同樣的。

請指教。

回答

0

所以這裏的dilimma:

有了這個路由定義:

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

,當你調用http://alskjdfasl.com/api/results/latestlatest成爲id,這顯然會引發錯誤的值,因爲不能將字符串轉換爲int陣列。

添加此路由定義

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 2014-09-26 05:06:03

+0

如果我像你一樣翻轉也建議它也會拋出多重路線異常。 local/api/users/1在這裏,如果1是動作名稱,它會變得困惑......所以我可以對ID數組做約束嗎?怎麼樣? – codebased 2014-09-26 05:09:08

+0

我想進一步瞭解 - ApiWithAction路線的目的是什麼?這是你在排除故障時想要做的嗎?同樣,你可以用'int []'來代替IEnumerable嗎? – Mrchief 2014-09-26 05:10:53