将 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 应用程序,它集成了 Views 和 Controllers .该应用程序可以正常运行。但是,当我将应用程序的 Views 和 Controllers 分成两个 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!为此你应该这样做:
在不同的端口上启动您的所有应用程序。 (例如 445 和 446)
在443端口启动NGinx(很重要。)模拟IIS体验。您应该拥有一个可以合并所有站点的应用程序。
为第一个和第二个站点设置 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 文件
我有一个 Asp.Net Core 应用程序,它集成了 Views 和 Controllers .该应用程序可以正常运行。但是,当我将应用程序的 Views 和 Controllers 分成两个 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
在不同的端口上启动您的所有应用程序。 (例如 445 和 446)
在443端口启动NGinx(很重要。)模拟IIS体验。您应该拥有一个可以合并所有站点的应用程序。
为第一个和第二个站点设置 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 文件