Asp.net core 为什么IHttpContextAccessor在Blazor服务器端总是获取空IP?
我使用的SDK是5.0.100-rc.2.20479.15 目标框架也是.NET5 以下是我在startup.cs中的代码:Asp.net core 为什么IHttpContextAccessor在Blazor服务器端总是获取空IP?,asp.net-core,.net-core,blazor,blazor-server-side,Asp.net Core,.net Core,Blazor,Blazor Server Side,我使用的SDK是5.0.100-rc.2.20479.15 目标框架也是.NET5 以下是我在startup.cs中的代码: using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpsPolicy; usi
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
namespace Sample
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
这是我在index.razor中的代码:
@page "/"
@inject IHttpContextAccessor httpContextAccessor
<h1>@IP</h1>
@code{
public string IP{get;set;}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
IP=httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString();
}
}
}
@page/“
@注入IHttpContextAccessor httpContextAccessor
@知识产权
@代码{
公共字符串IP{get;set;}
AfterRenderAsync(bool firstRender)上受保护的重写异步任务
{
if(firstRender)
{
IP=httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString();
}
}
}
我将其发布到服务器计算机,并且IP始终返回null
我的计划需要提交一份表格。该表格每天只能由同一个人提交一次(无账户)
因此,我需要获取IP并设置一个带有一天DateTimeOffset
的IMemoryCache
尽管如此,存储IP地址并不是解决我的功能的完美方法,但似乎我只能这样做。Blazor server App的服务器端通过信号器而不是HTTP与前端(浏览器)通信。因此,除了对应用程序的初始请求(始终是HTTP请求)之外,Blazor服务器应用程序中没有HttpContext对象。这是您可以访问HttpContext的唯一机会。请注意,_Host.cshtml文件是一个Razor页面文件,因此您可以在其中放入一些直接访问HttpContext的代码,并从HttpContext获取您想要读取的任何数据,例如远程IP等。然后,您可以将检索到的数据作为_Host.cshtml中存在的组件标记帮助器的参数传递给Blazor SPA。在应用程序组件的OnInitialized生命周期方法中添加代码以获取数据,例如定义一个获取当前用户远程IP地址的属性。然后,您可以将此数据存储在本地存储器中供以后使用 警告:@enet评论表明,在Blazor中,这不是推荐的方法 如果它能帮助任何人。。。以下是我对吴先生建议的解释 在_Host.cshtml.cs中
using AutoCheck.BlazorApp.Components;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace AutoCheck.BlazorApp.Pages
{
public class Host : PageModel
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IRememberMe _rememberMe;
public Host(IHttpContextAccessor httpContextAccessor, IRememberMe rememberMe)
{
_rememberMe = rememberMe;
_httpContextAccessor = httpContextAccessor;
}
public void OnGet()
{
_rememberMe.RemoteIpAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress;
}
}
}
记住
using System.Net;
namespace AutoCheck.BlazorApp.Components
{
public interface IRememberMe
{
public IPAddress RemoteIpAddress { get; set; }
}
public class RememberMe : IRememberMe
{
public IPAddress RemoteIpAddress { get; set; }
}
}
关于剃刀
@page "/About"
@inject IRememberMe RememberMe
<h3>About</h3>
<table class="table table-striped">
<thead>
<td>Item</td>
<td>Value</td>
</thead>
<tr>
<td>Remote IP</td>
<td>@RememberMe.RemoteIpAddress</td>
</tr>
</table>
@page”/About
@我记得我记得
关于
项目
价值
远程计算机
@RememberMe.RemoteIpAddress
在Startup.cs中的ConfigureServices中
public void ConfigureServices(IServiceCollection services)
{
...
//services.AddSingleton<IRememberMe, RememberMe>();
services.AddScoped<IRememberMe, RememberMe>();
...
}
public void配置服务(IServiceCollection服务)
{
...
//services.AddSingleton();
services.addScope();
...
}
我试图在startup.cs中添加一个作用域类来存储IP,并使用IHttpContextAccessor在_Host.cshtml中获取IP。但它仍然得到一个空IP。问题解决了,我应该将它添加到OnInitialized中,而不是添加到_Host.cshtml中。那么,为什么要注入IHttpContextAccessor呢?当您可以直接访问HttpContext时,为什么需要它?那么,您已经为此创建了一个单例服务,对吗?你打算为所有用户提供相同的IP地址吗?这不是向Blazor应用程序传递参数的方法。请参阅文档中的正确方法:@Mellon NG,请再次阅读您的问题:为什么IHttpContextAccessor在Blazor服务器端总是获取空IP?正如@enet正确指出的,它应该是services.addScope();以便捕获每个用户的IP地址。然而,正如链接所显示的,这可能根本不是正确的方法。由于我不确定这里的礼仪是否正确,我将更新答案,以包含一个警告。如果我需要做其他事情,请告诉我。