【问题标题】:Blazor WebAssembly App - API call from browser - Sorry, there's nothing at this addressBlazor WebAssembly 应用程序 - 来自浏览器的 API 调用 - 抱歉,此地址没有任何内容
【发布时间】:2021-05-08 21:47:03
【问题描述】:

更新:

在 Github ASP.NET Core 项目上创建了一个问题:

https://github.com/dotnet/aspnetcore/issues/32522

原文:

使用 Microsoft Visual Studio 2019 版本 16.9.4 创建了一个新的 Blazor WebAssembly 应用,其中托管了 Target Framework .NET 5.0 和 ASP.NET Core。

问题是,如果我在网站发布到 Azure Web 应用程序时从浏览器调用 API,我会收到如下错误响应:

抱歉,这个地址什么都没有。

如果我使用“空缓存和硬重新加载”发出请求,一切都会按预期工作。

请求始终在 localhost 上工作。

不限于通过 API 加载的图像,JSON response 的结果相同。

我如何告诉Blazor 不要使用/忽略包含/api/ 的网址的路由?

我已经阅读了有关ASP.NET Core Blazor routing 的信息,但在那里没有找到任何内容。

https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-5.0

错误信息来自App.razor文件:

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>
<MatPortalHost></MatPortalHost>

如果我在App.razor 中使用默认值,结果相同:

<Found Context="routeData">
    <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
        <NotAuthorized>
            @if (!context.User.Identity.IsAuthenticated)
            {
                <RedirectToLogin />
            }
            else
            {
                <p>You are not authorized to access this resource.</p>
            }
        </NotAuthorized>
    </AuthorizeRouteView>
</Found>

图像控制器:

[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ImagesController : ControllerBase
{
    private readonly ApplicationDbContext _context;

    public ImagesController(ApplicationDbContext context)
    {
        _context = context;
    }

    [HttpGet("{id}/file")]
    [AllowAnonymous]
    public async Task<ActionResult> GetImageDataFile(int id)
    {
        var image = await _context.Images.FindAsync(id);

        if (image == null)
        {
            return NotFound();
        }

        return File(image.Data, image.ContentType);
    }

Program.csBlazor.Client

namespace Blazor.Client
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");

            builder.Services.AddHttpClient("Blazor.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
                .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

            builder.Services.AddHttpClient<ImagesHttpClient>(client =>
                client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
                .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

            builder.Services.AddHttpClient<PostsAnonymousHttpClient>(client =>
                client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

            // Supply HttpClient instances that include access tokens when making requests to the server project
            builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("Blazor.ServerAPI"));

            builder.Services.AddApiAuthorization();

            builder.Services.AddMatBlazor();

            await builder.Build().RunAsync();
        }
    }
}

Startup.cs for Blazor.Server,完全没有修改:

namespace Blazor.Server
{
    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.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddDatabaseDeveloperPageExceptionFilter();

            services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

            services.AddAuthentication()
                .AddIdentityServerJwt();

            services.AddControllersWithViews();
            services.AddRazorPages();
        }

        // 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();
                app.UseMigrationsEndPoint();
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseIdentityServer();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapControllers();
                endpoints.MapFallbackToFile("index.html");
            });
        }
    }
}

发布配置如下所示:

【问题讨论】:

  • @BrianParker 完成,但我不确定这会有所帮助。我根本没有修改Startup.cs,只要Blazor 没有被加载,API 控制器就可以工作。 Blazor 客户端也不应使用 HTTP 客户端配置,请求应直接发送到服务器并返回响应,而不需要 Blazor 干预。
  • 我想帮忙。这很奇怪。它不会发生在本地主机上。嗯,邮递员可以可靠地击中它吗?
  • @BrianParker 非常感谢,我无意无礼。更正它不会发生在本地主机上。邮递员工作没有问题。我在尝试在浏览器中加载 /.well-known/openid-configuration/_framework/blazor.boot.json 时也遇到了同样的错误。
  • @BrianParker 我不这么认为,如果没有使用 endpoints.MapControllers();,该请求将无法与 Postman 一起使用或使用“空缓存和硬重新加载”。我同意托管配置,但我不知道它可能是什么。最好我想告诉 Blazor 始终让对 /api/* 的请求在没有 Blazor 路由干预的情况下通过。
  • 是的,我一读给自己听就删除了,呵呵。试过其他浏览器吗?

标签: c# asp.net-core asp.net-web-api blazor blazor-webassembly


【解决方案1】:

调试起来确实很痛苦,但我最终发现了问题。

TLDR

Blazor\Client\wwwroot\index.html中删除以下行:

<script>navigator.serviceWorker.register('service-worker.js');</script>

原文:

为了有某种开始,我必须在本地重现错误。我通过将我的应用程序发布到本地 IIS 而不是 IIS Express 来做到这一点。 certs 和 LocalDB 存在一些问题,但一段时间后我能够在本地重现错误。

Blazor WebAssembly App with Individual Accounts and ASP.NET Core Hosted - IIS - SQLLocalDB 15.0 The specified resource language ID cannot be found

然后我尝试创建一个新应用程序以查看那里是否存在错误。在一个新的应用程序中,一切都按预期工作。然后我尝试退回到Git,看看何时引入了错误。我最终到达了Initial commit,但错误仍然存​​在。

为了找到我第一次尝试使用 WinMerge 比较文件夹的实际错误,但为了使其正常工作,我必须为项目命名相同,因为每个 namespace 都会显示差异。

幸运的是,Meld 在比较文件和文件夹时可以忽略特定的单词。我在 Meld Preferences 下添加了两个与我想忽略的命名空间匹配的文本过滤器,然后比较结果。

https://stackoverflow.com/a/46162831/3850405

现在除了Client\wwwroot\ 文件夹外,几乎所有内容都相同。看着index.html我发现了很大的不同:

在创建应用程序时,由于上面的serviceWorker,我必须检查Progressive Web Application

当我删除该行时,一切都开始按预期工作。

<script>navigator.serviceWorker.register('service-worker.js');</script>

然后我尝试使用 Progressive Web Application 设置创建一个新项目,并使用以下设置将其部署到我的本地 IIS:

加载网站后,我无法在没有看到Sorry, there's nothing at this address. 的情况下访问https://localhost/_framework/blazor.boot.json

如果您想继续使用 Progressive Web ApplicationService worker,您可以编辑 service-worker.published.js 并更新 shouldServeIndexHtml 以强制将 URL 像这样在服务器上呈现:

&& !event.request.url.includes('/api/')

【讨论】:

  • 不错的答案,但最后一个技巧并没有帮助我解决这个烦人的问题。我不明白,因为这应该可以解决它。
【解决方案2】:

你检查过你的appSetting和你的restApi的url吗?可能你的rest api的url还是localhost。你必须把它改成你的服务器发布的地址

【讨论】:

  • 否 - 可以在 cmets 中看到 url。查看我的答案以了解修复它的原因。原来是Progressive Web Application和包含的ServiceWorker
猜你喜欢
  • 2022-07-19
  • 2022-11-28
  • 2022-07-23
  • 1970-01-01
  • 2022-01-15
  • 2020-02-10
  • 2016-05-02
  • 1970-01-01
  • 2021-02-25
相关资源
最近更新 更多