C# 如何在ASP.NET Core 3的Blazor页面中正确重用具有授权的控制器

C# 如何在ASP.NET Core 3的Blazor页面中正确重用具有授权的控制器,c#,asp.net-core,asp.net-web-api,blazor,blazor-server-side,C#,Asp.net Core,Asp.net Web Api,Blazor,Blazor Server Side,先决条件: 单个ASP.NET Core 3 preview 8项目,包括Blazor服务器端和Web Api控制器 ASP.NET核心标识 浏览器中以及从移动客户端调用API时用于授权逻辑的Cookie和JWT令牌身份验证方案 为了简洁起见,这里的所有代码示例都有最少的代码量 这里是初始blazor页面、模型和初始控制器 @page”/fetchdata @属性[授权] @使用BlazorApp2.Controllers 呼叫控制器 @代码{ 专用异步任务callController() {

先决条件:

  • 单个ASP.NET Core 3 preview 8项目,包括Blazor服务器端和Web Api控制器
  • ASP.NET核心标识
  • 浏览器中以及从移动客户端调用API时用于授权逻辑的Cookie和JWT令牌身份验证方案
  • 为了简洁起见,这里的所有代码示例都有最少的代码量
  • 这里是初始blazor页面、模型和初始控制器

    @page”/fetchdata
    @属性[授权]
    @使用BlazorApp2.Controllers
    呼叫控制器
    @代码{
    专用异步任务callController()
    {
    }
    }
    
    公共类输入模型
    {
    [必需]
    公共字符串消息{get;set;}
    }
    
    [路由(“api/[控制器]”)]
    [ApiController]
    [授权]
    公共类MessageController:ControllerBase
    {
    [HttpPost(“createMessage”)]
    公共异步任务CreateMessage(InputModel模型)
    {
    var userId=User.FindFirstValue(ClaimTypes.NameIdentifier);
    返回$“{model.Message}{userId}”;
    }
    }
    
    以“正常”的方式使用控制器(通过发送http请求)带来的内置好处很少:自动授权;模型验证;填充HttpContext和用户属性(以及其他)

    目标是在获取Blazor页面的数据时重用控制器

    想法1

    配置控制器并将其注入Blazor页面,使其操作的调用方式与http请求期间的调用方式类似。不确定如何实现这一点,以及这是否确实可行。向DI容器注册控制器不是问题(
    addControllerAsservices()
    )。但这不会在注入期间填充控制器的
    HttpContext
    User
    属性。在控制器注入后获取
    HttpContext
    的唯一方法(我知道)是在
    Startup
    中配置
    IHttpContextAccessor
    services.AddHttpContextAccessor();
    )并将其注入控制器。但这也意味着当使用http请求访问控制器时,可以从注入的
    IHttpContextAccessor
    和控制器的
    HttpContext
    属性访问
    HttpContext
    。是否有任何可能的问题,因为这?此解决方案也不会在控制器中进行模型验证。同时,可以在从Blazor页面发送之前验证模型,但我不确定在这种情况下是否必须在controller中手动重新验证它

    
    [路由(“api/[控制器]”)]
    [ApiController]
    [授权]
    公共类MessageController:ControllerBase
    {
    专用只读IHttpContextAccessor\u httpContextAccessor;
    公共消息控制器(IHttpContextAccessor httpContextAccessor)
    {
    _httpContextAccessor=httpContextAccessor;
    }
    [HttpPost(“createMessage”)]
    公共异步任务CreateMessage(InputModel模型)
    {
    var userId=_httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.nameignifier);
    返回$“{model.Message}{userId}”;
    }
    }
    
    @page”/fetchdata
    @使用BlazorApp2.Controllers
    @属性[授权]
    @注入MessageController消息控制器;
    呼叫控制器
    @代码{
    专用异步任务callController()
    {
    var结果=(等待消息控制器
    .CreateMessage(新输入模型{Message=“Hello”})).Value;
    }
    }
    
    创意2

    使用HttpClient向控制器发出http请求。这里有2个问题。A) 不确定如何在DI容器中注册
    HttpClient
    ,这样所有必需的身份验证cookie将自动添加到每个调用中;B) 从性能角度来看,可能不是理想的解决方案,因为呼叫将离开服务器应用程序(在blazor页面中),并返回到同一应用程序(在controller中)

    怎么走?还有其他更好的办法吗?我的想法中遗漏了什么