Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpRequest.RouteValues property is not accessible from code but accessible from debugger

I am trying to create middleware which performs some checking for particular requests.

For example, I have such routes:

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

and I have these requests:

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

Now inside my middleware I want to check if request contains {paramToCheck} and get value of this parameter.

When I set breakpoint inside InvokeAsync I can see httpContext.Request.RouteValues property containing all needed data (Keys contains "paramToCheck" and Values contains its value).

But in code I can't access this property, I get error:

Error CS1061: 'HttpRequest' does not contain a definition for 'RouteValues' and no accessible extension method 'RouteValues' accepting a first argument of type 'HttpRequest' could be found (are you missing a using directive or an assembly reference?)

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

How can I access this property or how can I perform needed check?

Code:

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);
    }
}

EDIT

Middleware is inside netstandard2.1 class library and it cannot be moved to api project as it is common and should be used by several api projects.

UPDATE

Seems like currently it cannot be achieved as RouteValues propery was added in Microsoft.AspNetCore.Http.Abstractions 3.0.0 which is inside NetCoreApp 3 metapackage. And there is no possibility to install this package in netstandard 2.1 project because the latest version is 2.2.0.

like image 493
Dixy Avatar asked Jan 06 '20 10:01

Dixy


3 Answers

Just encountered the same problem today.

This is hacky but it works

IReadOnlyDictionary<string, object>? routeValues = ((dynamic)context.Request).RouteValues as IReadOnlyDictionary<string, object>;
like image 51
Alexander Ivanov Avatar answered Sep 19 '22 15:09

Alexander Ivanov


Using a class library, the answer for me was to upgrade to using .netcore 3.1's Microsoft.AspNetCore.App instead of Microsoft.AspNetCore.Http.Abstractions v2.2

As stated here, .net core 3 did away with all the small packages, so I replaced

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
  </ItemGroup>

with

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
      <FrameworkReference Include="Microsoft.AspNetCore.App"/>
  </ItemGroup>

and then I could access the route like so:

HttpContext.Request.RouteValues["version"];

where {version} was set in the route.

like image 21
JsAndDotNet Avatar answered Sep 18 '22 15:09

JsAndDotNet


sounds like you trying to access this from a service implementation which does not have access to httpContext, am i correct in saying to have this outside of your api project.

if you do httpContext.Request.RouteValues["paramToCheck"]; in controller does it works... then to get it to work , do this in controller and pass the result to the lib.

httpContext has "binding"* to BaseController or ControllerBase... what ever its call.. basically the wiring which you are expecting is not done in your lib... so httpContext has no web context at all, there is a much better way to word this... all, but you get the just.

like image 35
Seabizkit Avatar answered Sep 18 '22 15:09

Seabizkit