Problem: ConfigurationManager does not work to access App.config in a v3.5 Azure WebJob
Question: How can I make it work?
* Background *
I have inherited a very old web application which must run as a Windows Azure Web App under a .Net 3.5 app pool.
There is a corresponding service which must be turned into an Azure WebJob (runs for several hours and requires access to the website files).
My problem is that the WebJob must be a .Net v3.5 application in order to run within the corresponding Web App (they both share the same App Pool so a v4.5 Web Job cannot be deployed to the v3.5 Web App).
This means I cannot use the normal WebJob NuGet packages such as Windows Azure Configuration Manager which I understand allows the System.Configuration.ConfigurationManager class to access App.config in the normal way, allowing referenced libraries containing EDMX based EntityFramework ObjectContexts to load their connection strings and app settings to be accessed by various bits of code all over the place. The code is shared between the web app and the web job so I need a method of configuration which is consistent across both.
Running the WebJob as a v4.5 allows it to work fine using ConfigurationManager but as soon as I switch to v3.5 (which I have to do to make the web app work) I have to remove all the incompatible WebJob Nuget packages including Windows Azure Configuration Manager. ConfigurationManager will no longer work to load AppSettings, no error, it just returns nothing for AppSettings.
My question is - how can I make ConfigurationManager work to load the deployed App.config without using those incompatible NuGet packages. I've looked at the code in Microsoft.WindowsAzure.Configuration.dll but I can't see how it make ConfigurationManager actually work, I must be looking in the wrong place.
After running some v4.6 vs v3.5 app pool tests (exactly the same codebase - no NuGet packages installed apart from Azure WebJobs Publish) I have found that Web Jobs running in v3.5 app pools simply don't load their config files.
On a side note RSACryptoServiceProvider.ImportParameters also explodes under v3.5.
The following works to force the config file to load.
class Program
{
static void Main()
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", #"D:\home\site\wwwroot\App_Data\jobs\triggered\DataImportWebJob\[TheAppName].exe.config");
Thanks to Using ConfigurationManager to load config from an arbitrary location
Related
I have a .net framework project with framework as 4.8. Recently I integrated docuSign 5.12 using a class library and nuget packages. Everything worked fine in development. When I published the exe in server, I am getting could not load file or assembly error. I cleared the references, reinstalled docusign, changed copy to output property to true for all and published again. But same result.
What I noticed is, when installing .net framework in server, it didn’t create a folder called .Netframework in ‘c:\Program Files(x86)\Reference Assemblies\Microsoft’. As the required dependencies missing are system dependencies, they are not copied to published folder.
So, I have another server where .net 4.8 SDK is present and everything worked fine there. My questions are
Why didn’t installation in server didn’t create assemblies?
Do we need to install .net 4.8 SDK for this to work?
How to publish dependencies for these kind of Nuget packages?
I have not added code samples as it is working already. Dependencies are https://www.nuget.org/packages/DocuSign.eSign.dll/5.12.0#dependencies-body-tab.
You can use the publish functionality of VS. It will package your app, including all NuGet dlls and their dependencies and send it to server. If you use Azure - it's integrated into the process. You can even include it in a CI/CD process. But your specific problem can be addressed by just having VS publish the app to your server instead of you manually copying files over there.
As per the comment from Ralf, I checked the references. Found an interesting thing. I already had a binding redirect in the project but, it was added to the class library config file but not the startup project config file. Because of that, my API was referring to old Newtonsoft version. I copied redirect from class library config to my main project config and it started working.
I am trying to update a library of shared code from .NET Framework to .NET Standard. The library has important dependencies on System.Web.Hosting.HostingEnvironment.IsHosted and HostingEnvironment.ApplicationID.
The library is precompiled into an assembly, and assembly is referenced across many projects:
.NET Framework console apps
.NET Framework Windows Forms apps
.NET Framework Windows services
Standalone ASP.NET website (bespoke code for a client, often as a web service)
Extension to ASP.NET site written by third-party. (Create new ascx controls with compiled code-behind added to \bin\ folder)
(Precompile is so that updated versions of the assembly can be dropped in place on solutions that already reference it.)
The library provides mostly code accelerators -- standardized database access, logging, license checking, type conversions, etc. The logging features are not only used by the calling project, but are also called by other parts of the library. For example, license checking relies on database access, and database errors are written to the log.
The logging area is a sticking point, especially in the context of bullet 5. The parent application may be served up from multiple IIS websites in multiple app pools. Or multiple IIS sites using the same app pool. Or from different subfolders on the same site, but in different app pools. When the library detects it is being run from inside IIS, logs are written to different files based on appId and application pool name. (E.G. MyCompany.2.PublicSitePool.log inside IIS, or just MyCompany.log when not in IIS)
On .NET Framework, I use System.Web.Hosting.HostingEnvironment.IsHosted to detect when I'm running in IIS, obtain the appId using HostingEnvironment.ApplicationID, and the app pool name comes from System.Environment.UserName.
I am trying to retarget the project for .NET Standard, so the library can be used equally well with .NET Core projects. System.Web.Hosting is not available on .NET Core. I'm looking for a solution that can either:
Give me consistent results on both .NET Framework and .NET Core
or
Explicitly detect whether running in .NET Framework or .NET Core, and then use appropriate techniques for the platform
I already have the "am I in IIS" check running as a singleton in the class constructor. Reflection does not thrill me but is a reasonable option if needed.
I have already reviewed these questions (and a few others). Some useful ideas, but no single solution. Reading settings from *.config is not an option. Asking the calling application to specify "hosted" or "not hosted" is the least attractive option that I know will work, because it will break all existing solutions that use this code.
HostingEnvironment does not contain a definition for IsHosted
How determine if an application is a web application in .NET Core?
How to tell if code is running on web server without using System.Web?
How to get HttpContext.Current in ASP.NET Core? [duplicate]
I have a .net core application , that at some point in the project refers to another .netStandard DLL which reads from app.config file using:
var x=ConfigurationManager.AppSettings["EngineServiceScansApiUrl"].
When I execute the application in debug mode (with debugger attached) x is null (the application can't find the configuration), whereas if I execute in ctrlf5 , sometimes it manages to read the configuration file, and sometimes it doesn't.
.NET Core uses appsettings.json instead of app.config. Take a look at this article for more information. ConfigurationManager is not available in .NET Standard 2.0 without a NuGet package.
I inherited a .net service project which does not support TLS 1.2, project was upgraded to .net 4.7. Previous .exe file was replaced with the new 4.7exe and the service was restarted. Service cannot be started due to error "1064:An exception occurred in the service when handling the control request"
Do I have to use installutil.exe MyNewService.exe to install a service?
The installutil.exe is located in C:\Windows\Microsoft.NET\Framework\v4.0.30319, would this support .net 4.7 or do I need to download and install .NET Framework 4.7 offline installer for Windows?
Thanks for any tips or suggestions, I am not familiar with .net services!
Ensure you include all output files from the build, including the app.config file. There might be assembly redirects there which are required by 4.7.
Is the correct .NET Framework version installed on the server you're running the service on?
If that doesn't help, try running the application from command prompt, if your application supports it (I recommend it should). If that works, the service user running the service might be missing some permissions.
Add logging. As minimum, add try-catch statements in your service entry points and log any exceptions to a file. You can also add a handler to AppDomain.UnhandledException which will -usually- be called before the application crashes.
A Microsoft Azure blog post from 2013 details how to use the application settings and connection strings in Azure app services. However, one part is not quite clear to me:
For ASP.NET web applications, there is some extra runtime magic that is available as well when using the .NET 4.5 framework (note: this magic is not available if you choose .NET 3.5 since it relies on functionality that only exists in .NET 4.5).
The author describes how you can use the System.Configuration.ConfigurationManager class to access the application settings and connection strings configured in the Azure portal.
How does this "extra runtime magic" work? Does the .NET Framework include Azure-specific code, or does Azure inject something, similar to how diagnostics will add a trace listener?
How does this "extra runtime magic" work? Does the .NET Framework include Azure-specific code, or does Azure inject something, similar to how diagnostics will add a trace listener?
As your article refered to,
If the website’s web.config file references the same connection string in the configuration section, then Windows Azure Web Sites will automatically update the connection string at runtime using the value shown in the portal.
Yes, Azure inject something.It is a feature of Azure App Service. For .NET apps, the application settings on portal are injected into your .NET configuration AppSettings/Connection strings at runtime, overriding existing settings.
Hope it can help you. For more details, you could refer to this article.