ASP.NET 使用单独程序集中的启动类时遇到核心 MVC 问题



我创建了一个.NET Core MVC Web app。我将 Startup 类移动到一个单独的库项目中,并将 MVC 项目中的依赖项添加到库项目上。在第三个命令行应用程序中,我可以使用此启动类。在我更新 MVC 项目以使用库项目中的 Startup 类而不是 Web 项目中的默认 Startup 类后,Visual Studio 中的 Web 服务器会为我提供 404。

找不到此本地主机页面 找不到网址的网页:https://localhost:44323/HTTP 错误 404

我可以通过 Startup.ConfigureServices(( 中此块的末尾调试进程,但随后调试器只是停止(无例外(,浏览器显示 404 页面。我的操作中的断点永远不会触发。

services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});

下面是启动类。这基本上是直接从Visual Studio模板复制的,并添加了DoWebStuff属性,CustomerServiceCollectionExtensions和DeliveryStackServiceCollectionExtensions ConfigureContentstackRepository((调用,以及catchall路由(我只是在测试(。

namespace Customer.Core.Configuration
{
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Deliverystack.Contentstack.Core.Configuration;
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.
public void ConfigureServices(IServiceCollection services)
{
if (DoWebStuff)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// Microsoft.Extensions.DependencyInjection.AddMvc(services).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// IMPORTANT: First configure deserialization from JSON. 
CustomerServiceCollectionExtensions.ConfigureSerialization(services, Configuration);
// then Add ContenstackOptions (connection details), ContentstackClient, and IRepository. 
DeliverystackServiceCollectionExtensions.ConfigureContentstackRepository(
services,
Configuration);
}
public bool DoWebStuff { get; set; }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (DoWebStuff)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
"default",
"{*url}",
new {controller = "Home", action = "Index"});
});
//            app.UseMvc(routes =>
//            {
//                routes.MapRoute(
//                    name: "default",
//                    template: "{controller=Home}/{action=Index}/{id?}");
//            });
}
}
}
}

以下是我如何启动命令行工具,该工具适用于此 Startup 类:

namespace scratch
{
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting.Internal;
using Deliverystack.Contentstack.Core.Models;
using Deliverystack.Contentstack.Core.Repositories;
using Deliverystack.Core.Repositories;
using Contentstack.Core;
using Contentstack.Core.Models;
using Customer.Core.Configuration;
using Customer.Core.Models.Entries.DemoPage;
using Customer.Core.Models.Entries.DemoPage.DemoBlocks;
class Program
{
static void Main(string[] args)
{
HostingEnvironment env = new HostingEnvironment();
//TODO: env.ContentRootPath = Directory.GetCurrentDirectory();
//TODO: env.EnvironmentName = "Development";
IConfiguration configuration = new ConfigurationBuilder().AddJsonFile(
"appsettings.json",
optional: false,
reloadOnChange: true).Build();
Startup startup = new Startup(configuration); // this is in another project/assembly
startup.DoWebStuff = false; // can't add parameters to constructor
ServiceCollection serviceCollection = new ServiceCollection();
startup.ConfigureServices(serviceCollection);
using (var provider = serviceCollection.BuildServiceProvider())
{

这是我尝试共享到命令行和我们的应用程序的启动类:

namespace Customer.Core.Configuration
{
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Deliverystack.Contentstack.Core.Configuration;
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.
public void ConfigureServices(IServiceCollection services)
{
if (DoWebStuff)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// Microsoft.Extensions.DependencyInjection.AddMvc(services).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// IMPORTANT: First configure deserialization from JSON. 
CustomerServiceCollectionExtensions.ConfigureSerialization(services, Configuration);
// then Add ContenstackOptions (connection details), ContentstackClient, and IRepository. 
DeliverystackServiceCollectionExtensions.ConfigureContentstackRepository(
services,
Configuration);
}
public bool DoWebStuff { get; set; }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (DoWebStuff)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
"default",
"{*url}",
new {controller = "Home", action = "Index"});
});
}
}
}
}

在 ASP.NET Core MVC 应用中,是否有任何理由不能使用单独库中的启动类?为什么调试器似乎崩溃了?为什么在这种情况下我会得到 404?似乎 ASP.NET 已经崩溃了。我可以在哪里查找日志?

2020年5月25日更新:

我可能有更多的信息。我写了一个命令脚本(.cmd 文件(。

# C:Users<USERNAME>.dotnettoolscs.cmd
# build and run cs project
cd <Solution Directory>
dotnet clean
cd <Web Project Directory>
dotnet run

http://localhost:5000 重定向到 http://localhost 5001,浏览器显示ERR_SSL_PROTOCOL_ERROR,请单击 404。服务器显示:

info: Microsoft.AspNetCore.Server.Kestrel[17]
Connection id "0HM00F1LUUSI1" bad request data: "Invalid request line: 'x16x03x01x02x00x01x00x01xFCx03x035x8Bx83xE8xDBQxC7xA0t67TxA0xF7xECx8Ax9Cx8DfxE5`xF5xD1gx91xE7x00xA9x85xD8u$ xA9xC3x85x9D xF1>/)dx1A{x9AYxC7FxF58xA38'0xE3)xE7zx15xD8xDAcjxA8x00"xEAxEAx13x01x13x02x13x03xC0+xC0/xC0,xC00xCCxA9xCCxA8xC0x13xC0x14x00x9Cx00x9Dx00/x005x00x0A'"
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Invalid request line: 'x16x03x01x02x00x01x00x01xFCx03x035x8Bx83xE8xDBQxC7xA0t67TxA0xF7xECx8Ax9Cx8DfxE5`xF5xD1gx91xE7x00xA9x85xD8u$ xA9xC3x85x9D xF1>/)dx1A{x9AYxC7FxF58xA38'0xE3)xE7zx15xD8xDAcjxA8x00"xEAxEAx13x01x13x02x13x03xC0+xC0/xC0,xC00xCCxA9xCCxA8xC0x13xC0x14x00x9Cx00x9Dx00/x005x00x0A'
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.RejectRequestLine(Byte* requestLine, Int32 length)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.GetUnknownMethod(Byte* data, Int32 length, Int32& methodLength)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.ParseRequestLine(TRequestHandler handler, Byte* data, Int32 length)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.ParseRequestLine(TRequestHandler handler, ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler>.ParseRequestLine(TRequestHandler handler, ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TakeStartLine(ReadOnlySequence`1 buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.ParseRequest(ReadOnlySequence`1 buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)

调试显示 IsDevelopment(( 块的内容正在运行。

如果我评论应用程序。使用HttpsRedirection((:

dbug: HttpsConnectionAdapter[1]
Failed to authenticate HTTPS connection.
System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> System.ComponentModel.Win32Exception: An unknown error occurred while processing the certificate
--- End of inner exception stack trace ---
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)
dbug: HttpsConnectionAdapter[1]
Failed to authenticate HTTPS connection.
System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> System.ComponentModel.Win32Exception: An unknown error occurred while processing the certificate
--- End of inner exception stack trace ---
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET https://localhost:5001/
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 28.3224ms 404

所以我想问题是,这个 Web 服务器是否与 Visual Studio 使用的服务器相同(在这种情况下,原因可能相同(,以及如何禁用此尝试的 SSL 或其他安全内容。

我从来没有弄清楚这一点,但放弃了,因为我认为控制台和 Web 项目不应该使用相同的 Startup。控制台项目将需要一堆依赖项,它不应该只是禁用由启动启用的 Web 功能。必须有更好的方法来管理共享给两者的任何配置/代码。

相关内容

最新更新