Tag Archives: web.config

Short Walks – Using AppSettings.json in Asp Net Core

One of the things that is very different when you move to Asp.Net Core is the way that configuration files are treated. This partly comes from the drive to move things that are not configuration out of configuration files. It looks like the days of app.config and web.config are numbered and, in their place, we have AppSettings.Json. Here’s an example of what that new file might look like:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AzureAppSettings": {
    "ApplicationInsightsKey": "1827374d-1d50-428d-92a1-c65fv2d73272"
  }
 
}
 

The old files were very flat and, using the configuration manager, you could simply read a setting; something like this:

var appSettings = ConfigurationManager.AppSettings;
string result = appSettings[key];

So, the first question is: can you still do this? The answer is, pretty much, yes:


public void ConfigureServices(IServiceCollection services)
{            
    IConfigurationBuilder builder = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json");
    Configuration = builder.Build();

    Configuration["AzureAppSettings:ApplicationInsightsKey"]

However, you now have the option of creating a class to represent your settings; something like:

AzureAppSettings azureAppSettings = new AzureAppSettings();
Configuration.GetSection("AzureAppSettings").Bind(azureAppSettings);

If you use this approach then you’ll need an extension library from NuGet:

Install-Package Microsoft.Extensions.Configuration.Binder

Is it better, or worse?

At first glance, it would appear that things have gotten worse; or at least, more complex. However, the previous method had one massive problem: it was a static class. The result being that most people have written their own wrapper around the ConfigurationManager class. We now have a class that can be injected out of the box; alternatively, you can split your configuration up into classes, and pass the classes around; the more I think about this, the better I like it: it makes more sense to have a class or method accept parameters that are necessary for its execution and, arguably, breaks the single responsibility principle if you’re faffing around trying to work out if you have all the operating parameters.

The other advantage here is that the configuration file can now be hierarchical. If you have well designed, small pieces of software then this might not seem like much of an advantage, but if you have 150 settings in your web.config, it makes all the difference.

Service has zero application (non-infrastructure) endpoints

The Error

Service ‘Namespace.ServiceName’ has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Service ‘Namespace.ServiceName’ has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:

[InvalidOperationException: Service ‘Namespace.ServiceName’ has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.]
System.ServiceModel.Description.DispatcherBuilder.EnsureThereAreApplicationEndpoints(ServiceDescription description) +345
System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +292
System.ServiceModel.ServiceHostBase.InitializeRuntime() +90
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +175
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +125
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +901
[ServiceActivationException: The service ‘/ServiceDirectory/ServiceName.svc’ cannot be activated due to an exception during compilation. The exception message is: Service ‘Namespace.ServiceName’ has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element..]
System.Runtime.AsyncResult.End(IAsyncResult result) +624522
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +196075
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +166

When are you likely to get this

This appears frequently when setting up new WCF services, or changing namespace or service names of existing ones. Unless, you’re a machine and never mistype anything, that is.

The cause

This is caused by a configuration error in the web.config. In my experience, it’s always caused by this; even if you’re sure that you’ve got it configured right – you haven’t.

Resolution

1. Check that the web.config has an endpoint defined:


      <service behaviorConfiguration="commonBehavior" name="Namespace.ServiceName">
        <endpoint binding="..." contract="Interface.IServiceName"/>
      </service>

2. Check the spelling. Compare the namespace against the service.svc file:


<%@ ServiceHost Service="Namespace.ServiceName" %>

3. Make sure you have the namespace specified in the web.config. The easiest way to determine why a WCF service is not working is navigating to the service.svc in internet explorer.

4. Don’t forget to do an IISReset if you change the web.config.