2014-08-27 63 views
0

我正在使用vs2012並開始與「ASP.net Web Api 2」模板的新項目。完成編碼並開始測試系統。我觀察到路由的奇怪行爲。如:Asp.Net Web Api 2奇怪的路由行爲

這裏是我的路線:

config.Routes.MapHttpRoute(
    name: "personRoute", 
    routeTemplate: "api/px/{action}/{personid:Guid}", 
    defaults: new { controller = "px", personid = RouteParameter.Optional } 
); 

config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{action}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
); 

,這裏是我的控制器:

public class PxController : ApiController { 

    private Configuration.DatabaseContext dbctx = new Configuration.DatabaseContext(); 

    [HttpGet] 
    public IEnumerable<Models.Person> GetAll() { 
     return dbctx.Persons.ToArray(); 
    } 

    [ActionName("op")] 
    [HttpGet] 
    public Models.Person ById(Guid personid) { 
     var data = dbctx.Persons.FirstOrDefault(e => e.PersonId == personid); 

     if (data == null) { 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 

     return data; 
    } 

    [ActionName("op")] 
    [HttpPost] 
    public void Insert([FromBody] Models.Person newPerson) { 
     dbctx.Persons.Add(newPerson);   
     dbctx.SaveChanges(); 
    } 

    [ActionName("op")] 
    [HttpPut] 
    public void Update([FromBody]Models.Person eperson) {   
     var data = dbctx.Persons.FirstOrDefault(e => e.PersonId == eperson.PersonId); 

     if (data == null) { 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 

     dbctx.Entry(eperson).State = System.Data.Entity.EntityState.Modified; 
     dbctx.SaveChanges(); 
    } 

    [ActionName("op")] 
    [HttpDelete] 
    public void DeleteById(Guid personid) { 
     var data = dbctx.Persons.FirstOrDefault(e => e.PersonId == personid); 

     if (data == null) { 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 

     dbctx.Entry(data).State = System.Data.Entity.EntityState.Deleted; 
     dbctx.SaveChanges(); 
    } 

    #region |:.Extended Queries.:| 
    [HttpGet] 
    public IEnumerable<RemoteProperty> Properties(Guid personid) { 
     var data = from n in dbctx.RemoteProperties 
        where n.PersonId == personid && n.ParentId == null 
        orderby n.PropertyType.Name 
        select n; 

     if (data == null) 
      throw new HttpResponseException(HttpStatusCode.NotFound); 

     foreach (var rp in data) { 
      rp.Details = dbctx.RemoteProperties.SqlQuery("SELECT * FROM properties WHERE parentid = @parid").ToArray(); 
     } 

     return data.ToArray(); 
    } 

    [HttpGet] 
    public IEnumerable<Relation> Relations(Guid personid) { 
     var data = from n in dbctx.Relations 
        where n.PersonId == personid 
        select n; 

     if (data == null) 
      throw new HttpResponseException(HttpStatusCode.NotFound); 

     return data.ToArray(); 
    } 
    #endregion 

    [NonAction] 
    protected override void Dispose(bool disposing) { 

     if (dbctx != null && dbctx is IDisposable) { 
      dbctx.Dispose(); 
     } 

     base.Dispose(disposing); 
    } 

} 

這些是查詢提琴手輸出:

http://localhost:49318/api/px/GetAll 
/* Works as expected */ 

http://localhost:49318/api/px/op/dfc737ca-312c-e411-ae3c-78843ccba6ef 
/* The requested resource does not support http method 'GET'. */ 

http://localhost:49318/api/px/op?personid=dfc737ca-312c-e411-ae3c-78843ccba6ef 
/* Returns the data with personid, but why the above query fails? */ 

http://localhost:49318/api/px/properties?personid=dfc737ca-312c-e411-ae3c-78843ccba6ef 
/* Returns the data with personid */ 

http://localhost:49318/api/px/properties/dfc737ca-312c-e411-ae3c-78843ccba6ef 
/* No action was found on the controller 'Px' that matches the request */ 

我的問題是什麼可能是這種行爲的原因?我也不能使用路由(因爲他們不工作):

"api/{controller}/{personid}/{action}" 

回答

0

好的。通過檢查整個項目並應用這些更改(下面列出),我成功地實現了它的運行。所以這裏是我做的:

  • 我正在使用VS2012和web.api模板2.0和.net 4.5。
  • VS.2012不支持web.api 2.0,但有更新。
  • 我檢查了所有的DLL文件引用,意識到他們中的一些有錯誤的版本。
  • 因此我刪除了所有的引用。
  • 我從NuGet獲得Web.api 2.2並安裝了所有DLL文件
  • Voila。它開始工作。

對於調試項目,有一個MS提供的「跟蹤」程序集,我使用它。它將跟蹤消息放置到輸出窗口,而路由選擇等等。所以我能夠看到(發生了什麼)。 VS 2012更新不足以使其工作。

1

嘗試使用[Route]屬性而不是[Action]屬性。

在我的控制器,我已經成功地使用了以下內容:

[RoutePrefix("api/Demo")] // Sets the base route for actions in this controller 
public class DemoController : ApiController 
{ 
    [HttpGet] 
    [Route("DemoAction")] // This makes this function map to route http://site/api/Demo/DemoAction 
    public IHttpActionResult PerformComplexApiAction(int id) 
    { 
     ... 

的[RoutePrefix]可以省略,可以在每個功能的單獨[路線]項中提供的完整路徑。

+0

如果我喜歡[Route(「api/px/oper/{pid:Guid}」)]並從_ById(Guid personid)_移除[ActionName] _到_ById(Guid pid)_,但爲什麼它不符合路線?我也沒有使用Route Debugger成功。它甚至沒有工作。 – 2014-08-27 14:18:23

+0

謝謝你的回答。 – 2014-09-02 10:35:14