如何在服务器端 Blazor 中使用 HttpContext 对象来检索有关用户、用户代理的信息
Posted
技术标签:
【中文标题】如何在服务器端 Blazor 中使用 HttpContext 对象来检索有关用户、用户代理的信息【英文标题】:How to use the HttpContext object in server-side Blazor to retrieve information about the user, user agent 【发布时间】:2020-04-19 15:23:50 【问题描述】:IP 地址等。很多时候,当用户询问如何在 Server Blazor 应用程序中执行此操作时,他们要么被告知这是不可能的,要么有时提供了采用 JSInterop 的部分解决方案。但是可以在不诉诸 JSInterop 的情况下完成吗?这是答案...
【问题讨论】:
【参考方案1】:HttpContext
对象不能与 Blazor Server 应用程序一起使用的虚构已经在 *** 上传播了很长时间,现在是时候取消它了。
当 WebSocket 连接运行时,HttpContext
确实不可用,但必须清楚:当您键入 url 并按 enter 按钮时,与服务器端 Blazor 应用程序的连接是HTTP 连接,而不是 WebSocket 连接。
因此,您的应用可以访问和使用HttpContext
,就像在 Razor Pages 应用或 MVC 应用中使用它一样,包括获取用户代理和 IP 地址。以下代码示例演示了如何使用HttpContext
本地获取用户代理和IP 地址,而不使用应作为最后手段使用的JSInterop
,并将提取的值传递给App
组件。
-
将文件添加到
Pages
文件夹并将其命名为_Host.cshtml.cs
。
将此代码添加到文件中:
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:
// https://***.com/questions/35441521/remoteipaddress-is-always-null
// https://***.com/questions/28664686/how-do-i-get-client-ip-address-in-asp-net-core
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;
-
将以下行添加到您的
Host.cshthml
页面(在页面顶部靠近使用和其他内容的地方):
@model HostModel
-
在
App
组件中,定义两个参数属性,它们将获取并存储从位于_Host.cshtml
的组件标签中传递给它的用户代理和IP 地址。
App.razor:
<p>UserAgent: @UserAgent</p>
<p>IPAddress: @IPAddress</p>
@code
[Parameter]
public string UserAgent get; set;
[Parameter]
public string IPAddress get; set;
-
在
_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>
-
将
services.AddHttpContextAccessor();
添加到Startup
的ConfigureServices
方法以启用对HttpContext 的访问。
就是这样。您也可以将 Identity UI
添加到您的 Blazor 服务器应用程序中,并在用户通过身份验证后应用上面显示的相同过程从 HttpContext
中提取声明主体(这样做仅用于学习目的,因为您应该使用AuthenticationStateProvider)。
Here's also a link关于当前主题的官方文档。
【讨论】:
如果没有 HttpContextAccessor 我本可以做到的:github.com/aspnet/AspNetCore/issues/… 是否有 .net core 版本可以让您的指令编译? 所以我想我一定在这里遗漏了一些东西。您上面推荐的代码似乎确实可以工作并获得所需的内容,但是您如何从 Blazor SSA 中的其他 razor 组件或服务访问 _Host.cshtml.cs 中的这些新属性? 您可以将它们保存在本地存储中,组件和服务可以从中读取它们。 参见我上面的第一条评论,我说不需要 HttpContextAccessor,因为您可以直接访问作为 ModelPage 对象的属性提供的 HttpContext【参考方案2】:在您的启动 > ConfigureServices 中:
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();
【讨论】:
通过重定向来获取用户代理似乎不直观... 在本例中,我无法查看 HttpContext 数据的位置。 在花了一天时间试图让批准的解决方案发挥作用后,我明白为什么会建议这样做。请参阅我上面的评论。以上是关于如何在服务器端 Blazor 中使用 HttpContext 对象来检索有关用户、用户代理的信息的主要内容,如果未能解决你的问题,请参考以下文章
如何在服务器端 Blazor 中访问 HttpContext?
如何在服务器端 Blazor 组件中访问实体框架 DbContext 实体