visual-studio

Exploring the JSON Configuration Files in ASP.NET Core 1.0

As I have mentioned before, my team and I are working on getting up and running with a new ASP.NET Core 1.0 application. I've spent some time with them going over the new JSON-based configuration files like project.json, global.json, and appsettings.json, and now I'm finally at a point where I can write this post. Let's take a look at the three default JSON configuration files in a new ASP.NET Core application, and see what each of them is responsible for and what new functionality we can expect to be using.

NOTE: This post was written using RC1 (Release Candidate 1) of ASP.NET Core, and as the framework gets closer to final release, some things may change. If they do, I'll do my best to keep this post up-to-date. If you notice anything that needs to be updated, let me know in the comments.

global.json

The first file we should take a look at is in the Solution Items folder, called "global.json":

Our sample project structure, with the global.json files singled out

This file contains settings relevant to the entire solution, specifically what projects are included in said solution and what version of the .NET Execution Environment (DNX) is being used. Here's the contents of that file:

{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-rc1-update1"
  }
}

The "projects" section specifies the folders which contain projects that are to be included in this solution. In our case, only the "src" folder currently exists, but if we had a "test" folder any projects within it would be included into our solution.

The "sdk" section specifies the version of the DNX that our solution is to be run under. As this post was written when ASP.NET Core was a Release Candidate, you'll see that the version of the DNX in use is "1.0.0-rc1-update1". This value will change for each version of ASP.NET Core released.

There are other sections we can use under the "sdk" section:

  • "runtime": Allows us to specify whether we will run on the ASP.NET 4.6 runtime ("clr") or the ASP.NET Core 1.0 runtime ("coreclr"). If we don't specify this, the app will be compiled for both runtimes.
  • "architecture": Allows us to specify whether this app is run under x86 or x64 computer architectures. The default architecture depends on the runtime selected.

Even better, we now get full Intellisense support in these configuration files:

The next file we need to dive into is the "appsettings.json" file.

appsettings.json

Our sample project structure, with the appsettings.json file singled out.

"appsettings.json" stores the application settings for our program, which were formerly stored in the <appSettings> portion of the web.config file for previous versions of ASP.NET. The default file looks like this:

{
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-ASPNET5Demo-14da7232-82c7-4174-aee7-d8a42c04c5c3;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Verbose",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

Currently we have two sets of settings, "data" and "logging". These two sets are not special, and you can define any sets you like. The way to access these values from within our code base is covered quite nicely over at docs.asp.net.

This file is, by default, injected into the .NET runtime environment by a line of code in the Startup.cs file:

var builder = new ConfigurationBuilder()  
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

Note the last call to AddJsonFile(). ASP.NET by default allows for us to inject different application settings files based on the current environment. If you're running in the Development environment, and you have a file called "appsettings.development.json", the values in that file will be added to the configuration only when executing in Development. This is how we handle adding different connection strings for different environments. In other words, Environment AppSettings files replace XST Transforms.

There's one last file we should look at, and it's arguably the most important of the three: project.json.

project.json

Our sample project structure, with the project.json file singled out.

The project.json file, in our default ASP.NET Web Application, contains information about how the project is to be built, what dependencies it has, what frameworks it runs on, etc. The default file looks like this:

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },

  "userSecretsId": "aspnet5-ASPNET5Demo-14da7232-82c7-4174-aee7-d8a42c04c5c3",

  "dependencies": {
    "EntityFramework.Commands": "7.0.0-rc1-final",
    "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
    "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final",
    "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-final",
    "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
    "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.FileProviderExtensions" : "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "ef": "EntityFramework.Commands"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": { }
  },

  "exclude": [
    "wwwroot",
    "node_modules"
  ],
  "publishExclude": [
    "**.user",
    "**.vspscc"
  ],
  "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  }
}

Let's step through each of these sections to better understand what they do.

"version"

The version number of the application. I know, I know, it's positively mind-boggling, but try to contain your enthusiasm, please.

"compilationOptions"

The "compilationOptions" section defines certain options for the project, such as the language version or turning warnings into errors.

"compilationOptions": {
    "emitEntryPoint": true,
    "warningsAsErrors": true,
    "languageVersion": "csharp6"
},

"userSecretsId"

ASP.NET Core includes a secrets configuration system which allows you to store confidential information (e.g. connection strings that use passwords) on your local system rather than checking them in to source control. You can do this by using the Secret Manager tool. Please note that the Secret Manager is still in beta, and could change.

The "userSecretsId" section of project.json is used by the Secret Manager to access application secrets in a secure manner.

"dependencies"

This is, hands-down, the coolest section of this file.

ASP.NET Core 1.0 is completely broken down into NuGet packages, creating a pluggable system that allows you to only use the packages you actually need. The "dependencies" section of the project.json file allows you to tell the DNX what dependencies are required for your app to run. Here's a snippet of the section:

  "dependencies": {
    "EntityFramework.Commands": "7.0.0-rc1-final",
    "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
    ...
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
    ...
  },

Each of the dependencies specifies their version number, and we get full Intellisense support here just like we do in the other files. Even better than that, we can get NuGet packages from the NuGet server, and we get Intellisense support for that as well:

But the most amazing thing is that, when we specify a new NuGet dependency and save the file, Visual Studio will automatically attempt to download the NuGet package and include it in our project. NuGet is now seamless, fully integrated into Visual Studio and ASP.NET projects. NuGet all the things!

"commands"

The "commands" section defines DNX commands that can be run from the command line or Visual Studio's Command Window. A command, according to the docs, is a named execution of a .NET entry point with specific arguments. Essentially, the .NET Execution Environment exposes a way to run commands within the environment, and you can define what exactly those commands do in this section.

"commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "ef": "EntityFramework.Commands"
  },

Note the defined "web" command. That command will start a Kestrel web server and begin listening for requests. In other words, the "web" command is a shortcut to getting Kestrel running. The ASP.NET docs have a more in-depth tutorial on using commands, both in the command line and VS's Command Window.

"frameworks"

This section goes hand-in-hand with the "dependencies" section. Here's the JSON for reference:

"frameworks": {
    "dnx451": { },
    "dnxcore50": { }
  },

ASP.NET can now target multiple versions of the .NET Framework, which is nice because the different version do different things (for example, "dnx451" means .NET 4.5.1, which contains the DLLs for WebForms, something that "dnxcore50" doesn't have).

We can use this section to specify that certain dependencies should only when be used when running on certain frameworks (regardless of whether they are framework dependencies or NuGet packages). For example, I could pull down the DLLs for WebForms and the NuGet package for JSON.NET only when using .NET 4.5.1, like so:

"frameworks": {
    "dnx451": {
      "frameworkAssemblies": {
        "System.Web.DynamicData": "4.0.0.0"
      },
      "dependencies": {
        "Newtonsoft.Json": "8.0.2"
      }
    },
    "dnxcore50": { }
},

"exclude"

The "exclude" section of project.json is used exclude folders from the Roslyn compilation search path (StackOverflow source).

"exclude": [
    "wwwroot",
    "node_modules"
],

This means that folders specified in this section will not be compiled (hence why, by default, the folders included are "wwwroot" and "node_modules" both of which contain client-side resources like JS and CSS files and should not be compiled server-side). Simply adding another folder to the "exclude" collection will ensure that Roslyn does not attempt to compile that folder. For example, if you have a "forms" folder that contains PDF files, you probably don't want that folder to be compiled, so you would exclude it by placing it in this collection.

"publishExclude"

Similarly to "exclude", the "publishExclude" section specifies files that should not be published when the app is published.

"publishExclude": [
    "**.user",
    "**.vspscc"
  ],

The use of the ** wildcard indicates that any file, regardless of folder, with the specified extensions should not be published with the site. Right now, this section is just excluding some user- and Visual Studio-specific files.

"scripts"

The "scripts" section specifies commands that will be run at certain points in either the build or publish processes. The section currently defines four commands that run immediately before publishing.

"scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  }

If I wanted to run certain commands immediately after the build, I could use the "postbuild" section, like so:

"scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ],
    "postbuild": [ "command1", "command2" ]
  }

The other possible sections are listed over on docs.asp.net, and most of them are self explanatory.

Others

There are quite a few sections that ASP.NET and Visual Studio understands that are not included in the default project.json file. Of course, we get full Intellisense for these options, so feel free to explore them.

A screenshot of the intellisense options for the project.json file

Summary

The three default JSON configuration files (global.json, appsettings.json, project.json) contain a myriad of configuration options and completely replace the functionality of the old web.config files, as well as providing entirely new features like NuGet integration and full Intellisense support. In particular, I'm digging the Commands and Scripts sections, as now I can automate certain tedious parts of developing a web app (like bundling/minification, etc.).

Is this was useful to you, if you noticed a bug in my code, or if you just need to sound off, feel free to do so in the comments!

Happy Coding!

Using Gulp.js and the Task Runner Explorer in Visual Studio 2015

We're setting up a new ASP.NET 5 ASP.NET Core 1.0 project in Visual Studio 2015, and my team is trying to get used to the idea of "Task Runners" such as Grunt.js or Gulp.js. We're brand new to this idea, and my personal philosophy is What I don't understand, I cannot change, so obviously I need to understand these pieces of tech before I can hope to use them properly. Let's see if we can understand what a Task Runner is, what Gulp.js can do for us, and how using these makes building our applications a little bit easier.

What is a Task Runner?

In Visual Studio, a Task Runner contains collection of "tasks" that can be executed either on demand, or automated as part of a build process. Visual Studio includes native support for Grunt.js and Gulp.js task runners, and each of these is designed to make building client-side resources easier. For this project, we're using Gulp.js as our task runner, so the rest of this demo will use Gulp.js. But what is Gulp.js?

What is Gulp.js?

Gulp.js bills itself as the "streaming build system". Gulp.js provides a set of automation tools that allow us developers to automate common processes, such as bundling and minification of CSS and JS files. In short, Gulp.js makes these processes part of the build for your application.

(NOTE: because Gulp.js performs bundling and minification, I'd be willing to bet that the default MVC bundling and minification will be disappearing at some point in the future)

The Default Gulpfile.js

In ASP.NET Core projects, Gulp.js and Visual Studio use a file called gulpfile.js to define and bind tasks (we'll get into what "binding" a task means just a bit further down). Now let's look at this file, created by Visual Studio 2015 in an ASP.NET Core 1.0 Release Candidate 1 project:

/// <binding Clean='clean' />
"use strict";

var gulp = require("gulp"),  
    rimraf = require("rimraf"),
    concat = require("gulp-concat"),
    cssmin = require("gulp-cssmin"),
    uglify = require("gulp-uglify");

var paths = {  
    webroot: "./wwwroot/"
};

paths.js = paths.webroot + "js/**/*.js";  
paths.minJs = paths.webroot + "js/**/*.min.js";  
paths.css = paths.webroot + "css/**/*.css";  
paths.minCss = paths.webroot + "css/**/*.min.css";  
paths.concatJsDest = paths.webroot + "js/site.min.js";  
paths.concatCssDest = paths.webroot + "css/site.min.css";

gulp.task("clean:js", function (cb) {  
    rimraf(paths.concatJsDest, cb);
});

gulp.task("clean:css", function (cb) {  
    rimraf(paths.concatCssDest, cb);
});

gulp.task("clean", ["clean:js", "clean:css"]);

gulp.task("min:js", function () {  
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

gulp.task("min:css", function () {  
    return gulp.src([paths.css, "!" + paths.minCss])
        .pipe(concat(paths.concatCssDest))
        .pipe(cssmin())
        .pipe(gulp.dest("."));
});

gulp.task("min", ["min:js", "min:css"]);

This file allows us developers to use Gulp.js through the new Task Runner Explorer window, which looks something like this:

But, what does this file actually do? Let's break it down.

Visual Studio Bindings and Strict Mode

The first couple of lines of code in gulpfile.js are these:

/// <binding Clean='clean' />
"use strict";

The XML you see is Visual Studio's binding. Clean='clean' states that the 'clean' task should be run when Visual Studio executes a Clean.

The second line forces strict mode. Douglas Crockford explains:

"Strict Mode is an opt-in mode that repairs or removes some of the language’s most problematic features."

This is one of those features that, for now, I'm too wary of to mess with. Needless to say, read Crockford's post if you want to understand more of what strict mode is supposed to do.

Node Packages Required

The next block of code looks like this:

var gulp = require("gulp"),  
    rimraf = require("rimraf"),
    concat = require("gulp-concat"),
    cssmin = require("gulp-cssmin"),
    uglify = require("gulp-uglify");

This imports packages from Node Package Manager (NPM), similarly to how NuGet imports packages for server-side development. Currently we're importing five packages.

  • gulp: The gulp package itself.
  • rimraf: A deep deletion module which allows for deletion of files and folders.
  • gulp-concat: Concatenates files (AKA bundling).
  • gulp-cssmin: Minifies CSS files.
  • gulp-uglify: Minifies JS files.

We'll be using each of these packages in this default file.

Path Setup

The next block of code is relatively easy to understand:

paths.js = paths.webroot + "js/**/*.js";  
paths.minJs = paths.webroot + "js/**/*.min.js";  
paths.css = paths.webroot + "css/**/*.css";  
paths.minCss = paths.webroot + "css/**/*.min.css";  
paths.concatJsDest = paths.webroot + "js/site.min.js";  
paths.concatCssDest = paths.webroot + "css/site.min.css";  

All this is doing is setting up some paths we'll be using later. Note the "**" wildcard. The "**" wildcard specifies that any folder at that location is to be included in the path. This allows you to have as many subfolders under "js" or "css" folders as you want, and any JS or CSS files in the subfolders can still be targeted and processed by Gulp.js.

Clean Tasks

Now we start to see the implementations of the tasks themselves (after all, the tasks are what this thing can actually do). Here's the implementation for the Clean tasks.

gulp.task("clean:js", function (cb) {  
    rimraf(paths.concatJsDest, cb);
});

gulp.task("clean:css", function (cb) {  
    rimraf(paths.concatCssDest, cb);
});

gulp.task("clean", ["clean:js", "clean:css"]);  

Note that the first two tasks, "clean:js" and "clean:css", call the rimraf() function to delete certain files. The "clean" task removes the minified files if they exist. Further, showing good coding standards, the "clean" task simply calls the "clean:js" and "clean:css" tasks, and doesn't do any work itself.

Min Tasks

Now we get to a more complicated task. Here's the first "min" task:

gulp.task("min:js", function () {  
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

We're defining a task called "min:js" and specifying that it do three things:

  1. Concatenate (or bundle) all the files at the paths in the paths.js set, but that are not in the paths.minJs set into one file.
  2. Minify the resulting file.
  3. Place the resulting minified file at root location.

A similar set of things happens in the "min:css" task:

gulp.task("min:css", function () {  
    return gulp.src([paths.css, "!" + paths.minCss])
        .pipe(concat(paths.concatCssDest))
        .pipe(cssmin())
        .pipe(gulp.dest("."));
});

The only difference is that we're using cssmin() to minify CSS files rather than uglify().

And, of course, the final line of code combines both of these tasks into one call:

gulp.task("min", ["min:js", "min:css"]);  

In short, the "min" tasks bundle and minify your CSS and JS files.

Running Tasks

Now we can investigate how to run these tasks using Visual Studio. Take a look at the structure of a brand-new ASP.NET Core 1.0 RC1 Project in Visual Studio 2015:

Note the site.css and site.js files. What happens after we run the "min" task? You can run a task by right-clicking it and selecting "Run".

Now, we'll see that the site.css and site.js files each have a minified version.

It follows that running the default "clean" would remove those minified files.

Binding Tasks to Events

I mentioned at the beginning of this post that you can bind these tasks to run during certain Visual Studio events. Any task can run during any event, and each task can run during multiple events. The events we can bind Gulp.js tasks to are:

  • Before Build
  • After Build
  • Clean
  • Project Open

We can bind tasks to events by using the interface (right-click the task you want to bind):

You can also do it directly by modifying the binding code in the gulpfile.js:

/// <binding BeforeBuild='min, clean' Clean='clean' />

Summary

The integration of Gulp.js into Visual Studio 2015 makes managing JS, CSS, and HTML files much simpler. We can create tasks for common operations like bundling and minification, and those tasks can now automatically be run as part of events like Clean or After Build. All-in-all, Task Runners like Gulp.js bring Visual Studio and ASP.NET Core just another step closer to being the best IDE and project stack out there. Of course, I might be just a little biased.

Did this help, or did I miss something about Gulp.js or Task Runners that you found useful? Need to yell at me because you're frustrated and no one else is around? Sound off in the comments!

Happy Coding!

NOTE (1/25/2016): This post has been updated to reflect the naming change from ASP.NET 5 to ASP.NET Core 1.0

Debugger Windows in Visual Studio 2015 Quick Guide

Debugging is a critical skill that every programmer needs to become better at their jobs. Visual Studio provides several windows that help make debugging easier, but until now I hadn't really used them all that often. Well, in the spirit of not caring that I suck as long as I'm learning, I did a little research into the debugger windows that I'd never truly used before, and compiled a list of the most useful debugger windows in Visual Studio 2015. Here's hoping this helps some other debugging newbie as much as it has helped me.

We will cover the following windows in this post:

Without further ado, let's get started!

Breakpoints

Shortcut: Ctrl + Alt + B

The Breakpoints window is the simplest of the debugger windows; it just lists all the breakpoints in your application, and bolds those that are currently active. From this window, you can enable or disable specific breakpoints (by checking/unchecking them in the list), delete breakpoints, or edit their settings.

The Breakpoints window, showing two breakpoints, including one that is currently active

Output

Shortcut: Ctrl + Alt + O

The Output window displays status messages from the IDE. This window is basically the talkative younger cousin to the other windows; it spouts everything it has ever heard, and occasionally you'll hear something that interests you. It's the most verbose of the debugger windows, but if you need to really dig deep to find the bug you're looking for, it is invaluable.

The Output window, showing a collection of status messages.

Diagnostic Tools

Shortcut: Ctrl + Alt + F2

New in Visual Studio 2015 is the Diagnostic Tools window. This handy window allows you to monitor and analyze performance data even as you are debugging, and IMHO is a truly useful addition to the Visual Studio IDE.

The Diagnostic Tools window, showing Process Memory and CPU Utilization graphs

The Diagnostic Tools window displays the following information:

  • Events: Displays the time information related to breakpoint- and stepping-enabled events.
  • Process Memory: A graph showing the memory being used by the process over time.
  • CPU Utilization: A graph showing the CPU utilization over time (note that the unit is "% of all processors")

Autos

Shortcut: Ctrl + Alt + V, A

The Autos window shows the variables used in the current line of code and the preceding line of code of a set Breakpoint, listing their current values. This is a quick way to view the nearby state of the application at the set breakpoint. If you are only concerned about the immediate vicinity of the line being executed, the Autos window will show you all the current values.

The Autos window, showing four variables and their current values

Locals

Shortcut: Ctrl + Alt + V, L

The Locals window displays the variables (and their values) that are local to the current context or scope. Generally this means the procedure or function you are currently debugging. Both the Locals and Autos windows are populated automatically by Visual Studio's debugger.

The Locals window, showing five variables and their current values.

Immediate

Shortcut: Ctrl + Alt + I

The Immediate window, like Locals and Autos, is used to debug the values of properties and expressions. However, unlike those windows, the Immediate window is not automatically populated; it only shows value for properties and expressions that you enter into it. More importantly, the Immediate window can evaluate expressions using a command-like syntax, three examples of which are included in the screenshot below.

The Immediate window gives you more fine-grain control over what expressions or value you'd like to view at a given point in the execution, but you have to populate it manually.

The Immediate window, showing three different ways of printing an object.

Watch

Shortcut: Ctrl + Alt + W, 1 or Ctrl + Alt + W, 2 or Ctrl + Alt + W, 3 or Ctrl + Alt + W, 4

The Watch window allows you to watch values entered into it. This means that you could track the value of that particular variable throughout the execution of your method. Even better, you can track more than just variables; you can track any expression recognized by the debugger. If you're trying to find out what happened to your variable or object, and need to know where and when it changed, this window will help you find out. Visual Studio 2015 allows you to have up to 4 Watch windows open at a time (hence the multiple shortcuts).

Because the values in the Watch window are persistent, they remain in the window even if they're no longer in current execution scope. Here's the window with variables that are in scope:

The Watch Window, showing two properties in context

And here is the window with those same two variables, except that now the execution has moved beyond the appropriate scope:

The Watch Window, showing two properties that are out of the current context.

Call Stack

Shortcut: Ctrl + Alt + C

The Call Stack window simply displays each method or function that is currently on the stack. This is very useful if you are trying to track down which method called the method that contains the current line of code. Even more useful is the fact that this window will also display the language that each item on the stack was written in, so those of you working in multiple-language environments will get extra usage out of this window.

The CallStack window, showing a two-item stack

Exception Settings

Shortcut: Ctrl + Alt + E

The Exception Settings window allows you to specify which exceptions will cause the debugger to break, and where they should break. For example, you could specify that the debugger only break on ArgumentNullExceptions, or JavaScript OutOfMemory exceptions, or nothing at all (which I don't recommend, but you could do it). If you need fine-grain control over what exceptions do and do not cause the debugger to break, this window has you covered.

The Exception Settings window, showing a list of Common-Language Runtime exceptions.

Summary

These are the debugger windows in Visual Studio that I believe are the most useful. Now that I more thoroughly understand what each of these windows are meant to be used for, I will certainly be utilizing them more often. Hopefully, you will too.

Did I miss any debugger windows in Visual Studio 2015 that you use? Do you have another purpose for one of the windows listed? Share in the comments!

Happy Debugging!

Using 64-bit IIS Express in Visual Studio

Our organization, like many other medium-to-large companies, uses a central ORACLE database for most of our company-specific data. By itself this is not an issue (according to management), but problems arise from two things:

  • We are almost exclusively a Microsoft shop.
  • The version of ORACLE we are using is very old (8+ years).

Our need to interface with ORACLE is what drove me and my team to develop a mapping system that allowed us to map ASP.NET DataTables to strongly-typed objects. Now, however, we're running into a different set of problems.

Like most other shops (I believe), our servers run a 64-bit architecture. What I didn't realize until I started working with ORACLE about a year ago is that ORACLE actually cares about the architecture of the machine it is running on; the x86 version of ORACLE's DLL will not run on an x64 machine and vice versa.

This is problem because Visual Studio is a 32-bit application. When you start debugging a web site or application in VS, it spins up a 32-bit instance of IIS Express to host the process in. But ORACLE's 64-bit DLL won't run in this environment, so running and debugging on our local machines was something of an annoyance.

Before Visual Studio 2013 there was no easy way to run an app as a 64-bit process, so what we were doing was running locally using the 32-bit ORACLE DLL and then at deployment replacing that DLL with the 64-bit equivalent. These extra steps, though, were often loss in the shuffle of deploying an app, so it was quite a relief to us when VS 2013 was able to spin up the 64-bit version of IIS Express so that we could not have to bother with switching the ORACLE DLLs around.

In VS 2013, here's how you enable targeting a 64-bit version of IIS Express. First, go to Tools -> Options, then in the resulting window expand Projects and Solutions to find Web Projects. Click on Web Projects to open this dialog:

The Web Projects dialog, showing the

See that check box? If that is checked, running projects locally will cause Visual Studio to spin up a 64-bit instance of IIS Express, thereby creating a 64-bit process that the ORACLE DLL can execute within.

It's just that easy! Let me know if you found any other tricks for dealing with ORACLE in ASP.NET applications in the comments.

Happy Coding!