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

Viewed 585

I have an Asp.Net Core app that integrates Views and Controllers. the app works without error. However, When I separated the app's Views and Controllers into two Asp.Net Core apps, it doesn't work properly. Views work as before but Controllers don't.

I followed one of the instructions mentioned at How to host multiple .NET Core apps under the same URL?

I did put Controllers to API Directory and Views in Main Directory like this

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

When I hit www.exampl.com/api/login, encounter the below error:

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

However, When I hit www.exampl.com/index which is the default page. It works perfectly.

I enabled Browsing Directory in IIS, but not worked.

my Controllers are Routed like below:

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

I worth saying that, I enabled logging into both web.config but no error detected.

Update

I just tested Controllers in a separated website, works and swagger appears

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

Update 2

Asp.Net Core Web 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();
    });
}

Update 3

I've enabled Detailed Error and I see below error thrown

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

However, when I tried the solutions explained here

The 500 - Internal Error is converted to 404 - Not Found.

Either way, the problem still exists.

1 Answers

you are trying to make the experience that Asp.Net Core does not support from the box.

When we creating Web application with old Asp.Net (.Net Framework) we host this app in IIS. So in IIS, you can create Sites and SubSites. It works like this - IIS owns 443 port and route requests to concrete site/subsite.

IIS is a big web server that starts in windows and owns ALL HTTP traffic. All sites start in separated domains (AppPool in IIS). Request routes by Pipeline.

But Asp.Net CORE uses another approach.

When you work with Asp.Net Core every application is a small Web Server (it is very simple, not like IIS). Each application starts and tries to get a port. It does not support Subsites. Each site is independent and starts on specific ports 443, 444,445, etc.

AS SOLUTION from you link How to host multiple .NET Core apps under the same URL? The author suggests using NGinx!To do this you should make this:

  1. start ALL your application on different ports. (for example 445 and 446)

  2. Start NGinx on 443 port (It's important.) To simulate experience from IIS. You should have one application that merges all your sites.

  3. Set up proxy_pass for the first and second Sites. It's done in Nginx config files. Like this:

     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.
    

One more option makes is to use IIS and setup proxy mode in IIS. It's analog of NGinx setup.

So, you are trying to place all files in the sub-folders. But it's incorrect. Subsites not must be placed in subfolders. It can be placed in different folders. For example, one site is placed in C:/MySite/UI and the other in C:/MySite/API, but you can Setup main site Root to C:/MySite/UI and API subsite to C:/MySite/API Then it will work as you want.

It's important to call UseIISIntergation() like this:

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

So, this is good article how to Setup this.

The main info:

1- Change 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- Setup APP POOL as "No Managed Code"

3- All configurations should be replaced by config.json files

Related