CategoryASP.NET

Continuous delivery, NuGet package generation and integration with TFS build server

Continuous Integration is getting more important and more popular and that is a good thing!
A couple of days ago, I was automating the NuGet package generation process. NuGet packages can be used for deployments to environments.

NuGet integrates in your solution when package restore is enabled.

enable-package-restore

This adds the following files to the .nuget folder in your solution:

  • NuGet.exe
  • NuGet.targets
  • NuGet.config

It also adds an import command for the NuGet.targets file to the project file:

<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />

One target of the targets file is BuildPackage. This target can be triggered by running the following msbuild command from the command line:


msbuild mysolution.sln /t:Build /p:BuildPackage=true

This will create a NuGet package for all projects which have imported the NuGet.targets file.
The following files will automatically be added to the NuGet package:

  • The project assembly
  • Files with build action set to content

For simple projects, this behavior is fine. The NuGet package holds the exact content of the project.
In my case, this was not really what I wanted. I wanted one NuGet package for multiple projects and the content files had to be placed in a different structure and location.

That’s when a nuspec file comes to the rescue!

The NuSpec file is the manifest file for NuGet packages. This file holds all information required for the NuGet packages, for example;

  • Package meta data (name, author, copyright, etc.)
  • Dependencies
  • Included Files

For a complete reference of the nuspec file, see http://docs.nuget.org/docs/reference/nuspec-reference.

I added a reference to the assembly1 and assembly2 project and added a nuspec file to the root of the project.
In the nspec file, I added the required assemblies and content files. The nuspec files section looked something like:

  <files>
    <file src="bin\assembly1.dll" target="lib\net40" />
    <file src="bin\assembly2.dll" target="lib\net40" />
    <file src="..\assembly1\Scripts\**\*.*" target="Content\Scripts" />
    <file src="..\assembly2\Scripts\**\*.*" target="Content\Scripts" />
  </files>

I ran the msbuild command on my dev environment and a package was created successfully and contained all files.
It also contains the dll of the NuGet project itself. This is not what I wanted.
I created a naming convention for all NuGet projects, the projects end with NuGet. This gives me the option to exclude the *nuget.dlls from the packages. This can be added to the build command I will describe later in this post.

Files added to the Content folder of a NuGet package are installed on the root of the target the project (the project which the NuGet package is installed to).
Assemblies added to the lib folder will be referenced in the target project. A subfolder in the lib folder can be used for providing different assemblies for a framework (.Net 3.5, .Net 4, etc).

I configured the TFS build server to run the same command and started a build.
The build failed, because NuGet could not find some of the referenced files in the files section of the nuspec file.
When I used RDP to login to the build server, I noticed that the output folder (binaries folder as it is called in the TFS build workflow template) is changed by TFS. It does not use the bin folder of every project, but it changes it to a different folder.
That is why bin\assembly1.dll and bin\assembly2.dll could not be found.

Creating packages should work on both dev environment and on the build server, so referencing the absolute output path on the build server is not an option.
The output folder is stored in the OutDir parameter. This parameter needs to be available in the nuspec file. This can be achieved by adding it to the properties list of the build command.
The build command is stored in the targets file, add “OutDir=$(OutDir.Trim(‘\\’))\\” to the property parameter of the build command. You can also exclude files by adding an Exclude parameter. This is what I have done to exclude the *Nuget.dll files.
The updated BuildCommand is as follows:

<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform);OutDir=$(OutDir.Trim('\\'))\\" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols -Exclude **\*NuGet.dll</BuildCommand>

It is now possible to use the OutDir variable in the nuspec file:

  <files>
    <file src="$OutDir$assembly1.dll" target="lib\net40" />
    <file src="$OutDir$assembly2.dll" target="lib\net40" />
    <file src="..\assembly1\Scripts\**\*.*" target="Content\Scripts" />
    <file src="..\assembly2\Scripts\**\*.*" target="Content\Scripts" />
  </files>

This solves the output issue on the build server and the build still works on the dev environment.

Adding a Placeholder to a TextBox for a String EditorTemplate

This post describes how an html5 placeholder can be added to an html input using mvc.

Add the Display attribute to a property in your ViewModel. Set the placeholder text to the Prompt property of this attribute.
MSDN describes the Prompt property as follows:

Gets or sets a value that will be used to set the watermark for prompts in the UI.

This is why I think the Prompt is the right property to use as placeholder.

ViewModel:

[Display(Prompt = "search for cities and countries")]
public string SearchTerm { get; set; }

Create a new EditorTemplate which overwrites the default editor template for properties of type string and save this file on the following location:

Views/Shared/EditorTemplates/String.cshtml

EditorTemplate:

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "text-box single-line", placeholder = ViewData.ModelMetadata.Watermark })

When you want to use placeholders with other types than strings (for example with type int), you should create a custom EditorTemplate for all these types.

Android Activities, it’s all about overriding event methods

In my previous post, I talked about class Attributes on Activities.
This post is about overriding event methods to influence the behavior of the Activity.

Activity LifeCycle

When a new Activity is created, the template overrides one event method; OnCreate.

[Activity]
public class MyActivity : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
       .....
    }
}

The OnCreate is part of the Activity LifeCycle.
It is important to understand the Activity LifeCycle, it is one of the fundamentals of an android application.
The OnCreate method works like the Page_Load method of a WebForms page.
This is ideal for setting up the Activity.

For instance:

  • loading layout files
  • updating controls
  • binding event handlers

All event methods of the Activity LifeCycle:

  • OnCreate
  • OnStart
  • OnResume
  • OnPause
  • OnStop
  • OnDestroy
  • OnRestart

When an activity changes state, the corresponding event method is called.
All these methods can be overridden and implemented.

The Activity exposes a lot more overridable event methods.
These are methods I use a lot:

Options menu

The following event methods are used for controlling the options menu:

public override bool OnPrepareOptionsMenu(IMenu menu)
{
       // add your options items to the menu here
      return base.OnPrepareOptionsMenu(menu);
}

public override bool OnOptionsItemSelected(IMenuItem item)
{
    // detect selected menu item and handle action
    return base.OnOptionsItemSelected(item);
}

The OnPrepareOptionsMenu is called when the options menu is created. Custom options can be added to the menu argument.
When an option item is clicked, the OnOptionsItemSelected is called with the selected option item as argument. I usually use a switch on item.Id to detect which item is selected.

The back button

The following event method is called when the back button is pressed:

public override void OnBackPressed()
{
    // handle back button
    base.OnBackPressed();
}

the base.OnBackPressed() provides the default back button behavior. Remove this line when you want to disable the default back button behavior, but I do not recommend it. People expect this behavior from the back button.

Creating Dialogs

This following event method is called when ShowDialog() is called in the current Activity.

public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
    // Create and return dialog here.
}

This method is used to create a dialog.

This should help you get on your way with creating your Activities.

Android Activities, it’s all about the attributes

As promised in my previous post (way too long ago, I know! I’m Sorry!!!), I would talk more about the Activities for Android applications in .Net (By Xamarin).
I want to start with one of the most important parts of the application, the Activities.

[Activity]
public class MyActivity : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
       .....
    }
}

This is the very basic of an Activity. It inherits from Activity and has an attribute Activity. The Activity base class provides many overridable methods, like onCreate, which is called when the Activity is created (think of the Page_Load in WebForm pages).

The Activity attribute has many interesting properties, some of them are listed below:

  • Label, this provides the label for the application, shown in the Android app screen
  • MainLauncher, this is an indication whether the Activity is the main activity and will be started on application startup.
  • Icon, Sets the icon for the application
  • Theme, sets the theme for the application, this can be a custom theme or a predefined theme.
  • ConfigurationChanges, sets which changes are handled by the application itself.
[Activity(Label = "My application",
          MainLauncher = true,
          Icon = "@drawable/icon",
          ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize,
          Theme = "@android:style/Theme.NoTitleBar")]
public class MyActivity : Activity
{
       .....
}

This is an example of the Activity with attributes. No custom code is needed to make this work.

The ConfigurationChanges is set to “Orientation” and “ScreenSize”, this means that orientation changes are handled by the Activity. I use this a lot with WebViews, this stops the application from reloading the page when the orientation changes.

The Theme “NoTitleBar” removes the titlebar from the application. This makes it possible to create your own title bar.
A list of all available predefined themes can be found here

Intercepting and filtering a result of a DataService Request

I’m a big fan of services. It really helps a loosely coupled design.
A WCF DataService isa RESTful service. This means that data can be get, modified or deleted based on the HTTP method used.

  • A GET request will return data
  • A POST request will insert data
  • A PUT request will update data
  • A DELETE request will delete data

It supports many data types (like SOAP, JSON, XML) without any extra programming. This makes it very flexible.

I was experimenting with a DataService and was trying to figure out how I can intercept a request and filter the results before returning the dataset.
In the example below, I am filtering a request for Participants. I only want to show participants with a specific Status.

public class ParticipantService : DataService
{
   // This method is called only once to initialize service-wide policies.
   public static void InitializeService(DataServiceConfiguration config)
   {
       config.SetEntitySetAccessRule("Participants", EntitySetRights.AllRead);
   }

   [QueryInterceptor("Participants")]
   public Expression<Func<Participant, bool>> FilterOnActiveStatus()
   {
       return participant => participant.Status == 2;
   }
}

The QueryInterceptor Attribute intercepts the request for “Participants” and it allows us to return an expression which filters the resultset.

Setting a version for an assembly with MSBuild

When you have multiple customers and common libraries, it is very important that you can track down the assemblies. You want to be able to tell at all time what the assemblies exactly contain.
Setting versions to an assembly helps a lot with that.
The version of an assembly is stored in the assembly.info file. You can find this file under the Properties folder in your project.
You can also set some meta data of the assembly in this file (like company name, copyright, etc).
The assembly version is stored in the attribute AssemblyVersion

[assembly: AssemblyVersion("1.0.0.0")]

For me, the  ideal situation of the version number should be as follows:

{major version}.{minor version}.{build number}.{revision}

The major and minor versions are defined by the user.
The build number is defined by the build server, a number which is incremented every time a build has run.
The revision is defined by source control;  this is the revision number of the latest commit in this build.

This makes it possible to determine when this build is created and what the source of the assemblies is.

I created a msbuild task for this, which sets the version number. I have used MsBuild Community Tasks for this. This has an AssemblyInfo Task which makes it very easy to set an assembly version:


<Import Project="tasks\MSBuild.Community.Tasks.Targets"/>

<PropertyGroup>
 <AssemblyInfoFile>.\Properties\AssemblyInfo.cs</AssemblyInfoFile>
 <AssemblyMajorVersion>1</AssemblyMajorVersion>
 <AssemblyMinorVersion>0</AssemblyMinorVersion>
 <AssemblyVersion>$(AssemblyMajorVersion).$(AssemblyMinorVersion).$(BUILD_NUMBER).$(SVN_REVISION)</AssemblyVersion>
<PropertyGroup>

<Target Name="SetAssemblyVersion">
 <AssemblyInfo CodeLanguage="CS"
 OutputFile="$(AssemblyInfoFile)"
 AssemblyCompany="Your company here"
 AssemblyProduct="Your product here"
 AssemblyCopyright="Your copyright here"
 ComVisible="false"
 AssemblyVersion="$(AssemblyVersion)"
 AssemblyFileVersion="(AssemblyVersion)" />
</Target>

Note that the BUILD_NUMBER and SVN_REVISION variables are environment variables set by the build server (Hudson in this case).

When you want to set the same version number for multiple assemblies, just simply add the assmblies as a link to the one assembly which will have the correct version number.

Creating and maintaining minified files in Visual Studio 2012 (with Web essentials)

Web essentials brings a lot of cool features to Visual Studio. It is a creation of Mads Kristensen. Many of these features will be added to Visual Studio in future releases and Web Essentials is downloadable as nuget package.
One of the cool features of Web Essentials is minification and bundling.
When you right click on a js file, Web essential adds an option to the context menu called “Minify Javascript file(s)”.
This creates two files, one minified file (adds min.js to the original filename) and a map file (adds min.js.map to the original filename).
Map files can be used to make the minified file readable and debuggable. The creation of a map file can be enabled or disabled in Tools > Options.

But now the coolest feature, when you make changes to the original javascript file, the minified file gets updated automatically.

I use this features a lot for my javacript plugins (see http://www.vicreative.nl/Projects). I work in the original files, the minified files are updated automatically and I commit them all in Git.

When selecting more than one file, the option “Create Javascript bundle file” gets enabled. This creates the following files:

  • a bundle file, an xml file containing all filenames for this bundle.
  • a javascript file
  • a minified javascript file
  • a map file

The same features also work for CSS files, but no map is created because this is not necessary for css files.

Creating bundles can also be done automatically, read this post.

Update:
The bundling and minification has moved from Web essentials to a different NuGet package: Bundler & Minifier

Reading properties by property name via reflection in C#

Reflection can come in handy in some situations.

Some of the situations in which I really like reflection is when you have to read properties when you only have the property name.
For instance when mapping data from xml to strongly typed objects and vice versa.

public T ReadProperty<T>(object model, string propertyName)
{
     Assert.IsNotNull(model, "model");
     Assert.IsNotNull(propertyName, "propertyName");

     var result = default(T);
     PropertyInfo property = model.GetType().GetProperties().FirstOrDefault(p => p.Name == propertyName);
     if (property != null)
     {
         var propertyResult = property.GetValue(model, null);
         if (propertyResult is T)
         {
             result = (T) propertyResult;
         }
         else
         {
             Logging.Info(string.Format("{0}: Property {1} is not of type {2}", typeof(PropertyReader), propertyName, typeof(T)));
         }
     }
     else
     {
         Logging.Info(string.Format("{0}: Property {1} not found in type {2}", typeof(PropertyReader), propertyName, model.GetType()));
     }
     return result;
}

This method reads a property from an object and returns the data in the type provided by the generic type.

This is just one of the few situations in which reflection is very powerful.

Mobile devices, detection and views in .Net MVC

Mobile is hot, and will probably only get hotter. Sites need to be viewable on any kind of devices, so mobile detection is a hot issue.

Headers

But how do we detect mobile devices?

Every http request send to a page or website contains headers. These headers give us information about the sender. A nice tool to intercept a request and check the headers is fiddler. I have been using this tool for some years now, and I gained a lot of knowledge about requests and responses.


GET http://vicreative.nl/ HTTP/1.1
Host: vicreative.nl
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4

This is an example of a request to my website. This request is sent by Chrome.

The header we are looking for is the User-Agent. This header gives us information about the indentity of the browser who send the request. In above example, you can see that the request is send with a Chrome browser. This header will also tell us when the request is send by a mobile browser. I used a mobile device emulator to fake a mobile request:

GET http://www.vicreative.nl/ HTTP/1.1
User-Agent: Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10
Host: www.vicreative.nl
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, multipart/mixed, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Device-Stock-UA: Opera Mobile Emulator (no stock UA available)

Another header to keep in mind is the following:


X-Requested-With: XMLHttpRequest

This header information tells us that this is an ajax request. This is also used to determine the IsAjaxRequest property in a MVC controller.

So many devices

Now that we know that every device and browser sends its own User-agent header, you will probably think that it’s impossible to know all devices and browsers and operation systems. Well, you’re right.

I think that’s why the mobile device detection of Microsoft does not work so great. They just can’t update it enough to make it work for all devices.

So do not use HttpCapabilitiesBase.IsMobileDevice. It will only work if you override it and set the correct value.

There is a NuGet package which contains many devices and is updated regularly: 51 degrees.mobi

It also comes with a config, which allows you to set actions for mobile devices, like redirects.

Setting Mobile context

Whether a browser is mobile, can be manually overridden:

HttpContext.SetOverriddenBrowser(this.Request.Browser.IsMobileDevice
                                        ? BrowserOverride.Mobile
                                        : BrowserOverride.Desktop);

The 51 degrees framework will automatically do that, so you don’t really have to do this, but it can come in handy when you want to force it for some reason.

The Browser object has a lot more useful properties for determining which view to display, for instance the property Platform.

Creating Display Modes

As described above, the Browser object has a lot of information about the requested device.
At application start, we can create specific display modes for device types. For instance for Andriod devices:

DisplayModes.Modes.Insert(0, new DefaultDisplayMode("android")
{
    ContextCondition = Context => Context.Request.Browser.Platform == "Android"
});

Keep it clean and create a (static) class in the App_start folder called DisplayModes which contains a method RegisterDisplayModes which registers all display Modes:

public class DisplayModes
{
    public static void RegisterDisplayModes(DisplayModeProvider displayModeProvider)
    {
        displayModeProvider.Modes.Insert(0, new DefaultDisplayMode("android")
        {
            ContextCondition = Context => Context.Request.Browser.Platform == "Android"
        });
        .....
    }
}

Now call this method from the App_Start in the Global.asax file:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    DisplayModes.RegisterDisplayModes(DisplayModeProvider.Instance);
    .....
}

Now that we have registered a display mode for android, we can create android specific views.

Know that the first matching DisplayMode will be used. So the order of registration is very important! The mobile display mode is already registered.

Mobile views

Let’s make some mobile views now.

Creating views for devices is really simple, just add the name of the view before the extension of the file and the ViewEngine will automatically pick up the view for the correct device.

mobile-views

This example has a default Index view (index.cshtml) a mobile view for all mobile devices (Index.mobile.cshtml) and a android specific view (Index.android.cshtml).

This works for all views, including layouts, partial views, shared views, strongly typed views etc.

Because we registered the android DisplayMode at position 0 (first), all android devices will be provided with this view.  When the device is not an android device, but is a mobile device, the mobile view will be presented. For all other devices, the normal index view will be displayed.

Testing

It’s kinda difficult to test this from your developer laptop/pc, but there are many tools who simulate mobile devices. I like the mobile emulator from Opera. It has a lot of presets for mobile devices.

But there are many other emulators, even microsoft has its own.

Caching issues MVC 4

Now that you have created and published your mobile friendly application, you deploy it to your server and quickly check it on your mobile to see if it really works. And it works! Hooray!

Soon people start complaining about seeing strange views. It looks like a mixture of mobile and default views.

This is because of a bug in MVC4. The MVC team has released a patch for it, available here on NuGet.

Automatic Bundling and Minification in .Net

One of the cool new features of .Net 4.5 is the bundling and minification feature. This can save so many requests to your server and saves you many kbs without creating a debug hell. The amount of data is getting more and more important, because of the mobile devices. People pay lots of money on data bundles for their mobile device, we better not waste it. It also decreases loading time!! Reasons enough to start using bundling and minification!

First thing you need to do is download and install the Microsoft ASP.NET Web  Optimization Framework nuget package.

The bundles are registered at application startup. This event is handled in the Application_Start method in the Global.asax. I always try to keep my Global.asax as clean as possible and split all registrations to seperate files in the App_Start folder. So I created a static BundleConfig class in the App_Start folder. This class contains one method, Register with the current Bundles as argument.

BundleConfig.RegisterBundles(BundleTable.Bundles);

BundleConfig

The BundleConfig class registers all JavaScript and Stylesheet bundles, Both Bundles can be added to the same BundleCollection, but both bundles have their own classes. JavaScript bundles are created by using the ScriptBundle class and Stylesheet Bundles are created by using the StyleBundle class.

bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js"));

This creates a JavaScript bundle named “~/bundles/jquery”  and includes one file, “~/Scripts/jquery-{version}.js”.  {version} is automatically resolved to the version of the jquery file in the scripts folder.

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));

This creates a Stylesheet bundle names “~/content/css”” and contains one file “~/Content/site.css”. Adding more files is easy, just add more files to the include and separate them by a comma.

Adding bundles to a view

The only thing left to do, is adding the bundles to a view.

MVC (Razor)

@Scripts.Render("~/bundles/jquery")

WebForms

<%: Scripts.Render("~/bundles/jquery") %>

The above code renders the JavaScript bundle.

MVC (Razor)

@Styles.Render("~/Content/css")

WebForms

<%: Styles.Render("~/Content/css") %>

The above code renders the Stylesheet bundle.

All the requests to the bundles have a querystring parameter (v=CkVTG71m7lHB5jSCpyOSxbeCVJLIPag7u7NL4ykFenk1). This is to make sure that no old versions of this file are cached and retrieved.

Config files

Bundles can also be configured in config files. This allows you to make changes to your bundle without having to rebuild the project. It also allows frontend developers to easily include, remove or change files in a bundle without having to use visual studio.

An example of a bundle.config file

<?xml version="1.0" encoding="utf-8" ?>
<bundles version="1.0">
  <styleBundle path="~/Content/css">
    <include path="~/Content/Site.css" />
  </styleBundle>
</bundles>

Debugging

One of the biggest problems of minified files is debugging. It’s almost impossible to debug those files.

That’s when the best feature of this minification framework comes in place. When compilation is set to debug (in web.config), the files will not be minified, which makes it a lot easier to debug.

<system.web>
    <compilation debug="true" />
    <!-- Lines removed for clarity. -->
</system.web>

Creating custom bundle transforms

Custom transforms can be created by implementing the IBundleTransform interface.,

using System.Web.Optimization;

public class MyByndleTransform : IBundleTransform
{
   public void Process(BundleContext context, BundleResponse response)
   {
       // Process bundle tranform here
   }
}

The custom transform can now be added to the transform of a bundle

var myBundle = new Bundle("~/My/Files/To/Include");
lessBundle.Transforms.Add(new MyBundleTransform());

This bundle can now be added to the bundles collection in the BundleConfig file.

Why creating custom bundle transforms? Just think of less or coffeescript, or whatever bundle you want.