Category Archives: CodeProject

Muggles Don’t Understand Your Release Notes

Hey software friends, we need to talk.  In 2016, 61% of Americans are carrying smart phones and that means they’ve also got an app store on a device in their pocket.  My iPhone reports to me when I have updates to applications that need to be installed.  Many times, I see a screen that looks like this on my phone:

Release Notes Gone Bad

Release Notes Gone Bad

I’ve hidden the application names and icons in an effort to protect the innocent.  The problem with this approach is easy to identify when your non-technical friends and family members ask about the update notifications like this on their phones or tablets.  The conversation sounds something like:

“What are these updates my phone wants me to install?”

“There are some bug fixes for the applications you have installed that the author of those apps wants you to install”

“Will it fix that issue that I’m having and I’ve been calling you about?”

“I don’t know, the update just indicates, ‘various improvements and bug fixes'”

“Then I’m not installing it, it will probably just make my problem worse”

This is not a drill… Everyone is reading your release notes!

Seriously tech friends – when you publish software updates, people want to know what you are changing.  Other tech workers may stomach a “fixes and updates” release note every now and again, but in a world where the non-technical are seeing your notes, this is an opportunity for customer service engagement and you’re doing a TERRIBLE JOB at it.

When I used to publish release notes for NuGet, an open source project, I would give a one or two sentence description of the issue addressed and a link to the original issue on GitHub that discusses the reported issue and links to the software that fixed it.

Some of my NuGet Release Notes

Some of my NuGet Release Notes

Do you need to be this in-depth?  No… but give us a reason to install your update.  If you don’t have space in the minimal field size allocated on your app store or package management service, provide a link for more details.  You can list more in a blog post, a release notes part of your docs, and even include images to show off your cool updates.

Please software authors – start telling us a little more about what work you’ve accomplished in each release.  Its the right thing for your customers to show them that you are fixing things that they care about and gives credit to your development team for their accomplishments.

Where Did My ASP.NET Bundles Go in ASP.NET 5?

Stuffed BagEdit: There is now a screencast version of this post available.

Since ASP.NET 4.5 in 2012, developers have had access to a pair of tools in their ASP.NET toolbox called “bundling and minification”.  This feature would direct the webserver to combine together CSS or JavaScript files into one extra-large file and then apply a minification algorithm to shrink the size of the file for delivery.  In ASP.NET 5 however, this feature is no longer available.  In this article, I’ll review where bundles were configured and how you can migrate them to the recommended deployment model for ASP.NET 5

Continue reading

Get Started with ASP.NET MVC TagHelpers

Tag HelperWe are almost to the BETA cycle of ASP.NET vNext, and I’ve been following the ASP.NET team’s development on GitHub.  If you didn’t know already, the all-star developers at Microsoft are cranking away on the next version of ASP.NET in a completely open-source model.One of the cool new features set to be released with the next version is a significant addition to the HTML Helper model that we currently have in MVC 5, and its called TagHelpers. Continue reading

Authentication, Authorization and OWIN – Who Moved My Cheese?

I was working with one of my ASP.NET projects this weekend and ran into an interesting

problem while I was debugging.  This application was written from the ground up to use ASP.NET identity and OAuth security for all of my authentication and authorization needs.  That also means that my application follows the new default layout for an ASP.NET web forms application, with account management and login capabilities reside in the /Account folder structure.

An interesting series of things happens to web.config when we adapt the OAuth security management in ASP.NET 4.5+  What follows is what I have learned the hard way…

Authentication Information in Web.Config disappears

If you’re a long time developer with ASP.NET like me, you’re accustomed to the FormsAuthentication configuration in web.config.  With the new authentication and identity modules in ASP.NET 4.5, all of this goes away.  This really tweaked me at first, I got confused and followed the code… and trust me, its all good.

Web.Config has its authentication turned off and all identity providers removed.  Check out this snippet from a fresh web.config in a new ASP.NET 4.5 application:

  <system.web>
    <authentication mode="None" />
    <!-- other stuff -->
    <membership>
      <providers>
        <clear />
      </providers>
    </membership>
    <profile>
      <providers>
        <clear />
      </providers>
    </profile>
    <roleManager>
      <providers>
        <clear />
      </providers>
    </roleManager>
    <!-- other stuff -->
    </system.web>
  <system.webServer>
    <modules>
      <remove name="FormsAuthentication" />
    </modules>
  </system.webServer>

That’s some scary stuff right there.  Everything that I’ve known since ASP.NET was released in 2002 screams out: NOOOOOooooooo!  This is the necessary configuration to turn off all of the embedded and automatically activated security modules in ASP.NET  With that functionality shut off, the OAuth security module can step in.

OAuth Security Configuration

Instead, all of the security configuration goodness is kicked off in a new OWIN-compliant manner from within Startup.cs on the root of the application.

[assembly: OwinStartup(typeof(MyApplication.Startup))]

namespace MyApplication
{
  public partial class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      ConfigureAuth(app);
      app.MapSignalR();
    }
  }
}

Check out that attribute at the top of the file, an OwinStartupAttribute that points to this class that contains the codified configuration of the application.  The class is required to have a Configuration method with the same signature in this snippet.  I’m not clear why the class does not adhere to an interface that enforces the presence of this method, but this is the requirement.  You can see from here, that it calls the ConfigureAuth method in the App_Start/Startup.Auth.cs file.  Its in there that we can find all of the configuration for managing the authentication of resources in the application.

public void ConfigureAuth(IAppBuilder app)
{
 
  // Stuff to configure the Identity data storage
  
  // Enable the application to use a cookie to store information for the signed in user
  // Configure the sign in cookie
  app.UseCookieAuthentication(new CookieAuthenticationOptions
  {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
      LoginPath = new PathString("/Account/Login")
      // other stuff
  });
  
  // more stuff down here
}

This is where I was thrown for a loop.  How does ASP.NET know where my login page is?  Its defined right here with the LoginPage configuration property inside of the CookieAuthenticationOptions class.

How is Authorization Handled?

Finally, how is authorization to pages handled?  In the past, I would write blocks of XML with authorization elements that looked similar to the following…

  <location path="Admin">
    <system.web>
      <authorization>
        <deny users="?" />
        <allow roles="Admin" />
      </authorization>
    </system.web>
  </location>

The good news is that none of that has changed, and we can continue to code high-level authorization rules inside of web.config files in ASP.NET 4.5.

Summary

Its not a good idea to tinker with the default security configuration of ASP.NET unless you know where all of the moving pieces are.  In the past, I knew where everything was referencing from web.config through global.asax.cs to verify connections to my application where authenticated and authorized. In the new Owin enabled ASP.NET, those pieces have moved and are now very descriptive in their new locations.  Coming soon, I have a Pluralsight course that will discuss all of the cool things that you can do to configure ASP.NET OWIN security and other Advanced topics.  I look forward to delivering it for you in the very near future.

How to Automate ASP.NET Custom Controls with the Gulp JavaScript Task Runner

Here I am, writing a module for my next Pluralsight course and I ran into an interesting problem.  When I write a custom ASP.NET control, I now have lots of JavaScript and CSS libraries that I want to ship with it.  With the introduction of the Task Runner Explorer in Visual Studio, I decided to try my hand at writing a Gulp script that will combine and compress these static resources inside of my class library project.

Introducing Gulp for the ASP.NET Developer

Gulp is another task runner for use with NodeJS, similar to Grunt.  Unlike Grunt, Gulp runs based on a JavaScript file of instructions and can be run in an asynchronous manner.  This leads to Gulp being a bit easier to read as a series of functions that will run faster than the Grunt JSON configuration file.

To get started with Gulp and Visual Studio:

1. Install NodeJS from www.nodejs.org

2. Install Gulp with the NPM package manager as follows:

npm install gulp -g

This will install Gulp globally and make the gulp command-line executable available.

3. Create a package.json file in the root of your project.  This can be a file that contains just a pair of curly braces.

4. Configure gulp locally to the project by running the following script on the command line at the project root folder:

npm install gulp --save-dev

5. Install a handful of gulp plugins to manage the concatenation, renaming, minifying and notification processes:

npm install gulp-minify-css gulp-concat gulp-uglify gulp-notify gulp-rename --save-dev

With those command issued, we’re ready to build our gulpfile.js to contain the instructions for how to automate working with our static resources.

Create a file called gulpfile.js on the root of the project.  This file should be excluded from the project.  Begin by defining a series of variables using gulp’s built-in require commands:

var gulp = require('gulp'),
  concat = require('gulp-concat'),
  minifycss = require('gulp-minify-css'),
  rename = require('gulp-rename'),
  notify = require('gulp-notify'),
  uglify = require('gulp-uglify');

Next, we can define a simple gulp task to minify the bootstrap.css file that is in our project:

gulp.task('css', function() {

  return gulp.src('css/bootstrap.css')
    .pipe(rename('mycontrols.min.css'))
    .pipe(minifycss())
    .pipe(gulp.dest('css'))
    .pipe(notify({message: 'Styles minified'}));

});

The name of the task is “css” and it will trigger a function.  The function returns the result of operations on the css/bootstrap.css file.  The file is piped from one operation to the next with the pipe method.  First, the file is renamed to mycontrols,min.css so that the file matches the “mycontrols” project name.  Next, the contents of the CSS file are minified with the minifycss command and then piped to the css folder using the gulp.dest method.  Finally, a notification is triggered with the notify method and the message text specified.

The JavaScript processing is similar:

gulp.task('js', function() {
  
  return gulp.src(['scripts/jquery-1.10.2.js','scripts/respond.js','scripts/bootstrap.js'])
    .pipe(concat('mycontrols.js'))
    .pipe(gulp.dest('scripts'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .pipe(gulp.dest('scripts'))
    .pipe(notify({message: 'Scripts merged and minified'}));

});

This time, I am passing an array of files in to be processed.  The collection are concatenated together with the concat method into the mycontrols.js file and written into the scripts folder with another gulp.dest method.  The filename is renamed with a suffix of .min and sent into the uglify processor for minification.  The results of the uglification are written back to the scripts folder and a notification is triggered with an appropriate message.

Finally, I wrote a default task to call the JS and CSS tasks.  I called this task default:

gulp.task('default', ['js','css'], function() {});

The second argument in this method call is the collection of dependent tasks that should be called before the function is executed.  In this way, the js and css tasks are called asynchronously.

Automating Gulp with Task Runner Explorer

With the Task Runner Explorer extension in Visual Studio, I can connect any and all of these tasks to various steps in the build process.  In my case, I right-clicked on the ‘default’ task and chose to bind it to the ‘Before Build’ run time.

Now, every time I build my MyControls project, the gulp default task will run and deliver appropriate CSS and JS files for my controls to use.

 

Custom Control Project Considerations

Importantly, for this project I marked my gulpfile, package.json, and all of my original CSS and JS files as  Build Action None and Do not copy to output directory.  I did mark the new mycontrols.min.js and mycontrols.min.css as Embedded Resources so that they would be delivered inside of the DLL I will distribute with my controls.

Summary

The new Task Runner Explorer combined with the NodeJS command line interface and Gulp have made automating packaging assets for my custom controls much easier than previously.  Now, visitors to my applications will download one script file and one css file for my controls.  This will provide a faster and easier experience for my visitors and my developers that use my custom ASP.NET controls