【发布时间】: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.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 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