My company is exploring ASP.NET Core. We currently use ASP.NET Web API 2 & MVC 5.2.2. We deploy our applications under IIS using the following configuration:
VirtualDirectory1 (web.config with connection string and other non-specific information)
App1 (app specific web.config)
App2 (app specific web.config)
Api1 (api specific web.config)
Api2 (api specific web.config)
VirtualDirectory2 (web.config with connection string and other non-specific information)
App1 (app specific web.config)
App2 (app specific web.config)
Api1 (api specific web.config)
Api2 (api specific web.config)
As you know, each application or API inherits configuration from the parent web.config under IIS, so each inherits the parent connection string. We use a single copy of each application on the server. Can we deploy ASP.NET Core applications the same way?
I found StackOverflow articles on nested objects and environment specific AppSettings.json configurations but this does not appear to be the answer.
UPDATE 1:
The above is a multi-tenant configuration where each virtual directory is a tenant. The web.config at the root of each virtual directory contains the connection string all apps under the virtual directory use.
I read that a web.config file must exist for ASP.NET Core apps to work under IIS.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/index?tabs=aspnetcore2x#webconfig-file
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration#webconfig-file
So I wonder if that the connection string is visible to the ASP.NET Core applications.
Update 2:
A.F.A.I.K, web.config can be loaded from the app content root, but the one we need resides up in a virtual directory. A AspNetCoreModule maintainer told me environment variable inheritance (which applies in this scenario) is unreliable, and no plumbing exists to access other inherited configuration. The web.config only exists to configure IIS for ASP.NET Core applications.
The best solution seems to be using host headers the way Saaskit does.
https://github.com/saaskit/saaskit
This requires us to change our IIS deployment and add a DNS record per tenant, but it is the next best thing to inherited web.config files. I would like the ASP.NET Core team to consider introducing a ASP.NET Core-approach to inherited settings that gives us the same ability inherited web.configs did.
Putting tenant specific settings in a file up in a virtual directory is out of the box thinking, but it greatly simplifies multi-tenant support. Our MVC & Web API code needs nothing extra. It simply retrieves settings through the ConfigurationManager as though no other tenant exists.
We have one website under IIS and one virtual directory per tenant. Each tenant is accessed via its URI.
https://myfqdn.com/tenant1/myapp
https://myfqdn.com/tenant2/myapp
tenant1 and tenant2 are virtual directories containing a tenant specific web.config, so invoking https://myfqdn.com/tenant1/myapp loads tenant1's web.config and myapp inherits its settings for requests. /tenant2/myapp loads a different web.config.
Myapp is unaware of which virtual directory it was invoked from on each request. We install myapp in one physical location but add it as an application under each tenant's virtual directory. The result is we have one copy of the app, multiple instances, and no multi-tenancy plumbing.
ASP.NET Core is not bound to IIS so the same approach won't work as for ASP.NET. But you can implement a similar approach if you would like by moving your common settings to some SharedSettings.json and use this.
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
var sharedFolder = Path.Combine(env.ContentRootPath, "..", "Shared");
config
.AddJsonFile(Path.Combine(sharedFolder, "SharedSettings.json"), optional: true) // When running using dotnet run
.AddJsonFile("SharedSettings.json", optional: true) // When app is published
.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
config.AddEnvironmentVariables();
})
Read more here: Sharing appsettings.json configuration files between projects in ASP.NET Core
Related
Is it possible to host an ASP.NET Core MVC web app with different paths?
For example: I've an ASP.NET Core MVC web app hosted in IIS, with binding test.com.
Is it possible to cover multiple paths (app1, app2) without having to create multiple application under test.com.
https://test.com/app1/home
https://test.com/app2/home
This was achieved using UsePathBase (instead of creating multiple applications under IIS)
In StartUp.cs, added the below code to achieve it. WebsitePaths is a list of string ("app1", "app2").
foreach (var path in WebsitePaths)
{
app.UsePathBase(new PathString($"/{path}"));
}
Note: I have the same user group who can access multiple site under multiple paths (app1,app2 - to display different contents) under a single domain (test.com).
I would to host two ASP.NET Core Applications, a Web API and a Blazor Server App, but I searched in the internet and the answers that I founded only target to a different path inside of one application, that's not my case. I would to use they like a sub-address of the same Azure Web App for example: www.example.com and www.example.com/api where each one will be a different .NET Core application. So I suspect that I'll need to create two Azure App Services and try to communicate they both, but maybe the structured that I wonder won't work in this way, it's that right? How I can do this?
I have the same setup as you; an ASP.NET Core web API, and a Blazor Server Side app.
As you want to use the same domain for both services, you would have to use Azure API Management or some other proxy if you were to route requests to two different Azure App Services.
An easier option is to deploy both services to the same App Service, but as different virtual applications. You publish your Blazor app as normal, but for the Web API you would publish to a new virtual application /api.
To enable this virtual application, navigate to Configuration and then Path mappings in your App Service. Here you already have the default virtual application / pointing to site\wwwroot. You then add another virtual application named /api pointing to site\wwwroot\api:
When adding the virtual application, remember to remove checkbox for Directory (making it a virtual application instead), and optionally enable Preload:
If you publish your app using Azure DevOps Pipeline, it has an option to specify virtual application if another than default should be used.
You can now navigate to your two different URLs and hit each service. Note that when developing your Web API, you should not add api to your controllers routes, as this virtual application does that for you.
I want to use ASP.Net Directives in a TXT file. Typically, I would add a handler mapper for that. But how can I do that in Azure App Service? Adding the following handler (D:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll):
generates the following exception:
Most likely causes: IIS received the
request; however, an internal error occurred during the processing of
the request. The root cause of this error depends on which module
handles the request and what was happening in the worker process when
this error occurred. IIS was not able to access the
web.config file for the Web site or application. This can occur if the
NTFS permissions are set incorrectly. IIS was not able to
process configuration for the Web site or application. The
authenticated user does not have permission to use this DLL.
The request is mapped to a managed handler but the .NET
Extensibility Feature is not installed.
Things you can
try: Ensure that the NTFS permissions for the
web.config file are correct and allow access to the Web server's
machine account. Check the event logs to see if any
additional information was logged. Verify the permissions
for the DLL. Install the .NET Extensibility feature if the
request is mapped to a managed handler. Create a tracing
rule to track failed requests for this HTTP status code. For more
information about creating a tracing rule for failed requests, click
here.
and I don't think there is much I can do with the suggestions.
So what's the right way to map static file to ASP.Net pipeline in Azure App Services?
In Azure web service, we don't have to use aspnet_isapi.dll to use ASP.Net pipeline because the built-in server is IIS. We can see below screenshot, i published a ASP.NET Core to Azure web app, and we can see the Microsoft.Owin.Host.SystemWeb.dll under the root folder, this means that my ASP.NET Core application is hosted in IIS. (Besides IIS, are there any other better servers to support OWIN?).
Thus, if you are using ASP.NET Core and you want to use IIS pipeline, i think it is impossible because the IIS is just a reverse proxy server in this situation. You need to delete the Microsoft.Owin.Host.SystemWeb.dll and modify the web.config file (I tried and worked) but doing this will cause your ASP.NET Core application crashing.
If you are using ASP.NET Framework or just a simple static web, we can do it with our code and web.config.
I'm looking for a solution to facilitate for running a local solution that has a ASP.NET MVC Web Project and a Web API REST service project.
Setting multiple startup projects is saved in the .suo file, and is not checked into the repository since it is a specific user settings file. Also, IIS Express is configured outside the solution in the current's user's directory.
Any suggestions on how to support this multiple startup project scenario in a team scenario ensuring that the same ports are assigned to everyone that brings down the repository from source control?
Note: I do not want to move the Web API controllers to the web solution. The segregation of those two projects is important in this architecture.
In my MVC web app, one controller function (Validate) calls a service. See below code and note that MessageHandlerClient is a service proxy generated in Visual Studio. The service proxy call client.ValidateMessage(formdataasbson["HLmessage"].ToString()) works fine in my local dev environment. When I publish the project to Azure, calls to Validate controller function no longer work. Suspecting a problem with the proxy, I changed Validate() to give back hard-coded results, re-publish to Azure, and all works fine - confirming a problem with the web service proxy behavior in Azure.
[HttpPost]
public ActionResult Validate(String serializedformdata)
{
try
{
BsonDocument formdataasbson = this.serializer.JSONFormtoBSON(serializedformdata);
MessageHandlerClient client = new MessageHandlerClient();
this.jsonresponse.ReturnValue = "true";
StandaloneValidator.My_ServiceReference.Error[] results = client.ValidateMessage(formdataasbson["HLmessage"].ToString());
this.jsonresponse.ReturnMessage = results.ToJson();
return Json(this.jsonresponse);
}
catch (Exception ex)
{
this.jsonresponse.ReturnValue = "false";
this.jsonresponse.ReturnMessage = ex.Message;
return Json(this.jsonresponse);
}
}
What's more, I see details of the web service proxy in my local web.config file as below (IP intentionally obscured):
I have read various posts about web.config in Azure and the fact that it is not writable, so I'm suspecting my local ..... proxy info is never published in Azure. If indeed web.config does not publish from local to Azure, then I understand why my proxy doesn't work. The question is.....what should I do to fix??!
EDIT: I see various posts discussing migration of some settings from web.config to csfg files for Azure - perhaps a viable solution? Given that I am not coding manual read of these settings (I simply created service proxy from URL to service) I worry about auto-generated code or any "under-the-hood" behavior of the service not knowing how to read migrated settings from csfg.
Based on what you have written above, it seems you are confused with Web Role and Web Sites. First you would need to understand the difference between these two so you can make better decision on what to choose for your application. Here are some useful links:
SO discussion on difference between Azure Web Sites and Web Role
MSDN Article on when and why to choose Azure Web Sites and Web Role and Azure VM
Windows Azure Web site, you do not have full control over IIS web server and because of that some of the settings web site specific settings are configurable and others are not. In Windows Azure websites, most of machine and system specific settings added into web.config are overwritten so these settings does not work. Also you can not RDP to your Azure Websites instance as well.
If you have to use ASP.NET MVC application which MUST need proxy configuration, you must deploy it to Windows Azure Cloud Service.