将 Asp.net 核心应用拆分为视图和控制器,并在同一个 Domain:Port 中托管 [路由问题]

Splitting Asp.net Core app to Views and Controllers and Hosting in a same Domain:Port [Routing Problem]

我有一个 Asp.Net Core 应用程序,它集成了 ViewsControllers .该应用程序可以正常运行。但是,当我将应用程序的 ViewsControllers 分成两个 Asp.Net Core 应用程序时,它不能正常工作。视图像以前一样工作,但控制器不工作。

我遵循了

中提到的其中一项说明

我确实把控制器放到 API 目录中,像这样把视图放到主目录中

/Website
      /api
         /swagger
         /api.dll
         /api.exe
         /...
         /web.config
      /wwwroot 
      /front.dll
      /front.exe
      /...
      /web.config
  

当我点击 www.exampl.com/api/login 时,遇到以下错误:

500 - Internal server error. There is a problem with the resource you are looking for, and it cannot be displayed.

但是,当我点击 www.exampl.com/index 时,这是默认页面。它完美运行。

我在 IIS 中启用了浏览目录,但没有用。

我的控制器的路由如下:

namespace MyAppControllers
{
    [Route("[controller]")]
    [ApiController]
    public class loginController: ControllerBase
    ...

值得一提的是,我启用了登录 web.config 但没有检测到错误。

更新

我刚刚在一个单独的网站上测试了 Controllers,工作正常并且出现了 swagger

http://www.example.com:12345/swagger/index.html 

更新 2

Asp.Net 核心网站 API

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }
    app.UseSwagger();

    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });
    app.UseRouting();
    app.UseAuthorization();
    app.UseCors("mPolicy");
    app.Use((context, next) =>
    {
        context.Response.Headers["Access-Control-Allow-Origin"] = "*";
        return next.Invoke();
    });
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

更新 3

我已启用 Detailed Error,但我看到下面抛出错误

Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'aspNetCore

但是,当我尝试解释的解决方案时 here

500 - 内部错误 转换为 404 - 未找到

不管怎样,问题依然存在

您正在尝试提供 Asp.Net 核心不支持的体验。

当我们使用旧 Asp.Net (.Net Framework) 创建 Web 应用程序时,我们在 IIS 中托管此应用程序。因此在 IIS 中,您可以创建站点和子站点。它是这样工作的——IIS 拥有 443 个端口并将请求路由到具体 site/subsite.

IIS 是启动于 windows 并拥有所有 HTTP 流量的大型 Web 服务器。所有站点都在单独的域中开始(IIS 中的 AppPool)。通过 Pipeline 请求路由。

但是 Asp.Net CORE 使用了另一种方法。

当您使用 Asp.Net 核心时,每个应用程序都是一个小型 Web 服务器(非常简单,不像 IIS)。 每个应用程序启动并尝试获取端口。它不支持子站点。每个站点都是独立的,并从特定端口 443、444,445 等开始。

作为您的解决方案 link 作者建议使用 NGinx!为此你应该这样做:

  1. 在不同的端口上启动您的所有应用程序。 (例如 445 和 446)

  2. 在443端口启动NGinx(很重要。)模拟IIS体验。您应该拥有一个可以合并所有站点的应用程序。

  3. 为第一个和第二个站点设置 proxy_pass。它在 Nginx 配置文件中完成。像这样:

     Some nginx Configuration 
     location / {
         proxy_pass http://127.0.0.1:443; <-- Firs site as ROOT
     }
     location /api {
         proxy_pass http://127.0.0.1:444; <-- Second site as /api route
     }
    
     Other configurations.
    

另一种选择是使用 IIS 并在 IIS 中设置代理模式。它类似于 NGinx 设置。

所以,您正试图将所有文件放在子文件夹中。但是这是不正确的。子站点不必放在子文件夹中。它可以放在不同的文件夹中。 例如,一个站点放在 C:/MySite/UI,另一个放在 C:/MySite/API,但是您可以将主站点 Root 设置为 C:/MySite/UI,将 API 子站点设置为 C:/MySite/API 然后它会如你所愿地工作。

像这样调用 UseIISIntergation() 很重要:

public static IHostBuilder CreateHostBuilder(string[] args) =>
             Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseKestrel();
                    webBuilder.UseIISIntegration();
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseIIS();
                });

所以,这很好article how to Setup this

主要信息:

1-更改web.config

<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\MyTestApplication.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

2- 将 APP POOL 设置为“无托管代码”

3- 所有配置都应替换为 config.json 文件