与 asp.net 应用程序和子文件夹协商时出现 SignalR 错误 404
SignalR error 404 on negotiate with asp.net application and subfolder
我正在使用 ASP.NET Core 3.1,SignalR 3.1.9:
- Microsoft.AspNetCore.SignalR.Common 3.1.9
- Microsoft.AspNetCore.SignalR.Core 1.1.0
- Microsoft.AspNetCore.SignalR.Protocols.Json3.1.9
我正在使用 Javscript 客户端 v3.1.9(libman.json 文件):
{
"provider": "unpkg",
"library": "@microsoft/signalr@3.1.9",
"destination": "wwwroot/lib/signalr/",
"files": [
"dist/browser/signalr.js",
"dist/browser/signalr.min.js"
]
}
在我的网络服务器上,根 (example.com) 被 Wordpress 用作前端。 Wordpress 允许在 web.config 中对 /core 进行一些修改,并且网站加载正确 100%。
为了托管我的 .NET Core 应用程序,我创建了一个指向子文件夹 core 的应用程序(示例。com/core)。我不知道这是否重要,但我所有的控制器都在“app”区域下(示例。com/core/app)。
我声明了一个新的 Hub:
public class NotificationsHub : Hub
{
private readonly IMainDataService _data;
private readonly ILogger<NotificationsHub> _logger;
public NotificationsHub(IMainDataService data, ILoggerFactory loggerFactory)
{
this._data = data;
this._logger = loggerFactory.CreateLogger<NotificationsHub>();
}
public async Task SendFriendNotification(Guid newFriendId, Guid currentUserId)
{
var currentUser = await this._data.GetUserByIdAsync(currentUserId);
var notificationRecipientId = newFriendId.ToString();
await Clients.User(notificationRecipientId).SendAsync("FriendRequestReceived", newFriendId, currentUserId, currentUser.FirstName, currentUser.LastName);
}
这是我的Startup.cs(缩写为基本内容):
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.ConsentCookie.Expiration = TimeSpan.FromDays(365);
});
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C");
services.AddControllersWithViews()
.AddMvcLocalization()
.AddMicrosoftIdentityUI();
services.AddRazorPages();
services.AddSignalR();
services.AddRouting();
services.AddOptions();
services.Configure<OpenIdConnectOptions>(Configuration.GetSection("AzureAdB2C"));
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.IsEssential = true;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
if ((env.IsDevelopment() || env.IsStaging() || env.IsProduction()) && !env.IsEnvironment("Localhost"))
{
app.UsePathBase("/core");
}
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Map}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{area=App}/{controller=Map}/{action=Index}"
);
endpoints.MapControllerRoute(
name: "profile",
pattern: "{area=App}/{controller=Profile}/{action=Index}/{id?}"
);
endpoints.MapRazorPages();
endpoints.MapDbLocalizationAdminUI();
endpoints.MapDbLocalizationClientsideProvider();
if (env.EnvironmentName == "Localhost")
{
endpoints.MapHub<NotificationsHub>("/notificationshub");
}
else
{
endpoints.MapHub<NotificationsHub>("/core/notificationshub");
}
});
}
在本地,因为我直接 运行 我的 .NET Core 应用在根目录下,没有问题。但是当我部署到Dev/Staging/Prod,使用子文件夹/core时,我总是在以下URL上得到错误404:https://www.example.com/core/notificationshub/negotiate?negotiateVersion=1
我也试过:
- https://www.example.com/notificationshub/negotiate?negotiateVersion=1
- https://www.example.com/notificationshub/
- https://www.example.com/core/notificationshub/
在这两种情况下,我都会收到 404 异常。在 F12 控制台中,404 始终跟在以下行之后:
Error: Failed to complete negotiation with the server: Error: Not Found
Error: Failed to start the connection: Error: Not Found
Error: Not Found
上面的第 3 行指向我的 JavaScript 客户:
"use strict";
var currentUrl = window.location.href;
var basePath = '';
if (currentUrl.includes("/core") == true) {
basePath = '/core'
}
var connection = new signalR.HubConnectionBuilder().withUrl(basePath + "/notificationshub").build();
connection.start().catch(function (err) {
return console.error(err.toString());
});
错误在 connection.start() 行。
我试图在路径前用 ../ 修改上一行,但没有帮助:
let connection = new signalR.HubConnectionBuilder().withUrl("../" + basePath + "/notificationshub").build();
知道我是否遗漏了什么吗?让 SignalR 在根 URL 上工作似乎很简单,但如果有子文件夹则不然。
您似乎正在将您的应用映射到“/core”,然后将您的中心映射到“/core/hub”。所以你的集线器实际上是在“/core/core/hub”。
我正在使用 ASP.NET Core 3.1,SignalR 3.1.9:
- Microsoft.AspNetCore.SignalR.Common 3.1.9
- Microsoft.AspNetCore.SignalR.Core 1.1.0
- Microsoft.AspNetCore.SignalR.Protocols.Json3.1.9
我正在使用 Javscript 客户端 v3.1.9(libman.json 文件):
{
"provider": "unpkg",
"library": "@microsoft/signalr@3.1.9",
"destination": "wwwroot/lib/signalr/",
"files": [
"dist/browser/signalr.js",
"dist/browser/signalr.min.js"
]
}
在我的网络服务器上,根 (example.com) 被 Wordpress 用作前端。 Wordpress 允许在 web.config 中对 /core 进行一些修改,并且网站加载正确 100%。
为了托管我的 .NET Core 应用程序,我创建了一个指向子文件夹 core 的应用程序(示例。com/core)。我不知道这是否重要,但我所有的控制器都在“app”区域下(示例。com/core/app)。
我声明了一个新的 Hub:
public class NotificationsHub : Hub
{
private readonly IMainDataService _data;
private readonly ILogger<NotificationsHub> _logger;
public NotificationsHub(IMainDataService data, ILoggerFactory loggerFactory)
{
this._data = data;
this._logger = loggerFactory.CreateLogger<NotificationsHub>();
}
public async Task SendFriendNotification(Guid newFriendId, Guid currentUserId)
{
var currentUser = await this._data.GetUserByIdAsync(currentUserId);
var notificationRecipientId = newFriendId.ToString();
await Clients.User(notificationRecipientId).SendAsync("FriendRequestReceived", newFriendId, currentUserId, currentUser.FirstName, currentUser.LastName);
}
这是我的Startup.cs(缩写为基本内容):
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.ConsentCookie.Expiration = TimeSpan.FromDays(365);
});
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C");
services.AddControllersWithViews()
.AddMvcLocalization()
.AddMicrosoftIdentityUI();
services.AddRazorPages();
services.AddSignalR();
services.AddRouting();
services.AddOptions();
services.Configure<OpenIdConnectOptions>(Configuration.GetSection("AzureAdB2C"));
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.IsEssential = true;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
if ((env.IsDevelopment() || env.IsStaging() || env.IsProduction()) && !env.IsEnvironment("Localhost"))
{
app.UsePathBase("/core");
}
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Map}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{area=App}/{controller=Map}/{action=Index}"
);
endpoints.MapControllerRoute(
name: "profile",
pattern: "{area=App}/{controller=Profile}/{action=Index}/{id?}"
);
endpoints.MapRazorPages();
endpoints.MapDbLocalizationAdminUI();
endpoints.MapDbLocalizationClientsideProvider();
if (env.EnvironmentName == "Localhost")
{
endpoints.MapHub<NotificationsHub>("/notificationshub");
}
else
{
endpoints.MapHub<NotificationsHub>("/core/notificationshub");
}
});
}
在本地,因为我直接 运行 我的 .NET Core 应用在根目录下,没有问题。但是当我部署到Dev/Staging/Prod,使用子文件夹/core时,我总是在以下URL上得到错误404:https://www.example.com/core/notificationshub/negotiate?negotiateVersion=1
我也试过:
- https://www.example.com/notificationshub/negotiate?negotiateVersion=1
- https://www.example.com/notificationshub/
- https://www.example.com/core/notificationshub/
在这两种情况下,我都会收到 404 异常。在 F12 控制台中,404 始终跟在以下行之后:
Error: Failed to complete negotiation with the server: Error: Not Found
Error: Failed to start the connection: Error: Not Found
Error: Not Found
上面的第 3 行指向我的 JavaScript 客户:
"use strict";
var currentUrl = window.location.href;
var basePath = '';
if (currentUrl.includes("/core") == true) {
basePath = '/core'
}
var connection = new signalR.HubConnectionBuilder().withUrl(basePath + "/notificationshub").build();
connection.start().catch(function (err) {
return console.error(err.toString());
});
错误在 connection.start() 行。
我试图在路径前用 ../ 修改上一行,但没有帮助:
let connection = new signalR.HubConnectionBuilder().withUrl("../" + basePath + "/notificationshub").build();
知道我是否遗漏了什么吗?让 SignalR 在根 URL 上工作似乎很简单,但如果有子文件夹则不然。
您似乎正在将您的应用映射到“/core”,然后将您的中心映射到“/core/hub”。所以你的集线器实际上是在“/core/core/hub”。