将HttpContext.Request读取为对象? [英] Reading HttpContext.Request as object?

查看:78
本文介绍了将HttpContext.Request读取为对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的基本 Request 类如下:

public class GetAllProjectsQuery : QueryBase<ProjectsListModel>
{
}

public abstract class QueryBase<T> : UserContext, IRequest<T> // IRequest is MediatR interface
{
}

public abstract class UserContext
{
    public string ApplicationUserId { get; set; } // and other properties
}

我想向我的 .NET Core 3.1 WebApi 中编写一个中间件,该中间件将从请求标头中获取 JWT ,并从中读取 ApplicationUserId .我开始编写一些代码:

I want to write a middleware to my .NET Core 3.1 WebApi that will grab JWT from request header amd read ApplicationUserId from it. I started to code something:

public class UserInformation
{
    private readonly RequestDelegate next;

    public UserInformation(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var jwt = context.Request.Headers["Authorization"];
        // read jwt here
        var userContext = (UserContext)context.Request.Body; // i know it wont work
        userContext.ApplicationUserId = //whats next? Any ideas?

        await this.next(context);
    }
}

但是说实话,我不知道如何开始,所以这是我的问题:

But to be honest i have no idea how to start so here are my questions:

如您所见,每个请求将与我的 UserContext 类一起打包,依此类推.如何将 HttpContext.Request.Body 投射到我的请求对象并将 ApplicationUserId 附加到我的请求对象?是否可以?我想从头部的JWT访问用户凭证,并且希望在我的API的每个请求中都包含该信息(将其传递给控制器​​,然后传递给命令等).

As you can see, every request will be packed with my UserContext class and so on. How to cast HttpContext.Request.Body to my request object and attach ApplicationUserId to it? Is it possible? I want to acces to user credentials from my JWT from headers and i want to have that information in every request in my API (pass it to controller, then to command etc).

如果不是从中间件获取此信息的最佳做法,那是什么?

If getting this information from middleware is not the best practice, what is?

使用 MediatR 的Mcontroller:

Mcontroller that using MediatR:

// base controller:
[ApiController]
[Route("[controller]")]
public abstract class BaseController : ControllerBase
{
    private IMediator mediator;

    protected IMediator Mediator => this.mediator ?? (this.mediator = HttpContext.RequestServices.GetService<IMediator>());
}

// action in ProjectControlle

[HttpGet]
[Authorize]
public async Task<ActionResult<ProjectsListModel>> GetAllProjects()
{
    return Ok(await base.Mediator.Send(new GetAllProjectsQuery()));
}

// query:
public class GetAllProjectsQuery : QueryBase<ProjectsListModel>
{
}

// handler:

public class GetAllProjectsQueryHandler : IRequestHandler<GetAllProjectsQuery, ProjectsListModel>
{
    private readonly IProjectRepository projectRepository;

    public GetAllProjectsQueryHandler(IProjectRepository projectRepository)
    {
        this.projectRepository = projectRepository;
    }

    public async Task<ProjectsListModel> Handle(GetAllProjectsQuery request, CancellationToken cancellationToken)
    {
        var projects = await this.projectRepository.GetAllProjectsWithTasksAsync();

        return new ProjectsListModel
        {
            List = projects
        };
    }
}

推荐答案

您可能不需要中间件,但需要模型绑定器:

You might not need a middleware, but need a model binder:

请参阅: https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/model-binding?view = aspnetcore-3.1

另请参阅:

然后将模型绑定程序添加到 UserContext 类:

Then add model binder to UserContext class:

[ModelBinder(typeof(UserContextModelBinder))]
public abstract class UserContext
{
    public string ApplicationUserId { get; set; }
}

还将 IHttpContextAccessor 添加到Startup.cs中的服务:

Also add IHttpContextAccessor to services in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddHttpContextAccessor();
}

这篇关于将HttpContext.Request读取为对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆