Ни один HTTP Resource не был найден, что соответствует ошибке URI запроса в ASP.NET Web API
-
21-12-2019 - |
Вопрос
Все это код веб-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'.
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) {...}
}
.
по причинам, не связанным со мной, у меня нет проблем, ничего не призывающих в целостке. Параметры маршаллированы точно так же, и используются маршруты .
Darrel Miller ниже использует тестирование блока для проверки маршрутов. Честно говоря, я пинаю себя за то, что не думаете об этом, и теперь я сделал то же самое.
Но тесты, поскольку он показывает, что они действительно тестируют только разбор 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"]);
}
.
Несмотря на заметное отсутствие метода, смутителя на контроллере передачи.
Также объект маршрута на самом деле не является объектом HTTPROUTE, это объект HTTPROTEDATA. Но это тривиально исправлено. Объект HTTPROUTE доступен в качестве свойства объекта HTTPROTEDATA.
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"]);
}
.
И это в свою очередь имеет свойство обработчика. Однако это менее информативно, чем может быть, поскольку нулевой обработчик просто означает (от MSDN)
Теперь мой контроллер получают из Apicontroller, который, безусловно, реализует метод ExecuteAsync, который является единственным, указанным интерфейсом IHTTPController. Что я представляю, значит, я мог бы проверить выполнение этого метода, если я знал больше об этом.Если нуль, обработчик по умолчанию отправляет сообщения для реализаций IHTTPController.
Решение 2
Хорошо, тогда ... спасибо за то, что выступил идею тестирования подразделения в моей голове, он сильно поправился.
Вот низкое расстояние:
Вы можете иметь одинаковые параметры подписи на разных глаголах (Получить поставку Удалить).
Вы
Вам нужно только варьироваться одно имя параметра .
Так что это нормально, потому что они все на разных глаголах
[HttpDelete, ActionName("Delete")]
public void Delete(Guid sessionId, Guid fileId) {...}
[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid fileId) {...}
[HttpPost, ActionName("FileChunk")]
public void PostFileChunk(Guid sessionId, Guid fileId) {...}
.
Но это не круто, потому что они оба получают
[HttpGet, ActionName("UploadedBytes")]
public long GetUploadedByteCount(Guid sessionId, Guid fileId) {...}
[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid fileId) {...}
.
, и вы можете исправить это как это
[HttpGet, ActionName("UploadedBytes")]
public long GetUploadedByteCount(Guid sessionId, Guid uploadBytesFileId) {...}
[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid cancelFileId) {...}
.
Может быть, я жесткая задница, но насколько я понимаю, это не маршрутизация, пока метод не будет вызван.
Другие советы
Вот тест, который демонстрирует маршрутизацию, работает хорошо,
[Fact]
public void TestRoute()
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}"
);
var route =
config.Routes.GetRouteData(new HttpRequestMessage()
{
RequestUri = new Uri("http://localhost:54770/api/Transfer/Queue?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580") //?
});
Assert.NotNull(route);
Assert.Equal("Transfer",route.Values["controller"]);
Assert.Equal("Queue",route.Values["action"]);
}
.
А вот тест, показывающий выделение диспетчера / действия, также работает,
[Fact]
public void TestDispatch()
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}"
);
var server = new HttpServer(config);
var client = new HttpClient(server);
var response =
client.GetAsync(new Uri("http://localhost:54770/api/Transfer/Queue?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580")) //
.Result;
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
public class TransferController : ApiController
{
[HttpGet]
[ActionName("Queue")]
public IEnumerable<object> Queue(Guid sessionId)
{
return null;
}
}
.