It is very easy. All we need to do is to change hard codded string into one obtained from configuration object.
Startup file?
It is the place where it all starts. You probably expected to find global.asax file. Just like you got used to it previous versions of ASP.NET applications. Not this time. Now all we have at this start is startup.cs file.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging;namespace CoreDemo { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } } }
We can a class named Startup. This is a class that ASP.NET will look for by default when starting application. There are two methods in this class. Let’s take a look at the Configure method. It is in this method that we configure our application and response pipeline.
Now that we mentioned that. It is about time to finally start our application and see what we be the result.
As we may expected the result is our favourite “Hello world”. That is all because this piece of code from the configuration method.
app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); });
As we can see all the response pipeline does is to add “Hello World” text to the response context. Now let’s try to change it a bit and see if our changes would have result on application response context. We will try to add one more line to the response.
public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); await context.Response.WriteAsync(Environment.NewLine); await context.Response.WriteAsync("From my first ASP.NET CORE"); }); } }
It actually works. By changing Configure method we managed to change the output of the response.
Step in right way.
It is always a bad approach to return hard coded string. Always. Don’t argue. It should be stored in database or in configuration file. In our case database would be an overkill so let’s stick to configuration files. In previous version we would be able to use web.config file. That is no longer true. By default application doesn’t have a direct access to this file. So what is it good for in current version of framework?
<?xml version="1.0" encoding="utf-8"?> <configuration><!-- Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380 --><system.webServer> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/> </handlers> <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".logsstdout" forwardWindowsAuthToken="false"/> </system.webServer> </configuration>
In current version this file in only used to serve information for the IIS. Now if we want to store custom information we need to do this in appsettings.json. Let’s add this file to our project.
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true" }, "HelloMessage": "Hello from application settings." }
At this point there aren’t many elements in it. We have a connection string value. That is placed have by the default and our custom message. Before we start working with this settings file we are going to need a two new packages.
"dependencies": { "Microsoft.NETCore.App": { "version": "1.0.1", "type": "platform" }, "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0" },
This is an extended list on dependencies. We can see that we have added one for JSON and one for file extensions.
Now that all the dependencies are in place we can change hard coded string into ones from settings files.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging;namespace CoreDemo { public class Startup { public Startup(IHostingEnvironment hostingEnvironment) { var configurationBuilder = new ConfigurationBuilder() .SetBasePath(hostingEnvironment.ContentRootPath) .AddJsonFile("appsettings.json"); this.Configuration = configurationBuilder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync(Configuration["HelloMessage"]); }); } } }
A few new elements have been added. First of all there is a property.
public IConfiguration Configuration { get; set; }
This property hold an object of IConfiguration interface. Thanks to this object we can actually get data from settings file.
We also have a constructor.
public Startup(IHostingEnvironment hostingEnvironment) { var configurationBuilder = new ConfigurationBuilder() .SetBasePath(hostingEnvironment.ContentRootPath) .AddJsonFile("appsettings.json"); this.Configuration = configurationBuilder.Build(); }
Inside of it we are creation elements needed to get actual data from settings file. First on of get create new ConfigurationBuilder object. After that we set a base path. It is done that to environment object, which we manage to get thanks to dependency injection mechanism. Last step when creating this object is to set a source. In this case our settings file is going to be the source. When this is done we build our builder object and save result of the build inside property.
Now, that the configuration object is created we can use it to get data inside the response pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync(Configuration["HelloMessage"]); }); } }
It is very easy. All we need to do is to change hard codded string into one obtained from configuration object.
Karol Rogowski