Blazor WebAssembly App-API从浏览器调用-抱歉,此地址没有任何内容 [英] Blazor WebAssembly App - API call from browser - Sorry, there's nothing at this address

查看:25
本文介绍了Blazor WebAssembly App-API从浏览器调用-抱歉,此地址没有任何内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:

创建了一个关于Github ASP.NET核心项目的问题:

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

原件:

使用托管了Target Framework.NET 5.0和ASP.NET Core的Microsoft Visual Studio 2019 16.9.4版创建了新的Blazor WebAssembly应用程序。

问题是,如果我在将站点发布到Azure Web应用程序时从浏览器进行API调用,则会得到如下错误响应:

很抱歉,此地址没有任何内容。

如果我使用";清空缓存并硬重新加载";发出请求,则一切都按预期进行。

请求始终在localhost工作。

并不局限于API加载的图片,JSON response结果相同。

如何告诉Blazor不要对包含/api/的URL使用/忽略路由?

我已阅读有关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>

ImagesController:

[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.cs对于Blazor.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对于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");
            });
        }
    }
}

发布配置如下:

推荐答案

这真的很难调试,但我最终发现了问题。

TLDR

BlazorClientwwwrootindex.html中删除以下行:

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

原件:

为了开始某种操作,我必须在本地重现错误。我是通过将我的应用程序发布到本地的IIS而不是IIS Express来做到这一点的。证书和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首选项下添加了两个文本筛选器,这两个筛选器与我想要忽略的名称空间匹配,然后比较结果。

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

现在,除了Clientwwwroot文件夹之外,几乎所有内容都是相同的。查看index.html,我注意到一个很大的差异:

创建应用程序时,由于上述serviceWorker,我一定选中了Progressive Web Application

当我删除该行时,一切都开始正常工作。

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

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

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

如果您希望继续使用Progressive Web ApplicationService worker,您可以编辑service-worker.published.js和更新shouldServeIndexHtml,以强制服务器呈现URL,如下所示:

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

这篇关于Blazor WebAssembly App-API从浏览器调用-抱歉,此地址没有任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆