为什么IHttpContextAccessor总是在Blazor服务器端获取空IP



我使用的SDK是5.0.100-rc.2.20479.15。

目标框架也是.Net 5。

这是我在startup.cs:中的代码

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();
        }
    }
}

我把它发布到服务器计算机上,IP总是返回null。

我的程序需要提交一份表格。该表格每天只允许同一个人提交一次(没有帐户(。

所以我需要获得IP,并用一天的DateTimeOffset设置一个IMemoryCache

尽管如此,存储IP地址并不是解决我的功能的完美方法,但我似乎只能这样做。

Blazor服务器应用程序的服务器端通过SignalR而不是HTTP与前端(浏览器(通信。因此,HttpContext对象在Blazor服务器应用程序中不可用,除非是对应用程序的初始请求,该请求始终是HTTP请求。这是您可以访问HttpContext的唯一机会。请注意,_Host.cshtml文件是一个Razor-Page文件,因此您可以在其中放入一些直接访问HttpContext的代码,并从HttpContext中获取您想要读取的任何数据,例如远程IP等。然后,您可以将检索到的数据作为_Host.cshtml中组件标记帮助程序的参数传递给Blazor SPA。在应用程序组件的OnInitialized生命周期方法中添加代码以获取数据,例如,定义一个获取当前用户远程IP地址的属性。然后,您可以将这些数据存储在本地存储器中,以便以后使用

警告:AS@enet评论表明,这不是Blazor 中建议的解决方法

如果它能帮助任何人。。。以下是我对@Melon NG建议的解读

在_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;
            
        }
    }
}

RememberMe

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>

在Startup.cs 中配置服务

public void ConfigureServices(IServiceCollection services)
{
...
//services.AddSingleton<IRememberMe, RememberMe>();
services.AddScoped<IRememberMe, RememberMe>();
...
}

相关内容

  • 没有找到相关文章

最新更新