我在我的項目中使用Web API 2屬性路由來爲我的數據提供JSON接口。我面臨着控制器選擇的怪異行爲,並未決定它是一個錯誤還是一個功能:) 讓我來描述一下我的方法。Web API 2屬性路由控制器選擇
我想借助屬性路由來模擬OData語法(由於設計原則,直接OData使用已被拒絕)。例如,要獲取id = 5的實體,我使用HTTP GET請求來訪問URI http://mydomain.com/api/Entity(5)。我期望與HTTP PUT動詞使用相同的URI來更新實體。這是旅程的開始...
我想單獨控制器獲取實體(FirstController
在下面提供的示例中提供)和另一個用於修改實體(SecondController
)。兩個控制器處理相同的URI(例如http://mydomain.com/api/Entity(5)),唯一的區別是與URI一起使用的HTTP動詞 - GET應該由FirstController
處理,PUT應該由SecondController
處理。但是URI並沒有被處理。而不是HTTP 404錯誤返回。 當我將GET和PUT操作「合併」到一個控制器(在FirstController
中註釋掉)時,兩個動詞都被正確處理。 我使用的是IIS Express,並且所有常規路由都被禁用,只有屬性路由負責。
它看起來像控制器選擇過程不適用於HTTP動詞。換句話說,HttpGet
和HttpPut
屬性只是限制操作使用,但它們不作爲控制器選擇期間的標準。我對MVC/Web API基礎知識並不熟悉,所以讓我問你我的一個大問題:
以上描述的行爲是MVC/Web API 2有意實現的功能還是需要修復的錯誤?
如果它被認爲是一個功能,它會阻止我遵循設計原則。我可以和「合併」的控制者一起生活,但仍然認爲這是一種不好的做法...... 或者我錯過了我的思路?
我的環境設置:
- 的Windows 7(使用Oracle的VirtualBox虛擬機)
- 的Visual Studio 2013
- .NET 4.5。1
- 的Web API 2
以下是實現FirstController
類:
public class FirstController : ApiController
{
[HttpGet]
[Route("api/Entity({id:int})")]
public Output GetEntity(int id)
{
Output output = new Output() { Id = id, Name = "foo" };
return output;
}
//[HttpPut]
//[Route("api/Entity({id:int})")]
//public Output UpdateEntity(int id, UpdateEntity command)
//{
// Output output = new Output() { Id = id, Name = command.Name };
// return output;
//}
}
以下是實現SecondController
類:
public class SecondController : ApiController
{
[HttpPut]
[Route("api/Entity({id:int})")]
public Output UpdateEntity(int id, UpdateEntity command)
{
Output output = new Output() { Id = id, Name = command.Name };
return output;
}
}
以下是實現一個控制檯應用程序來測試所描述的行爲:
class Program
{
static void Main(string[] args)
{
// HTTP client initialization
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("http://localhost:1567");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET - FirstController.GetEntity
HttpResponseMessage getEntityResponse = httpClient.GetAsync("/api/Entity(5)").Result;
Output getOutput = getEntityResponse.Content.ReadAsAsync<Output>().Result;
// HTTP PUT - SecondController.UpdateEntity
UpdateEntity updateCommand = new UpdateEntity() { Name = "newEntityname" };
HttpResponseMessage updateEntityResponse = httpClient.PutAsJsonAsync("/api/Entity(10)", updateCommand).Result;
Output updateOutput = updateEntityResponse.Content.ReadAsAsync<Output>().Result;
}
}
完成,以下是使用的DTO:提前爲您的答覆
public class UpdateEntity
{
public string Name { get; set; }
}
public class Output
{
public int Id { get; set; }
public string Name { get; set; }
}
感謝,
月Kacina
對於「Google搜索」完成,這裏是您在這種情況下的錯誤: 「找到了與URL匹配的多個控制器類型,如果多個控制器上的屬性路由匹配請求的URL,就會發生這種情況。 –
我已經看到了最好的問題之一,很好地完成:) – Scozzard