ASP.NET Core 2.0 SignalR部署IIS遇negotiate接口404问题求助
我之前踩过和你几乎一模一样的坑!结合你用的ASP.NET Core 2.0 + SignalR 1.0.0-preview1-final这个特殊版本组合,给你分享几个亲测有效的排查和解决步骤:
先确认IIS的ASP.NET Core模块和Runtime是否匹配
Win7或者旧版Windows Server默认没有ASP.NET Core的IIS代理模块,你需要安装和ASP.NET Core 2.0对应的**.NET Core 2.0 Runtime Hosting Bundle**——这个包会自动配置IIS的反向代理模块,确保请求能转发到Kestrel。安装后记得重启IIS,另外用dotnet --info检查服务器上的Runtime版本和本地开发环境是否一致,版本不匹配很容易出各种奇怪问题。检查SignalR路由注册顺序
因为你用的是SignalR预览版1,路由注册的位置很关键!一定要在Startup.cs的Configure方法里,把app.UseSignalR()放在app.UseMvc()之前,比如:public void Configure(IApplicationBuilder app) { // 先注册SignalR路由 app.UseSignalR(routes => { routes.MapHub<NotificationHub>("/notification"); }); // 再注册MVC路由 app.UseMvc(); }如果顺序反了,MVC可能会拦截掉SignalR的negotiate请求,导致404。
核对IIS应用程序池的核心设置
这是最容易忽略的点:- 应用程序池的**.NET CLR版本必须设为「无托管代码」**,因为ASP.NET Core是自托管的,IIS只做反向代理,不需要托管CLR。
- 确保应用程序池的身份(比如ApplicationPoolIdentity)有站点根目录的读写权限——如果权限不够,Kestrel启动失败,自然处理不了请求。
验证web.config的反向代理配置
部署后生成的web.config是关键,检查aspNetCore节点的配置是否正确:<aspNetCore processPath="dotnet" arguments=".\YourApp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="OutOfProcess" />我建议暂时把
stdoutLogEnabled设为true,然后查看站点根目录下logs文件夹里的日志——这里面会有Kestrel启动和请求处理的详细错误,比如Hub是否加载成功、路由是否注册正确,比IIS的错误提示有用得多。另外,预览版SignalR对OutOfProcess托管模式的兼容性更好,如果你之前用的是InProcess可以改成OutOfProcess试试。检查IIS请求筛选规则
有时候IIS会默认阻止某些请求类型或路径:- 进入站点的「请求筛选」功能,确保POST方法是允许的(negotiate请求是POST)。
- 检查URL规则里有没有拒绝
/notification/*这类路径的设置,有的话删掉。
匹配前后端SignalR版本
预览版的SignalR客户端和服务端版本必须严格对应!你前端用的@aspnet/signalr包版本必须是1.0.0-preview1-final,不能用正式版或者其他预览版,版本不匹配也会导致negotiate请求失败。
如果以上步骤都试过还是不行,建议给Kestrel开启详细日志,在Program.cs里添加日志配置:
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .ConfigureLogging(logging => { logging.AddConsole(); logging.SetMinimumLevel(LogLevel.Debug); }) .Build();
然后查看stdout日志,里面应该会有更具体的错误线索,比如是不是某个中间件拦截了请求,或者Hub的依赖注入出了问题。
内容的提问来源于stack exchange,提问作者Humbertda

