'ASP.NET Core 3.1 MVC Routing issue with IIS Default Web Site

New information:

After much messing around with trying to manipulate the URL I almost got it working but not quite. Then I discovered that it works without any coding changes if my home page url is \\localhost\ABIAdmin\Home. But it starts as \\localhost\ABIAdmin, and I have link in my _Layout to bring me there and it also comes up as \\localhost\ABIAdmin (without the \Home). It's easy enough to require our users to provide the full url with home in it, but I need the link to also provide \Home in it. Here's the html for the Home link:

 <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Dashboard</a>

So now the question is how do I get \Home in the url from the link, and if possible on startup? Can this be addressed through IIS, or through my endpoints?


I have an ASP.NET Core 3.1 MVC application with Razor Pages which works fine when I deploy it to IIS if I do not use the Default Web Site, or if I run the application as an exe. All of my navigation works, and all of my CRUD operations work (I'm using Syncfusion's DataGrid). However, if I deploy to the Default Web Site I run into what seem to be routing issues. Please note the following:

I added a folder under c:\inetpub\wwwroot called ABIAdmin, which contains my core app.

Relevant code from Startup/ConfigureServices: services.AddControllersWithViews();

Relevant code from Startup/Configure:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseCookiePolicy();
app.UseSession();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "Privacy",
        pattern: "{controller=Privacy}/{action=Privacy}/{id?}");
});

I have about 80 controllers not including the Privacy and Home controllers. There is no routing information in any of the controllers.

I tried messing with adding virtual directories but that did not help.

When I navigate to the Campaigns page from the Privacy page it forms a proper URL, e.g., http://localhost:5000/ABIAdmin/Campaigns, where ABIAdmin is the name of the site under the Default Web Site. But if I navigate from the Home page I get a 404 error. The requested URL is formed as http://localhost:5000/Campaigns, but it is missing the "/ABIAdmin", and the physical path is wrong too: C:\inetpub\wwwroot\Campaigns. When I successfully navigate from the Privacy page, the data is retrieved, but if I try to perform an Add/Update/Delete operation it just hangs. I believe this is because whatever URL the grid is forming is wrong. I don't think this is the fault of the Syncfusion grid.

So the question is, why does the Default Web Site behave differently then a standalone web site in this situation? We will be deploying this to multiple customers, and some will want it under the Default Web Site.

Any help would be appreciated. :)



Solution 1:[1]

It's looks like I found an answer. I have 3 scenarios to handle, running from VS, running from a standalone website, and running from an application under the Default Web Site. I could not figure out a way to tell in my _Layout.cshtml whether it is running under the Default Web Site so I'm using a configuration parameter to tell me that. I can tell whether I'm running from VS by the name of the application pool (from VS it's "ABIAdminApp AppPool"). I can also tell if I'm coming from the Home page now (that was the missing link), by checking Context.Request.Path. Given that info I can conditionally add the name of my application, ABIAdminApp. Note in the original post I may have referred to this as ABIAdmin. I will consider making the name of the app a configuration parameter as well.

@{
    @using ABIAdminApp.Classes;
    @using Microsoft.Extensions.Configuration;
    @inject IConfiguration Configuration;
    
    string appPoolId = System.Environment.GetEnvironmentVariable("APP_POOL_ID");
    string appName = "";
    
    if (appPoolId != "ABIAdminApp AppPool" && Context.Request.Path.ToString() == "" && Extensions.UseDefaultWebsite(Configuration)) { appName = "ABIAdminApp" + "/"; } else { appName = ""; }

    string anchor_template = "<a href='" + appName + "${URL}'>${FriendlyName}</a>";
}

So that solves my navigation problems. I also had to make changes for the Syncfusion grid updates. I had to conditionally add the app name and used ViewBag for that purpose with dynamic values for insertUrl, updateUrl, and removeUrl.

So in my Index method of the controller for Campaigns I had this code (preceded by logic to determine whether or not to add the app name):

ViewBag.InsertUrl = AppName + "/Campaigns/Insert";
ViewBag.UpdateUrl = AppName + "/Campaigns/Update";
ViewBag.RemoveUrl = AppName + "/Campaigns/Delete";

And this code in my view, Campaigns.cshtml:

<e-data-manager url="Campaigns/Campaigns" adaptor="UrlAdaptor" insertUrl="@ViewBag.InsertUrl" updateUrl="@ViewBag.UpdateUrl" removeUrl="@ViewBag.RemoveUrl"></e-data-manager>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Victor