Category Archives: ASP.NET @en

VSTS – build & publish .NET your Console App as a Webjob

Building App Services quite often, I came across the need to deploy Webjobs as part of CI/CD capabilities of VSTS.

What is so special about WebJobs?

  • They run in an App Service
  • They provide a simple way to build jobs using a variety of different languages (F#, cmd, exe, bash, nodejs, php…)
  • They can be found using Kudu:
    • under “d:\home\site\wwwroot\app_data\jobs\triggered\{job name}” for triggered jobs
    • under “d:\home\site\wwwroot\app_data\jobs\continuous\{job name}” for always running jobs

You can go here to read more details about Webjobs and how they work in Kudu.

VSTS configuration to build a Webjob

As part of our CI/CD strategy, we would like to deploy those jobs from VSTS.

VSTS does not have yet a predefined task to do so, but if we look again on where files should be placed, we could actually push artifacts in the proper place to make it works the way we need.

First let’s look at how we need to build our console app.

What are going to do here is to add a “Copy” task to actually copy our build output to the proper folder, using the same App Service folder structure:

What you can see here is that we are copying the output of the console app build from “$(Build.SourcesDirectory)/MyApp/MayAppConsoleApp/bin/Prod” to “$(build.artifactstagingdirectory)\App_Data\jobs\continuous\MyAppJob”.

Looks similar to what we saw earlier right? 🙂

By doing so we are creating our build artifact already with the required structure, so we can deploy our artifacts then straight  to the root App Service folder, as the WebJob folder will already be there.

This means when looking at release App Service deployment part:

As you can see, nothing special is to be found here 🙂


If you want to deploy your Webjob in your App Service:

  1. In your build, create a “Copy” task which outputs the copy to you artifact directory : “$(build.artifactstagingdirectory)\App_Data\jobs\continuous\MyAppJob”,
  2. Nothing to do in your deployment part, TADA!
  3. There no 3.

Happy coding!

Using Hangfire, or how to run your code as jobs

I encountered Hangfire a while ago, and tried it out sometimes a year ago, but was not having time or need to properly address some job capabilities.

If you are reading me, it’s because your either looking at understanding what is Hangfire or how to address some of your needs.

Hangfire is about running some portion of your code as jobs away from your main (server/web) process. It also adds the capability to run this code as recurring (very convenient to put in place simple update/cleaning/reminder/mailing jobs).

The most important part you have to get when willing to run Hangfire job, is that you code has to be cable to give itself a proper context:

  • no HttpContext.Current or similar objects: only what you give to your object at method calling time matters (this is what get serialized as Json on the Hangfire back-end).
  • no complex object graph: if the class/service you are willing to instantiate has many dependencies (other objects inits or similar), please make sure everything is in proper order from the call you initiate with Hangfire OR let your object initialize itself properly.
  • Bottom-line, be context friendly! if you have keys or ids to identify data you want to manipulate, pass on these values for serialization: simple to serialize and easier to maintain.

When digging into implementing Hangfire, you’ll see by yourself going over the documentation that almost all you need has been thought through.

As per writing some code using Hangfire, here a re a few hints:

  • You can only add Hangfire.Core Nuget package to a given project if you only intend to add jobs from it (less is better)
  • When willing to use an IOC container, make sure your use the proper Enqueue prototype; if you don’t, Hangfire will simply store the actual type (not the interface) that was used at Job enqueuing time,  which might work at first, but  won’t switch to your new type if you change your interface implementation in your ioc container:
BackgroundJob.Enqueue(x => x.MyInerfaceMethod(param1, param2, param3));
  • If you are planning to run the Hangfire server part in an ASP.NET app, don’t forget to have it running all the time! Hangfire does not auto-start the web app because it’s there 🙂
  • As you can access multiple queues when building with Hangfire, don’t forget to assign Hangfire processing servers to different queues.

Thanks for reading, happy coding!

Azure Directory Library & TokenCache persistance – upgrade issue

When using the Microsoft.IdentityModel.Clients.ActiveDirectory nuget package to deal with ADAL token cache, you can ctaully serialize the state of your cache to use it at a later point:

public class RefreshTokenCache : TokenCache
    private void AfterAccessNotification(TokenCacheNotificationArgs args)
        if (this.HasStateChanged)
            var data = Convert.ToBase64String(this.Serialize());

When migrating from 2.x to 3.x versions of the library, I encountered some issues trying to serialize back my token cache to its initial state:

var tc = new RefreshTokenCache();

The problem was that serialized data obtained on v2.x was not de-serialized properly when using 3.x versions.

I that case, I am forcing the token to be asked again to the end-user, so that I can serialize it back to the 3.x format.

Happy coding!

Kicking System.Web out of your code – part 3: utilities

Last part of my blog posts about getting rid of System.Web.

We are going to look into some pretty gluing parts of System.Web now.

1. HtmlEncode & UrlEncode

This one is pretty easy, System.Net is actually coming with System.Web equivalents methods here.

2. Querystring value access

Same for easiness here, based on Rick Strahl’s extensions found here.

3. MachineKey

This one gets a litle more tricky, but looking around can bring you a replacement, as the one below:

public class LogrrMachineKey
    private static string _decryption = "AES";

    private static byte[] _cryptKey;
    private static string _decryptionKey;

    public static string DecryptionKey
            _decryptionKey = value;
            var key = HexStringToByteArray(_decryptionKey);
            _cryptKey = key;

    public static byte[] Encrypt(byte[] inputBuffer)
        SymmetricAlgorithm algorithm;
        byte[] outputBuffer;

        if (inputBuffer == null)
            throw new ArgumentNullException("inputBuffer");

        algorithm = GetCryptAlgorithm();

        using (var ms = new MemoryStream())
            ms.Write(algorithm.IV, 0, algorithm.IV.Length);

            using (var cs = new CryptoStream(ms, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
                cs.Write(inputBuffer, 0, inputBuffer.Length);
            outputBuffer = ms.ToArray();
        return outputBuffer;

    public static byte[] Decrypt(byte[] inputBuffer)
        SymmetricAlgorithm algorithm;
        byte[] inputVectorBuffer, outputBuffer;

        if (inputBuffer == null)
            throw new ArgumentNullException("inputBuffer");

        algorithm = GetCryptAlgorithm();
        outputBuffer = null;

            inputVectorBuffer = new byte[algorithm.IV.Length];
            Array.Copy(inputBuffer, inputVectorBuffer, inputVectorBuffer.Length);
            algorithm.IV = inputVectorBuffer;

            using (var ms = new MemoryStream())
                using (var cs = new CryptoStream(ms, algorithm.CreateDecryptor(), CryptoStreamMode.Write))
                    cs.Write(inputBuffer, inputVectorBuffer.Length, inputBuffer.Length - inputVectorBuffer.Length);
                outputBuffer = ms.ToArray();
        catch (FormatException e)
            throw new CryptographicException("The string could not be decoded.", e);
        return outputBuffer;

    private static SymmetricAlgorithm GetCryptAlgorithm()
        SymmetricAlgorithm algorithm;
        string algorithmName;

        algorithmName = _decryption;
        if (algorithmName == "Auto")
            throw new Exception("Explicit algorithm is required");

        switch (algorithmName)
            case "AES":
                algorithm = new RijndaelManaged();
            case "3DES":
                algorithm = new TripleDESCryptoServiceProvider();
            case "DES":
                algorithm = new DESCryptoServiceProvider();
                throw new Exception($"Algorithm {algorithmName} is not recognized");

        algorithm.Key = _cryptKey;

        return algorithm;

    private static byte[] HexStringToByteArray(string str)
        byte[] buffer;

        if (str == null)
            throw new ArgumentNullException("str");

        if (str.Length % 2 == 1)
            str = '0' + str;

        buffer = new byte[str.Length / 2];

        for (int i = 0; i < buffer.Length; ++i)
            buffer[i] = byte.Parse(str.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
        return buffer;

This class is not a one-to-one replacement of the existing MachineKey classes found in System.Web, so please make sure you migrate/ reset your values first.

Happy coding!

Kicking System.Web out of your code – part 2: HttpBrowserCapabilities object

Second part of my blog posts about getting rid of System.Web.

I will cover 2 part fo this object that I usually use: browser info & mobile device detection

1. Web browser information

We will he make use of the UAParser-csharp (c-sharp equivalent or the UAParser.js) which provides us a parsing mechanism of the User Agent string.

After installing the lib using Nuget, just a simple extension make the day (here returning “Windows 10 using Chrome“):

public static string GetBrowserName(this HttpRequestMessage request)
    var ua = request.Headers.UserAgent.ToString();
    var uaParser = Parser.GetDefault();
    var c = uaParser.Parse(ua);
    return $"{c.OS.Family} using {c.UA.Family}";

2. Mobile device detection

As far as you want to make sure you are rendering the web page for a mobile device or not, you can just use this extension method (inspired by this SO answer):

public static bool IsMobileDevice(this HttpRequestMessage request)
    string u = request.Headers.UserAgent.ToString();
    var b = new Regex(@"(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    var v = new Regex(@"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
    var returnVal = b.IsMatch(u) || v.IsMatch(u.Substring(0, 4));
    return returnVal;

Last step, will be removing MachineKey and utilities dependencies.

Happy coding!

Kicking System.Web out of your code – part 1: ASPNET MVC

Being doing some .NET code for a while now, you sure saw how much dependencies your code has on it.

With .NET core coming in sight, but also for optimizing you existing ASP.NET code base, you probably would want to start lowering your dependencies on it…

The first step (but not the smallest) for me is to kick out ASP.NET MVC.

DISCLAIMER: don’t get me wrong, ASP.NET MVC is a great framework for some use cases, but in my search for boot time optimization and lower memory footprint, this is not exactly what I need.

  1. Replacing ASPNET.MVC by RazorEngine

Not having much linked to it anyway, I replaced it with Razor Engine, a decoupled open source version for the MVC Razor engine (that you can also use to render other things than pages: emails, documents…)

Here is a piece of code to end up using the Razor Engine to render html views and use it the way you alwazs used ASP.NET MVC:

HttpRequestMessage extensions first:

public static class HttpRequestMessageExtensions
    public static TemplateServiceConfiguration TemplateConfig = new TemplateServiceConfiguration
        TemplateManager = new EmbeddedResourceTemplateManager(typeof(Startup))

    public static IHttpActionResult View&amp;lt;T&amp;gt;(this ApiController controller, string viewName, T model)
        return GetResponseView(controller.Request, viewName, model);

    public static IHttpActionResult GetResponseView&amp;lt;T&amp;gt;(this HttpRequestMessage request, string viewName, T model)
        var service = RazorEngineService.Create(TemplateConfig);

        var result = service.RunCompile($"Views.{viewName}", typeof(T), model);

        return new HtmlActionResult(request, result);

Using the extension in a controller:

public IHttpActionResult Index()
    var model = new AppModel();
    // filling the model accordingly.
    return this.View("Index", model);

Warning: this does not handle partial views, so this has to be managed additionally.

  1. Replace ASPNET.MVC with SPAs

The ultimate goal is to only have service-side code running as services (leveraging ASP.NET Web API), then to build your UI using a front-end stack for that (Angular. React, whichever suits you).

Next step, will be removing Browser HttpBrowserCapabilities dependencies.

Happy coding!

Swagger (Swashbuckle) with dotnet: real life implementation – part 2

Following my first article on how to use Swagger with .NET using Swashbuckle, I wanted to cover a last but very important point: dynamic entities.

I am sure that a lot of you are using dynamic object with document-orentied DBs, which bring the problem of giving a proper output to them with .NET documentation (and strongly type)

In any of these cases, what I usually do first is to never exposing my back-end objects directly through Swagger (which makes real sense with Entity Framework) to give all the flexibility to serialize or not certain properties, or even the way they need to.

1. Using SwashBuckle hooks

Which SwashBuckle we can hook into documentation creation to add/update object properties to set more custom properties. Have a look here in the current documentation.

2. Using string[] and Json.Net objects

What to do if you have complete dynamic objects that you what to show either as empty objects (on which you can add as many properties as you want) or an array of strings or properties ?

// property shown by Swashbuckle as empty object.
public JObject AppInstProperties { get; set; }

// property shown by Swashbuckle as an array.
public string[] EditableUserInAppProperties { get; set; }

In this cases, you could also replace string[] by YourObject[] 🙂

Happy coding!

Swagger (Swashbuckle) with dotnet: real life implementation – part 1

I have been roaming around the web for a while to try to find real hints to implement proper Swagger documentation on top of Web API, and I didn’t really find what I wanted.

I have then being doing myself investigations on the road, and I found very interesting points on how to (or not to!) do things with Swagger and dotnet.

1. Setup

To be able to use your method documentation on you assemblies, the first step is to enable then to be output, whether it’s coming from your main project or referenced libraries:

To do so, go to you build project Build settings, and check “XML documentation file” to specify the file name used to output the XML:


Then in your Swagger project go to your SwaggerConfig.cs in App_Start folder and use the following line of code to make Swashbuckle understand where to Get XML to enrich your methods and object definitions:

c.IncludeXmlComments(string.Format(@"{0}\bin\Gibberish.Api.xml", AppDomain.CurrentDomain.BaseDirectory));

2. Documenting

To document your entities refer to this table to know how xml tags are mapped to Swagger properties, have a look here (coming from the Swagger Github home page):

  • Action summary -> Operation.summar
  • Action remarks -> Operation.description
  • Parameter summary -> Parameter.description
  • Type summary -> Schema.descripton
  • Property summary -> Schema.description (i.e. on a property Schema)

Real example for these for methods:

/// <summary>
/// Updates the mobile entity
/// </summary>
/// <remarks>
/// entity need to be up to date
/// </remarks>
/// <param name="entity">Parameter description goes here</param>
[HttpPut, Route("update")]
public IHttpActionResult UpdateMobileEntity(RestMobileEntity entity)
    return Ok(base.mobileService.Update(entity));

And for types :

/// <summary>
/// Mobile entity
/// </summary>
public class RestMobileEntity 
    /// <summary>
    /// Entity Id
    /// </summary>
    public int entityId { get; set; }

    /// <summary>
    /// Entity content
    /// </summary>
    public string entityContent{ get; set; }

That’s a first round for Swagger and dotnet, let’s have a look next about Swagger with dynamic object, and custom theme use.

Announcing the new Azure App Service

Yesterday, Scotts (Guthrie and Hanselman) have been introduced a new AzurepPlatform offering called: Azure App Service.
A bit of renaming is to be done, but there is a LOT of new stuff behind all of this:

  • “Azure Websites” now become “Azure App Service – Web Apps”,
  • “Azure Mobile Service” is now “Azure App Service – Mobile Apps”,

Renaming stops here, with newcomers to the Platform:

  • “Azure App Service – Logic Apps”, which basically behaves like modeling processes using different API Apps,
  • “Azure App Service – API Apps”, which is actually for me the base of the new offfering.

So what about these API apps then?

To make long story short, API Apps are here to simplify most of the work of the 3 others (Web Apps, Moible Apps & Logic Apps) by:

  • providing a similar way of consuming API apps (JSON based with Swagger capabilities “”),
  • giving a way to make API apps to deal with authentication in a transparent manner,
    offer versioned and automatically updatable APIs to all 3 types of apps.

API Apps are based at core on ASPNET Web API stack, with few little twists for authentication.

To have a more concrete view of this, here is a little MS slide used to represent to common glue which is API Apps in that regard:

These API Apps is making a best use of some great tooling already available such as:

  • Swagger to repressent API methods and content (a “modern WSDL” I always say),
  • Swashbuckle, a tool to implement simply Swagger capabilities inside of ASP.NET Web API,
  • AutoRest, a Swagger “svcutil-like” to build up a proxy for REST Services.

As of with all these new offering, the best part is: you can get all of them hosted under the same pricing you has for only one Website or Mobile App: all of these can run inside a Shared or dedicated container that does all of this!

As a conclusion, this starts a real great new platofrm settlement for Azure, which we should all be looking into!

Introducing ASP.NET 5

For some of you who could have missed a bit about what is happening in the MS world these days, I am pretty sure that most didn’t miss all of the annoucements going around .Net…

The biggest part of it, is the annoucement of ASP.NET 5, which holds a lot of undelying changes and promises:

  • Build & run ASP.NET apps on Windows, Linux AND Mac.
  • .NET Core, which is the base of this capability, a new modular and versioning capable stack.

As .Net Core is for now more limited than the Full .Net frameowrk, this does not mean that you will have to migrate you code to benefit from all new ASP.NET 5 capbilities: these  will also be available on Full .NET stack 4.5.2 and above.

The BIGGEST point here is the fact that .Net Core is Open Source, and its code source is available on GitHub.

The promise that I see coming, is all the new block that could be coming along with it (Compiler…) would also end up as Open Source components!

These are great times to be working on MS tehcnologies!

VERY happy coding everyone!