System.Web.Hosting.HostingEnvironment in .NET Core? - c#

We have a system that we're moving from .NET Framework to .NET Core.
One piece of this is a logging system that we configure at startup using SimpleInjector. So in
App_Start\SimpleInjectorConfig we have:
private static void InitializeContainer(Container container)
{
var application = System.Web.Hosting.HostingEnvironment.SiteName;
var instance = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
// .. use application and instance in configuring the logging system
}
And the problem, of course, is that in .NET Core there isn't any System.Web.Hosting.
I've been browsing around, and I haven't found a way of getting an equivalent to HostingEnvironment.SiteName in .NET Core - at startup, before any endpoints are active.
Any ideas?

Check the discussion around SiteName on these two .net Core Git tickets. and that will help you to take the decision weather it is really required.
github.com/dotnet/aspnetcore/issues/7400 and
github.com/dotnet/aspnetcore/issues/17069

Related

Azure .NET v4 SDK Proxy Configuration in .NET Framework

I'm using the newer v4.x version of the Azure .NET SDKS - https://www.nuget.org/packages/Azure.Security.KeyVault.Secrets/4.1.0
In my case this is to access Key Vault secrets but the question probably applies globally. When using the above nuget package to retrieve a secret through a .NET Core 3.1 app, all seems to work OK.
var credential = new ClientSecretCredential("<TENANT_ID>", "<CLIENT_ID>", "<SECRET>");
var client = new SecretClient(new Uri("https://MyVault.vault.azure.net/"), credential);
var secret = await client.GetSecretAsync("MySecret");
However I need it to run in a .NET Framework 4.7.1, the call eventually times out after retrying 4 times.
I fully suspect this is down to the corporate proxy I work behind (although if there may be other reasons please tell me).
There is a SecretClientOptions that inherits from ClientOptions which contains a Transport property but it is not immediately obvious how to use this.
I see on other versions of the Node SDK they have a proxyOptions property but that doesn't exist in the .NET version. Is there another way to configure this?
I also wanted to try an diagnose a bit further but am not sure how to use the Diagnostics property and I struggle to get Fiddler to capture any .NET traffic these days.
UPDATE: Looks like a fix for this was committed 9 days ago so expecting a fix soon which will make .NET Framework use the system proxy correctly - https://github.com/Azure/azure-sdk-for-net/issues/16990
After diving into the library code it appears that the normal proxy as used with HttpClient isn't used. By setting the HTTP_PROXY and HTTPS_PROXY environment variables I was able to get this to work.
Environment.SetEnvironmentVariable("HTTP_PROXY", "http://my.corporate.proxy/");
Environment.SetEnvironmentVariable("HTTPS_PROXY", "http://my.corporate.proxy/");
UPDATE: Looks like a fix for this was committed 9 days ago so expecting a fix soon which will make .NET Framework use the system proxy correctly - https://github.com/Azure/azure-sdk-for-net/issues/16990
An alternative solution here can be the answer by Mun here. He suggests to cache the Key Vault values in App Settings Data structure.
You can also try this approach suggested by Docs if you don't prefer above approach.

'AddEntityFramework*' was called on the service provider, but 'UseInternalServiceProvider' wasn't called in the DbContext options configuration

I'm upgrading an ASP.NET Core application from Framework 2.2 to 3.1. It also uses Entity Framework Core.
In the Startup.ConfigureServices method, there is this code:
services.AddEntityFrameworkNpgsql()
.AddDbContext<MainDbContext>(options => options
.UseNpgsql(Configuration.GetConnectionString("MainDbContext")));
Everything was fine with .NET Core 2.2. With .NET Core 3.1, I get this warning on every application start:
'AddEntityFramework*' was called on the service provider, but 'UseInternalServiceProvider' wasn't called in the DbContext options configuration. Remove the 'AddEntityFramework*' call as in most cases it's not needed and might cause conflicts with other products and services registered in the same service provider.
Looking up the UseInternalServiceProvider method, it looks like that should be called on the options to pass on the main service provider. Unfortunately, at this point, the service provider does not exist yet. It is just about to be built.
I don't understand what the problem is and what this warning wants to tell me, but failed to do. How can I make that warning go away? The web doesn't know about this message yet.
Remove AddEntityFrameworkNpgsql. The docs explain that :
Calling this method is no longer necessary when building most applications, including those that use dependency injection in ASP.NET or elsewhere. It is only needed when building the internal service provider for use with the method. This is not recommend other than for some advanced scenarios.
The actual Getting Started page For Npgsql shows there's no need for anything extra :
simply place the following in your ConfigureServices method in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// Other DI initializations
services.AddDbContext<BloggingContext>(options =>
options.UseNpgsql(Configuration.GetConnectionString("BloggingContext")));
}

Is there any way to get EmployeeID in .NET Core without third party libraries?

I used to use the UserPrincipal class to retrieve active directory information on a user, specifically the EmployeeId (not the username, we don't usually use that to tie employees to specific data points in sql). However, in .net core that class doesn't exist and I'm still fairly new to .net core so I'm not sure how a lot of it's features work in an Intranet setting. I know many probably won't work with asp.net core being cross platform and other server types not having any idea of active directory.
Below is code I use in regular asp.net environments to grab an employee id.
var userContext = System.Web.HttpContext.Current;
PrincipalContext pcxt = new PrincipalContext(ContextType.Domain, "mydomain.com");
UserPrincipal uPrincipal = UserPrincipal.FindByIdentity(pcxt, IdentityType.SamAccountName, userContext.User.Identity.Name);
return uPrincipal.EmployeeId;
What kind of code if any can I use to grab the same information? Is it possible without third party libraries? It seems the IIS server may transport some kind of information I need through claims? I've attempted to do research but every thing just leads me down more research avenues and I'm not sure where to start.
What you are looking for now has moved in Net Core. The User Principal lives on the HttpContext, but you access via the IHttpContextAccessor which is injected using dependency injection.. This is an example from Microsoft of the starting point for it: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2
Okay, looks like for .net core 2> Microsoft has implemented the Principal Context library again, even though the documentation says there is no page when clicking .NET Core 2.2. At the very least, I am able to install the package and it works. It's authored by Microsoft, so I don't consider it Third Party.
https://dotnet.myget.org/feed/dotnet-core/package/nuget/System.DirectoryServices.AccountManagement
Luckily was able to find the package thanks to this answer: https://stackoverflow.com/a/49773749/5245385
The code is the exact same as it is in my question. All functionality seems intact.

How to get compatibility version in MVC

When configuring services within MVC app you can set the compatibility version:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
How can I retrieve this version later in my own code to determine which compatibility version is in use?
There does not appear to be a corresponding GetCompatibilityVersion method anywhere and google/stackoverflow search was not my friend.
Any help appreciated.
The MVC compatibility version is actually stored in an instance of a class called MvcCompatibilityOptions. You can retrieve this object by locating it through the IoC container that is being used by the application – either ASP.NET Core's built-in one or a third party one.
For example, with the default IoC, you can retrieve it like this:
var compatibilityVersion = app.ApplicationServices.GetService<IOptions<MvcCompatibilityOptions>>().Value.CompatibilityVersion;
app is an instance of IApplicationBuilder.

ASP.Net Core Replacement for VirtualPathUtility

Is there a replacement for VirtualPathUtility.ToAbsolute in ASP.Net Core? It doesn't seem to be available.
I'm wanting to convert a relative path e.g. "~/bob" into an absolute path, e.g. "/app/bob".
I'm trying to do this from a class library and so doesn't have access to the usual properties of controllers and views.
I'm porting an app from ASP.Net to ASP.Net Core and this library is being called from lots of places and passing parameters through from the controller is not something that I want to be doing - it would be hours of work due to number of places I would have to pass everything through.
I'm using ASP.Net Core 2.1, running on .Net Framework 4.7.1 (although I plan to port to .Net Core in a future release, once some dependencies have been removed so I want a solution that will work with Famework and .Net Core)
You can use HttpRequest.PathBase:
string relativeUrl = "~/foo";
string absoluteUrl = httpContext.Request.PathBase + relative[1..];

Categories

Resources