Ing*_*and 5 c# asp.net-web-api asp.net-core blazor blazor-server-side
先决条件:
这是初始 blazor 页面、模型和初始控制器
@page "/fetchdata"
@attribute [Authorize]
@using BlazorApp2.Controllers
<button @onclick="@callController">Call controller</button>
@code {
private async Task callController()
{
}
}
Run Code Online (Sandbox Code Playgroud)
public class InputModel
{
[Required]
public string Message { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class MessageController : ControllerBase
{
[HttpPost("createMessage")]
public async Task<ActionResult<string>> CreateMessage(InputModel model)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
return $"{model.Message} {userId}";
}
}
Run Code Online (Sandbox Code Playgroud)
以“正常”方式(通过发送 http 请求)使用控制器几乎没有什么内置好处:自动授权;模型验证;填充 HttpContext 和 User 属性(以及其他属性)。
目标是在获取 Blazor 页面数据时重用控制器。
想法1
配置控制器并将其注入 Blazor 页面,其操作的调用方式与 http 请求期间的调用方式类似。不确定如何实现这一点以及这是否确实可行。向 DI 容器注册控制器不是问题 ( AddControllersAsServices())。但这不会在注入期间填充控制器HttpContext和User属性。控制器注入后获得的唯一方法(我知道)是在( ) 中HttpContext配置并将其注入到控制器中。但这也意味着当使用http请求访问控制器时,可以从注入的属性和控制器的属性中访问。是否有可能因此出现问题?该解决方案也不会在控制器中进行模型验证。同时,可以在从 Blazor 页面发送之前验证模型,但我不确定在这种情况下是否必须在控制器中手动重新验证它。IHttpContextAccessorStartupservices.AddHttpContextAccessor();HttpContextIHttpContextAccessorHttpContext
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class MessageController : ControllerBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MessageController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
[HttpPost("createMessage")]
public async Task<ActionResult<string>> CreateMessage(InputModel model)
{
var userId = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
return $"{model.Message} {userId}";
}
}
Run Code Online (Sandbox Code Playgroud)
@page "/fetchdata"
@using BlazorApp2.Controllers
@attribute [Authorize]
@inject MessageController MessageController;
<button @onclick="@callController">Call controller</button>
@code {
private async Task callController()
{
var result = (await MessageController
.CreateMessage(new InputModel {Message = "Hello"})).Value;
}
}
Run Code Online (Sandbox Code Playgroud)
想法2
使用 HttpClient 向控制器发出 http 请求。这里有2个问题。A) 不确定如何HttpClient在 DI 容器中注册,以便所有必需的身份验证 cookie 将自动添加到每次调用中;B) 从性能角度来看可能不是理想的解决方案,因为调用将离开服务器应用程序(在 blazor 页面中)并将返回到同一应用程序(在控制器中)。
走什么路?还有其他更好的办法吗?我的想法中错过了什么?
| 归档时间: |
|
| 查看次数: |
2552 次 |
| 最近记录: |