Первый запрос достигает контроллера, как и ожидалось, но повторный запуск того же запроса вызывает ошибку: HTTP-ресурс не был (исправлен, основная причина неизвестна)

#c# #asp.net-web-api #routes #request-uri

Вопрос:

Я прочитал бесчисленное множество других тем об этом конкретном сообщении об ошибке маршрутизации, но, похоже, ни одна из них не относится к моей ситуации. Вот упрощенная версия моего кода:

Запрос

 protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestOne)
{
    var reqClone = await requestOne.Clone();
    var responseOne = await base.SendAsync(requestOne, default(CancellationToken));
    var responseTwo = await base.SendAsync(reqClone, default(CancellationToken));
    
    return responseTwo;
}
 

Образец контроллера

 /// <summary>
/// Create an oRecord.
/// </summary>
/// <param name="cKey">key</param>
/// <param name="oRecord">record</param>
/// <param name="ct">cancellation token</param>
[Route(RouteDefinitions.ExampleRoutes.TestRoute)]
[Authorize]
[HttpPost]
public async Task<IHttpActionResult> Create(string cKey, [FromBody] OResource oRecord, CancellationToken ct)
{
    return something;
}
 

У меня есть настройка контроллера для получения, обнаружения, размещения и сообщений. Независимо от того, какой HTTP-запрос мы вызовем, первый запрос достигнет контроллера и выполнит ожидаемые действия, но второй запрос немедленно завершится ошибкой в System.Web.Http с

404: Не найден HTTP-ресурс, соответствующий запросу http://request/com/api/v1/example

Я также упомяну, что то же самое происходит, если мы выполняем два разных запроса (т. Е. Отправляем, а затем получаем) в одном и том же вызове на один и тот же сервер.

Моя маршрутизация контроллера, похоже, настроена нормально, потому что мы получаем первый успешный вызов.

У кого-нибудь есть указания, где искать? Может ли между двумя вызовами произойти что-то, что изменит данные маршрутизации?

Заранее благодарю вас за помощь!

Обновить

Fixed but root cause unknown!

Я нашел решение этой проблемы и наполовину понимаю ее основную причину. Я заметил, что маршрутные данные для моих двух запросов были разными. Смотреть ниже:

 protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestOne)
{
    var reqClone = await requestOne.Clone();
    IHttpRouteData routeData = requestOne.GetRouteData();
    IHttpRouteData clonedRouteData = reqClone.GetRouteData();
    var responseOne = await base.SendAsync(requestOne, default(CancellationToken));
    IHttpRouteData routeDataAfterRequestOne = requestOne.GetRouteData();
    IHttpRouteData clonedRouteDataAfterRequestOne = reqClone.GetRouteData();
    var responseTwo = await base.SendAsync(reqClone, default(CancellationToken));
    
    return responseTwo;
}
 

Я обнаружил, что если бы я выполнил приведенный выше код, как RouteData, так и clonedRouteData имели бы тип RouteCollectionRouteData. Однако после выполнения первого запроса routeDataAfterRequestOne и clonedRouteDataAfterRequestOne оба вернут тип HttpRouteData.

Я все еще не уверен, почему изменились данные маршрута, особенно для клонированного запроса, но это так. Я исправил свою проблему, выполнив следующее:

 protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestOne)
{
    IHttpRouteData routeData = requestOne.GetRouteData();
    var reqClone = await requestOne.Clone();
    var responseOne = await base.SendAsync(requestOne, default(CancellationToken));
    reqClone.setRouteData(routeData);
    var responseTwo = await base.SendAsync(reqClone, default(CancellationToken));
    
    return responseTwo;
}
 

Если кто-нибудь знает, почему данные маршрута могли быть обновлены для обоих запросов, пожалуйста, дайте мне знать. Я хотел бы лучше понять, что произошло. Спасибо!

Комментарии:

1. Вы используете разные параметры во втором запросе?

2. Какая программа делает запрос?

3. Он сломается, если мы будем использовать разные параметры, но также и если мы будем использовать клонированный запрос.

4. Я нашел исправление и обновил описание. Я все еще не знаю первопричины, но надеюсь, что кто — то еще сможет помочь с этим.