Это набросок моего класса TransferController.
Все это код веб-API.
public class TransferController : ApiController
{
[HttpGet, ActionName("Queue")]
public IEnumerable<object> GetQueue(Guid sessionId) {...}
[HttpDelete, ActionName("Delete")]
public void Delete(Guid sessionId, Guid fileId) {...}
[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid fileId) {...}
[HttpGet, ActionName("UploadedBytes")]
public long GetUploadedByteCount(Guid sessionId, Guid fileId) {...}
[HttpGet, ActionName("DownloadUrl")]
public string GetDownloadUrl(string fileId) {...}
[HttpPost, ActionName("FileChunk")]
public void PostFileChunk([FromUri]Guid sessionId, [FromUri]Guid fileId) {...}
[HttpPost, ActionName("UploadDefinition")]
public Guid PostUploadItem([FromBody]UploadDefinition uploadDef) {...}
}
Это маршрутизация.
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}"
);
config.Routes.MapHttpRoute(
name: "DefaultApiDefaultMethod",
routeTemplate: "api/{controller}"
);
}
Это вызов.
$.ajax({
url: "api/Transfer/Queue",
data: { sessiondId: login.SessionId() }
})
.done(function (result) {
history.push(new UploadItem());
for (var i = 0; i < result.length; i++) {
var ui = new UploadItem(result[i]);
history.push(ui);
}
})
.fail(function (result) {
app.showMessage(JSON.parse(result.responseText).Message);
});
И вот результат.
No HTTP resource was found that matches the request URI 'http://localhost:54770/api/Transfer/Queue?sessiondId=0e2c47b9-e674-446d-a06c-ce16932f9580'.
Это набросок моего класса UserController.
public class UserController : ApiController
[HttpGet, ActionName("Authenticate")]
public object Authenticate(string email, string password) {...}
[HttpPost]
public void Register([FromBody]UserDefinition userDef) {...}
[HttpGet, ActionName("Pulse")]
public bool Pulse(Guid sessionId) {...}
}
По непостижимым для меня причинам у меня нет проблем с вызовом чего-либо в UserController. Параметры маршалируются точно так же, и используются те же маршруты.
Даррел Миллер ниже использует модульное тестирование для проверки маршрутов. Честно говоря, я корю себя за то, что не подумал об этом, и теперь я сделал то же самое.
Но тесты, как он их показывает, действительно проверяют только синтаксический анализ URL. Например, этот тест проходит
public void TestMvc4RouteWibble()
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var route =
config.Routes.GetRouteData(new HttpRequestMessage()
{
RequestUri = new Uri("http://localhost:54770/api/Transfer/Wibble?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580&fileId=0e2c47b9-e674-446d-a06c-ce16932f9581") //?
});
Assert.IsNotNull(route);
Assert.AreEqual("Transfer", route.Values["controller"]);
Assert.AreEqual("Wibble", route.Values["action"]);
}
несмотря на бросающееся в глаза отсутствие метода Wibble на контроллере Transfer.
Кроме того, объект маршрута на самом деле не является объектом HttpRoute, это объект HttpRouteData. Но это банально поправимо. Объект HttpRoute доступен как свойство объекта HttpRouteData.
public void TestMvc4RouteWibble()
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var routeData =
config.Routes.GetRouteData(new HttpRequestMessage()
{
RequestUri = new Uri("http://localhost:54770/api/Transfer/Wibble?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580&fileId=0e2c47b9-e674-446d-a06c-ce16932f9581") //?
});
Assert.IsNotNull(routeData);
Assert.AreEqual("Transfer", routeData.Values["controller"]);
Assert.AreEqual("Wibble", routeData.Values["action"]);
}
А у него, в свою очередь, есть свойство Handler. Однако это менее информативно, чем могло бы быть, поскольку нулевой обработчик просто означает (из MSDN)
Если значение null, обработчик по умолчанию отправляет сообщения реализациям IHttpController.
Теперь мой контроллер является производным от ApiController, который, безусловно, реализует метод ExecuteAsync, который является единственной вещью, определяемой интерфейсом IHttpController. Я думаю, что это означает, что я мог бы проверить выполнение этого метода, если бы знал о нем больше.
Cancel
- person Daniel A. White   schedule 11.04.2014