如何在服务器端 Blazor 中使用 HttpContext 对象来检索有关用户、用户代理的信息

How to use the HttpContext object in server-side Blazor to retrieve information about the user, user agent

IP 地址等。很多时候,当用户询问如何在 Server Blazor 应用程序中执行此操作时,他们要么被告知这是不可能的,要么有时会提供使用 JSInterop 的部分解决方案。但是可以不借助 JSInterop 来完成吗?这是答案...

HttpContext 对象不能与 Blazor Server App 一起使用的谣言已经在 Whosebug 上传播了很长时间,是时候停止它了。

HttpContext确实在运行WebSocket连接时不可用,但必须清楚:当您键入url并按下回车键时,连接到您的服务器端 Blazor 应用是 HTTP 连接,而不是 WebSocket 连接。

因此,您的应用可以像在 Razor Pages 应用或 MVC 应用中一样访问和使用 HttpContext,包括获取用户代理和 IP 地址。以下代码示例演示了如何使用 HttpContext 本地获取用户代理和 IP 地址,而不使用应作为最后手段使用的 JSInterop,并将提取的值传递给 App 组件.

  1. 将文件添加到 Pages 文件夹并将其命名为 _Host.cshtml.cs
  2. 将此代码添加到文件中:
public class HostModel: PageModel
{
    private readonly IHttpContextAccessor _httpContextAccssor;
    
    public HttpContextFeatureModel(IHttpContextAccessor httpContextAccssor)
    {
        _httpContextAccssor = httpContextAccssor;    
    }

    public string UserAgent { get; set; }
    public string IPAddress { get; set; }
    
    // The following links may be useful for getting the IP Adress:
    // 
    // 
    
    public void OnGet()
    {
        UserAgent = _httpContextAccssor.HttpContext.Request.Headers["User-Agent"];
        // Note that the RemoteIpAddress property returns an IPAdrress object 
        // which you can query to get required information. Here, however, we pass 
        // its string representation
        IPAddress = _httpContextAccssor.HttpContext.Connection.RemoteIpAddress.ToString();  
    }
}

您可能需要以下一种或多种用法:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
  1. 将以下行添加到您的 Host.cshthml 页面(在页面顶部靠近 usings 和那些东西的地方):
@model HostModel
  1. App 组件中,定义两个参数属性,它们将获取并存储从位于 _Host.cshtml.
  2. 中的组件标记传递给它的用户代理和 IP 地址

App.razor:

<p>UserAgent: @UserAgent</p>
<p>IPAddress: @IPAddress</p>

@code
{
    [Parameter]
    public string UserAgent { get; set; }

    [Parameter]
    public string IPAddress { get; set; }
}
  1. _Host.cshtml中像这样更新组件标签(这种方法现在已经过时了):
<app>
    <component type="typeof(App)" render-mode="ServerPrerendered" param-UserAgent="@Model.UserAgent" param-IPAddress="@Model.IPAddress" />
</app>

在当前的 Blazor 服务器端应用程序中,可以这样做:

<div>
    @(await Html.RenderComponentAsync<App>(RenderMode.Server, new { IPAddress = Model.IPAddress, UserAgent = Model.UserAgent }))
</div>
  1. services.AddHttpContextAccessor(); 添加到 StartupConfigureServices 方法以启用对 HttpContext 的访问。

就是这样。您也可以将 Identity UI 添加到您的 Blazor Server 应用程序,并在用户通过身份验证后应用上面显示的相同过程从 HttpContext 中提取声明主体(这样做仅出于学习目的,因为您应该改用 AuthenticationStateProvider)。

Here's also a link 到关于当前主题的官方文档。

在您的启动 > 配置服务中:

 services.AddControllers();

在您的启动>配置中:

  app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });

添加一个文件夹名称吧:Controllers

添加控制器名称:InitController

添加这样的方法:

   [Route("[controller]/[action]")]
    public class InitController : Controller
    {
    public IActionResult UserInfo(string redirectUri)
        {
           var request = Request.HttpContext;


            return LocalRedirect(redirectUri);
        }
}

在请求变量中,所有数据都存在

最后从页面或组件重定向用户使用此代码:

@inject NavigationManager NavigationManager

@code{
     protected override Task OnInitializedAsync ()
        {       var uri = new Uri(NavigationManager.Uri)
            .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);

           var query = $"?redirectUri={Uri.EscapeDataString(uri)}";
          NavigationManager.NavigateTo("/Init/UserInfo" + query, forceLoad: true);
           StateHasChanged();

            return base.OnInitializedAsync();


        }
}