Свойство HttpRequest.RouteValues ​​недоступно из кода, но доступно из отладчика - PullRequest
4 голосов
/ 06 января 2020

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

Например, у меня есть такие маршруты:

  • api/Test/{paramToCheck}/aaa
  • api/Test/bbb/ccc

и у меня есть эти запросы:

  • http://some-host-and-port/api/Test/1234/aaa
  • http://some-host-and-port/api/Test/bbb/ccc

Теперь внутри моего промежуточное ПО Я хочу проверить, содержит ли запрос {paramToCheck} и получить ли значение этого параметра.

Когда я устанавливаю точку останова внутри InvokeAsync, я вижу httpContext.Request.RouteValues свойство, содержащее все необходимые данные (Keys содержит "paramToCheck" и Values содержит его значение).

Но в коде я не могу получить доступ к этому свойству, я получаю ошибку:

Ошибка CS1061: «HttpRequest» не содержит может быть найдено определение для 'RouteValues' и нет доступного метода расширения 'RouteValues', принимающего первый аргумент типа 'HttpRequest' (вам не хватает директивы using или ссылки на сборку?)

var value = httpContext.Request.RouteValues["paramToCheck"];

Как получить доступ к этому свойству или как выполнить необходимую проверку?

* 1 043 * Код:
public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware
    (
        RequestDelegate next
    ) => this._next = next;

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var value = httpContext.Request.RouteValues["paramToCheck"]; // error here

        //... some logis with value

        await this._next(httpContext);
    }
}

РЕДАКТИРОВАТЬ

Промежуточное программное обеспечение находится внутри netstandard2.1 библиотеки классов и не может быть перемещено в проект API, поскольку оно является общим и должно использоваться несколькими проектами API.

ОБНОВЛЕНИЕ

Похоже, что в настоящее время это не может быть достигнуто, поскольку свойство RouteValues было добавлено в Microsoft.AspNetCore.Http.Abstractions 3.0.0, который находится внутри NetCoreApp 3 метапакета. И нет возможности установить этот пакет в netstandard 2.1 проекте, потому что последняя версия 2.2.0.

Ответы [ 4 ]

2 голосов
/ 06 января 2020

звучит так, как будто вы пытаетесь получить доступ к этому из реализации службы, которая не имеет доступа к httpContext, правильно ли я сказал, что это происходит за пределами вашего проекта API.

, если вы делаете httpContext.Request.RouteValues["paramToCheck"]; в контроллере это работает ... затем, чтобы заставить его работать, сделайте это в контроллере и передайте результат в lib.

httpContext имеет "привязку" * к BaseController или ControllerBase ... что бы он ни вызывал .. в основном, проводка, которую вы ожидаете, не выполняется в вашей библиотеке ... поэтому httpContext вообще не имеет веб-контекста, есть гораздо лучший способ выразить это ... все, но вы получите справедливое.

0 голосов
/ 24 апреля 2020

Вы можете использовать расширение .GetRouteData() из RoutingHttpContextExtensions, которое предоставит вам экземпляр RouteData. Это расширение является частью пакета Microsoft.AspNetCore.Routing .

* RouteData содержит элемент свойства типа RouteValueDictionary с именем Значения .

var routeData = httpContext.GetRouteData();

if (routeData.Values.TryGetValue("MyRouteKey", out object value))
{
    // ... Do some logic with the value
}

Чтобы узнать немного больше о RoutingHttpContextExtensions и RouteData, проверьте исходный код на https://github.com/dotnet/aspnetcore/tree/3.0/src/Http/Routing

0 голосов
/ 11 апреля 2020

Сегодня столкнулся с той же проблемой.

Это хакерство, но оно работает

IReadOnlyDictionary<string, object>? routeValues = ((dynamic)context.Request).RouteValues as IReadOnlyDictionary<string, object>;
0 голосов
/ 06 января 2020
public async Task InvokeAsync(HttpContext httpContext)
{
    //Instead of this
    var value = httpContext.Request.RouteValues["paramToCheck"];
   //Use like this
    string originalPath = context.Request.Path.ToString();
   //You will get your desired values to check your validation
   //and then
  //just check like this
 if (originalPath.Trim().Contains("api/URL/{paramToCheck}", 
     StringComparison.InvariantCultureIgnoreCase)
 //then do your necessary validation here
...