为啥 Asp.Net Core Kestrel 服务器向 Ngrok 返回 404 并且控制器永远不会被调用?
Posted
技术标签:
【中文标题】为啥 Asp.Net Core Kestrel 服务器向 Ngrok 返回 404 并且控制器永远不会被调用?【英文标题】:Why is Asp.Net Core Kestrel server returns 404 to Ngrok and Controller is never gets called?为什么 Asp.Net Core Kestrel 服务器向 Ngrok 返回 404 并且控制器永远不会被调用? 【发布时间】:2021-03-07 16:57:00 【问题描述】:几天来,我正在尝试运行一个简单的 asp.net 核心应用程序,并为 Telegram bot 设置 webhook。它在 Mac 上运行,带有 Kestrel 服务器,Ngrok 在其上用于将 https 代理到 webhook。目前它向 Ngrok 返回 404,我在控制台中也看到 404。任何帮助表示赞赏。
我尝试了这条线的各种修改
./ngrok http http://localhost:5000 -host-header=localhost:5000
我是 Asp.Net Core 的初学者。这是我应用的核心部分:
[Route("/")]
[ApiController]
public class UpdateController : ControllerBase
[HttpPost]
public async Task<OkResult> Post([FromBody]Update update)
这个永远不会被调用。 这是我的 Program.cs
public class Program
public static void Main(string[] args)
BuildWebHost(args).Run();
private static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
Startup.cs
public class Startup
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
Bot.GetBotClientAsync().Wait();
Bot.cs
public static class Bot
private static TelegramBotClient botClient;
private static List<Command> commandsList;
public static IReadOnlyList<Command> Commands => commandsList.AsReadOnly();
public static async Task<TelegramBotClient> GetBotClientAsync()
if (botClient != null)
return botClient;
commandsList = new List<Command>
new StartCommand()
;
botClient = new TelegramBotClient(AppSettings.Token);
await botClient.SetWebhookAsync(AppSettings.NGrokUrl);
return botClient;
设置 webhook 工作正常,Ngrok 接收请求,但来自 Kestrel 的答案始终是 404,并且永远不会调用 Post 方法。
控制台输出示例:
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[3]
Hosting starting
dbug: Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer[2]
Failed to locate the development https certificate at '(null)'.
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[4]
Hosting started
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[0]
Loaded hosting startup assembly eBot
Hosting environment: Development
Content root path: /Users/yuriibabii/Projects/eBot/eBot
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]
Connection id "0HM4GMVPJLPSF" received FIN.
dbug: Microsoft.AspNetCore.Server.Kestrel[39]
Connection id "0HM4GMVPJLPSF" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel[1]
Connection id "0HM4GMVPJLPSF" started.
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]
Connection id "0HM4GMVPJLPSF" sending FIN because: "The client closed the connection."
dbug: Microsoft.AspNetCore.Server.Kestrel[10]
Connection id "0HM4GMVPJLPSF" disconnecting.
dbug: Microsoft.AspNetCore.Server.Kestrel[2]
Connection id "0HM4GMVPJLPSF" stopped.
dbug: Microsoft.AspNetCore.Server.Kestrel[39]
Connection id "0HM4GMVPJLPSG" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel[1]
Connection id "0HM4GMVPJLPSG" started.
dbug: Microsoft.AspNetCore.Server.Kestrel[39]
Connection id "0HM4GMVPJLPSH" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel[1]
Connection id "0HM4GMVPJLPSH" started.
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5000/ application/json 375
dbug: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[0]
Wildcard detected, all requests with hosts will be allowed.
trce: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[2]
All hosts are allowed.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM4GMVPJLPSH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 45.4537ms 404
dbug: Microsoft.AspNetCore.Server.Kestrel[25]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000001": started reading request body.
dbug: Microsoft.AspNetCore.Server.Kestrel[26]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000001": done reading request body.
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost:5000/
trce: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[2]
All hosts are allowed.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM4GMVPJLPSG" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 9.3331ms 404
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5000/ application/json 375
trce: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[2]
All hosts are allowed.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM4GMVPJLPSH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 10.7676ms 404
dbug: Microsoft.AspNetCore.Server.Kestrel[25]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000002": started reading request body.
dbug: Microsoft.AspNetCore.Server.Kestrel[26]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000002": done reading request body.
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5000/ application/json 375
trce: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[2]
All hosts are allowed.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM4GMVPJLPSH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 8.5738ms 404
dbug: Microsoft.AspNetCore.Server.Kestrel[25]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000003": started reading request body.
dbug: Microsoft.AspNetCore.Server.Kestrel[26]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000003": done reading request body.
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5000/ application/json 375
trce: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[2]
All hosts are allowed.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM4GMVPJLPSH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 8.8111ms 404
dbug: Microsoft.AspNetCore.Server.Kestrel[25]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000004": started reading request body.
dbug: Microsoft.AspNetCore.Server.Kestrel[26]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000004": done reading request body.
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5000/ application/json 375
trce: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[2]
All hosts are allowed.
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM4GMVPJLPSH" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 9.6591ms 404
dbug: Microsoft.AspNetCore.Server.Kestrel[25]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000005": started reading request body.
dbug: Microsoft.AspNetCore.Server.Kestrel[26]
Connection id "0HM4GMVPJLPSH", Request id "0HM4GMVPJLPSH:00000005": done reading request body.
【问题讨论】:
【参考方案1】:您是否发布了所有的 Startup 课程? 我没有看到任何必须有 services.AddMvc().AddMvcOptions() 行的 ConfigureServices 方法,也没有在 Configure 方法中看到 app.UseMvc() 行。
我不太确定,但我一直认为您需要这两行来启用控制器。
尝试以这种方式更改您的 Startup 类:
public class Startup
public void ConfigureServices(IServiceCollection services)
services.AddMvc().AddMvcOptions();
services.AddControllersWithViews();
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseMvc();
Bot.GetBotClientAsync().Wait();
【讨论】:
它确实奏效了!谢谢你。但是我不得不在代码中添加几行,因此我发布了一个新答案。【参考方案2】:对@PiGi78 的答案进行了一些修改,它确实有效。这是最终的解决方案:
public class Startup
public void ConfigureServices(IServiceCollection services)
services.AddMvc().AddMvcOptions(ApplyMvcOptions);
services.AddControllersWithViews();
services.AddControllers().AddNewtonsoftJson();
private void ApplyMvcOptions(MvcOptions options)
options.EnableEndpointRouting = false;
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseMvc();
Bot.GetBotClientAsync().Wait();
@PiGi78 非常感谢!
【讨论】:
以上是关于为啥 Asp.Net Core Kestrel 服务器向 Ngrok 返回 404 并且控制器永远不会被调用?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解
为 HTTPS 配置 ASP.NET Core 2.0 Kestrel