Profiling SQL Server in .NET

The main tool for profiling SQL Server is, of course, SQL Server Profiler. You can, however, achieve more or less the same results using .NET, I’ll show you how.

First, you need to have assemblies Microsoft.SqlServer.ConnectionInfo and Microsoft.SqlServer.ConnectionInfoExtended at hand, which are normally found in C:\Program Files\Microsoft SQL Server\120\SDK\Assemblies (for SQL Server 2014), if you installed the Shared Management Objects package from the SQL Server Feature Pack (again, this link is for SQL Server 2014, but there are feature packs for each version of SQL Server).

Then, write something like this:

var connInfo = new SqlConnectionInfo(@".\SQLEXPRESS");

//connInfo.UserName = "";

//connInfo.Password = "";

 

using (var reader = new TraceServer())

{

    reader.InitializeAsReader(connInfo, @"C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Profiler\Templates\Microsoft SQL Server\120\Standard.tdf");

 

    while (reader.Read() == true)

    {

        for (var i = 1; i < reader.FieldCount; ++i)

        {

            Console.Write(reader.GetName(i));

            Console.Write(": ");

            Console.WriteLine(reader.GetValue(i));

        }

 

        Console.WriteLine();

    }

}

And this is it. You will get a new entry for each event that happens on the server, such as SQL being run, etc. Among others, you get the following information:

  • ApplicationName: the name of the application that is executing the SQL, as supplied in its connection string;
  • NTUserName: the Windows user name of the connected user;
  • LoginName: the SQL Server login name of the connected user;
  • Duration: the request duration;
  • SPID: the executing Server Process ID;
  • StartTime: the start timestamp of the request;
  • EndTime: the end timestamp;
  • TextData: textual data, like, SQL.

One thing to keep in mind is that you need to pass a valid SQL Server Profiler template for the InitializeAsReader method. You can add one of the existing templates to your Visual Studio project, set it to copy to the output folder, and reference it locally, if you prefer, otherwise, you will need to know the full path where it is installed (C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Profiler\Templates\Microsoft SQL Server\120 is for SQL Server 2014).

SharePoint Pitfalls: GUID Formats

SharePoint uses GUIDs extensively. The problem is, it accepts them in different formats, in different locations:

  • The ListId and ListName properties of the DataFormWebPart, feature, site column definitions, solution manifests, all expect a GUID in the {A1ADD3D1-B21F-4F93-9B86-B1FE332424D0} format (inside { });
  • In an Elements.xml file or in a Parameter inside a data source, use B8381C7D-3B8D-46D8-8E40-C96E1FF4C308;
  • In the URL, you need to replace for %2D, { for %7B and } for %7D, as in %7BA1ADD3D1%2DB21F%2D4F93%2D9B86%2DB1FE332424D0%7D;
  • In feature receivers tokens and in New-SPTrustedSecurityTokenIssuer and the likes, GUIDs have to be in lowercase ($SharePoint.Type.edd0669b-2393-4fe6-988d-17a2De06c6e4.FullName$).

SharePoint Pitfalls: Master Pages in Page Layouts

When you deploy a page layout, you may want to add your own master page as well. I find it useful to add my own custom master pages and reference them directly, in the same or a dependent feature. You might be surprised, however, that it doesn’t work exactly how you’d expect!

The issue is, page layouts will ignore silently anything in the MasterPageFile attribute if it isn’t one of the standard tokens for the system or custom master pages. ~masterurl/default.master and ~masterurl/custom.master. The solution is to have a code behind class and specify the master page in the OnPreInit method (anywhere else won’t work):

protected override void OnPreInit(EventArgs e)

{

    base.OnPreInit(e);

 

    this.MasterPageFile = "~site/_catalogs/masterpage/CustomMasterPage.master":

}

SharePoint Pitfalls Index

This page will list all of my posts dedicated to SharePoint pitfalls. It will be updated regularly.

  1. Creating a Visual Studio Project Without SharePoint Locally Installed
  2. Save Publishing Site as Template Option Missing
  3. Publishing Pages in Document Libraries Other Than Pages

SharePoint Pitfalls: Publishing Pages in Document Libraries Other Than Pages

This one is a classic: the SharePoint Publishing feature in a Publishing Site creates a document library by the name of Pages; this is where you can store your publishing pages.

A common request is to have more of these document libraries, that is because we cannot create publishing pages anywhere else. The problem is, it is unsupported, God knows why!

What you can do is rename the document library to something else. SharePoint will look for the library id in the site’s property bag, under __PagesListId, so only need to update this value accordingly:

web.AllProperties["__PagesListId"] = newDocLibId.ToString();

web.Update();

Now, there are some solutions over the Internet that claim to go around this limitation, but none of them is supported, so proceed with care!

Case Study: Comparing ASP.NET Web Forms and MVC Implementations

Introduction

Apparently, I am the last ASP.NET Web Forms developer in the whole World, which makes me kind of sad… anyway, after much crying, I decided to try out something: a comparison of Web Forms and MVC to solve a real life problem! Now, I only needed a problem to solve… Then, a colleague of mine came questioning me about captchas, so I thought, why not use it as my example? And here we are!

Everyone is familiar with captchas. They are a way to prevent the automated use of web forms, so as to make sure that it is indeed an human that is providing the information. There are lots of implementations out there, and I don’t claim that mine is better or worse, I just implemented it in a couple of hours as an exercise.

Core Library

I designed a couple of classes, framework-agnostic, to hold my abstractions and sample implementations. These are:

Common

A succinct description is in order.

CaptchaSecretPersister

The contract for storing a secret key. Defines two methods, Store and Retrieve.

SessionCaptchaSecretPersister

An implementation of CaptchaSecretPersister that stores the secret key in the ASP.NET session.

CaptchaImageTransformer

The contract for transforming an image. Only has a single method, Transform.

NullCaptchaImageTransformer

Inherits from CaptchaImageTransformer, but doesn’t do anything.

CaptchaSecretGenerator

The contract for generating a new secret key (GetSecret).

RandomCaptchaSecretGenerator

An implementation of CaptchaSecretGenerator that generates a series of random letters.

CaptchaImageProducer

Base class for producing an image with a given secret key, dimensions, colors and an optional image transformer. Only has a single method, GetImage.

GdiCaptchaImageProducer

An implementation of CaptchaImageProducer that uses GDI+.

CaptchaSecretValidator

Base contract for secret key validation. Only defines a method, Validate.

CaseInsensitiveCaptchaSecretValidator

A case-insensitive string comparison implementation of CaptchaSecretValidator.

And here is their code:

public abstract class CaptchaSecretPersister

{

    public abstract void Store(String secret);

 

    public abstract String Retrieve();

}

 

public sealed class SessionCaptchaSecretPersister : CaptchaSecretPersister

{

    public static readonly CaptchaSecretPersister Instance = new SessionCaptchaSecretPersister();

 

    internal const String Key = "Captcha";

 

    public override void Store(String secret)

    {

        HttpContext.Current.Session[Key] = secret;

    }

 

    public override String Retrieve()

    {

        return HttpContext.Current.Session[Key] as String;

    }

}

 

public abstract class CaptchaImageTransformer

{

    public abstract void Transform(Graphics g);

}

 

public sealed class NullCaptchaImageTransformer : CaptchaImageTransformer

{

    public static readonly CaptchaImageTransformer Instance = new NullCaptchaImageTransformer();

 

    public override void Transform(Graphics g)

    {

        //do nothing

    }

}

 

public abstract class CaptchaSecretGenerator

{

    public abstract String GetSecret(UInt32 length);

}

 

public sealed class RandomCaptchaSecretGenerator : CaptchaSecretGenerator

{

    public static readonly CaptchaSecretGenerator Instance = new RandomCaptchaSecretGenerator();

 

    public override String GetSecret(UInt32 length)

    {

        var builder = new StringBuilder();

        var rand = new Random();

 

        for (var i = 0; i < length; i++)

        {

            var ch = (Char)('A' + rand.Next(26));

            builder.Append(ch);

        }

 

        return builder.ToString();

    }

}

 

public abstract class CaptchaImageProducer

{

    public abstract Image GetImage(Int32 width, Int32 height, String secret, Color foreColor, Color backColor, CaptchaImageTransformer transformer);

}

 

public sealed class GdiCaptchaImageProducer : CaptchaImageProducer

{

    public static readonly CaptchaImageProducer Instance = new GdiCaptchaImageProducer();

 

    public override Image GetImage(Int32 width, Int32 height, String secret, Color foreColor, Color backColor, CaptchaImageTransformer transformer)

    {

        var img = new Bitmap(width, height, PixelFormat.Format32bppArgb);

 

        using (var graphics = Graphics.FromImage(img))

        using (var font = new Font(FontFamily.GenericSansSerif, 10F))

        using (var color = new SolidBrush(foreColor))

        {

            graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

            graphics.Clear(backColor);

            graphics.DrawString(secret, font, color, 0F, 0F);

 

            if (transformer != null)

            {

                transformer.Transform(graphics);

            }

 

            return img;

        }

    }

}

 

public abstract class CaptchaSecretValidator

{

    public abstract Boolean Validate(String storedSecret, String secret);

}

 

public sealed class CaseInsensitiveCaptchaSecretValidator : CaptchaSecretValidator

{

    public static readonly CaptchaSecretValidator Instance = new CaseInsensitiveCaptchaSecretValidator();

 

    public override Boolean Validate(String storedSecret, String secret)

    {

        return String.Equals(storedSecret, secret, StringComparison.OrdinalIgnoreCase);

    }

}

Noteworthy:

  • Base classes are always abstract;
  • Actual implementations are sealed, stateless, and therefore define a static read only field, to avoid multiple instantiations.

Both implementations, Web Forms and MVC, will use these classes.

Web Forms

So let’s start playing. Web Forms has the concept of validators. A validator must implement interface IValidator, and a BaseValidator class exists to make the task easier. When a form is submitted by a control that triggers validation, such as Button, all registered validators (Page.Validators) of the same validation group (ValidationGroup) as the trigger control are fired (Validate is called). The page will be considered valid if all validators have their IsValid property set to true. Knowing this, I created a custom control to display the captcha image and perform its validation:

public sealed class CaptchaImage : WebControl, IValidator

{

    public CaptchaImage() : base(HtmlTextWriterTag.Img)

    {

        this.CaptchaSecretGenerator = RandomCaptchaSecretGenerator.Instance;

        this.CaptchaImageTransformer = NullCaptchaImageTransformer.Instance;

        this.CaptchaImageProducer = GdiCaptchaImageProducer.Instance;

        this.CaptchaSecretPersister = SessionCaptchaSecretPersister.Instance;

        this.CaptchaSecretValidator = CaseInsensitiveCaptchaSecretValidator.Instance;

 

        this.CaptchaLength = 4;

        this.CaptchaFormat = ImageFormat.Png;

 

        this.ForeColor = Color.Black;

        this.BackColor = Color.Transparent;

        this.AlternateText = String.Empty;

        this.ControlToSetError = String.Empty;

        this.ControlToValidate = String.Empty;

 

        (this as IValidator).IsValid = true;

    }

 

    public CaptchaSecretPersister CaptchaSecretPersister { get; set; }

 

    public CaptchaSecretGenerator CaptchaSecretGenerator { get; set; }

 

    public CaptchaImageTransformer CaptchaImageTransformer { get; set; }

 

    public CaptchaImageProducer CaptchaImageProducer { get; set; }

 

    public CaptchaSecretValidator CaptchaSecretValidator { get; set; }

 

    [DefaultValue("")]

    public String AlternateText { get; set; }

 

    [DefaultValue(4)]

    public UInt32 CaptchaLength { get; set; }

 

    [DefaultValue(typeof(ImageFormat), "Png")]

    public ImageFormat CaptchaFormat { get; set; }

 

    [DefaultValue("")]

    [IDReferenceProperty]

    [TypeConverter(typeof(ControlIDConverter))]

    public String ControlToValidate { get; set; }

 

    [DefaultValue("")]

    [IDReferenceProperty]

    [TypeConverter(typeof(ControlIDConverter))]

    public String ControlToSetError { get; set; }

 

    [DefaultValue("")]

    public String ErrorMessage { get; set; }

 

 

    public event EventHandler ValidationSuccess;

    public event EventHandler ValidationFailure;

    public event EventHandler ValidationComplete;

 

    private void OnValidationSuccess()

    {

        var handler = this.ValidationSuccess;

 

        if (handler != null)

        {

            handler(this, EventArgs.Empty);

        }

    }

 

    private void OnValidationComplete()

    {

        var handler = this.ValidationComplete;

 

        if (handler != null)

        {

            handler(this, EventArgs.Empty);

        }

    }

 

    private void OnValidationFailure()

    {

        var handler = this.ValidationFailure;

 

        if (handler != null)

        {

            handler(this, EventArgs.Empty);

        }

    }

    

    private ITextControl FindTextControl(String id)

    {

        return this.NamingContainer.FindControl(id) as ITextControl;

    }

 

    protected override void OnInit(EventArgs e)

    {

        if (this.Enabled == true)

        {

            this.Page.Validators.Add(this);

        }

 

        base.OnInit(e);

    }

 

    protected override void Render(HtmlTextWriter writer)

    {

        var secret = this.CaptchaSecretGenerator.GetSecret(this.CaptchaLength);

 

        this.CaptchaPersister.Store(secret);

 

        using (var img = this.CaptchaImageProducer.GetImage((Int32)this.Width.Value, (Int32)this.Height.Value, secret, this.ForeColor, this.BackColor, this.CaptchaImageTransformer))

        using (var stream = new MemoryStream())

        {

            img.Save(stream, this.CaptchaFormat);

 

            this.Attributes[HtmlTextWriterAttribute.Src.ToString().ToLower()] = String.Format("data:image/{0};base64,{1}", this.CaptchaFormat.ToString().ToLower(), Convert.ToBase64String(stream.ToArray()));

            this.Attributes[HtmlTextWriterAttribute.Alt.ToString().ToLower()] = this.AlternateText;

        }

 

        base.Render(writer);

 

        var val = this as IValidator;

 

        if (val.IsValid == false)

        {

            var errorControl = this.FindTextControl(this.ControlToSetError);

 

            if (errorControl != null)

            {

                errorControl.Text = this.ErrorMessage;

            }

            else

            {

                writer.Write(this.ErrorMessage);

            }

        }

    }

 

    Boolean IValidator.IsValid { get; set; }

 

    void IValidator.Validate()

    {

        var val = this as IValidator;

        val.IsValid = true;

 

        var secretControl = this.FindTextControl(this.ControlToValidate);

        

        if (secretControl != null)

        {

            var storedSecret = this.CaptchaSecretPersister.Retrieve();

 

            val.IsValid = this.CaptchaSecretValidator.Validate(storedSecret, secretControl.Text);

 

            if (val.IsValid == true)

            {

                this.OnValidationSuccess();

            }

            else

            {

                this.OnValidationFailure();

            }

 

            this.OnValidationComplete();

        }

    }

}

The CaptchaImage class inherits from WebControl, so that we can leverage some of its properties (ForeColor, BackColor), and defines a containing tag of IMG.

In its constructor, all relevant properties are instantiated to sensible defaults, these include a number of properties for the core library classes (CaptchaSecretPersister, CaptchaSecretGenerator, CaptchaImageProducer, CaptchaImageTransformer and CaptchaSecretValidator). Other important properties are:

  • ErrorMessage: the message to display in case of a validation error;
  • AlternateText: the image’s ALT text;
  • CaptchaLength: the desired length of the secret key; the default is 4;
  • CaptchaFormat: the image format of choice, where the default is ImageFormat.Png;
  • ControlToValidate: the required ID of a server-side control containing text (must implement ITextControl);
  • ControlToSetError: an optional ID for a control that can take text (must implement ITextControl too), which will be used to set the ErrorMessage value.

The IsValid property, from IValidator, is implemented privately because most of the time we do not want to mess with it. Another inherited property, Enabled, can be used to turn off validation.

Then we have three events:

  • ValidationSuccess: raised when the validation occurs and is successful;
  • ValidationFailure: raised when a failed validation occurs;
  • ValidationComplete: always raised when a validation is performed, regardless of its outcome.

When the control loads, OnInit is called, and it registers itself with the Validators collection, this is a required step. In Render, it generates a secret key, stores it, produces an image from it and renders it as an inline image using the Data URI format. It is the same approach that I talked about a number of times before. When the control receives a validation request, the Validate method is called, and the provided key is validated against the stored one.

A typical usage would be like this:

<web:CaptchaImage runat="server" ID="captcha" Width="50px" Height="25px" BackColor="Blue" AlternateText="Captcha riddle" ControlToValidate="text" ErrorMessage="Invalid captcha" OnValidationSuccess="OnSuccess" OnValidationFailure="OnFailure" OnValidationComplete="OnComplete" />

Whereas the registered event handlers might be:

protected void OnSuccess(Object sender, EventArgs e)

{

    this.captcha.Visible = false;

}

 

protected void OnFailure(Object sender, EventArgs e)

{

}

 

protected void OnComplete(Object sender, EventArgs e)

{

}

Easy, don’t you think? Now, let’s move on to MVC!

MVC

In MVC we don’t really have controls, because of the separation of concerns and all that. The closest we have at the moment are extension methods, let’s have a look at the Captcha method:

public static IHtmlString Captcha(this HtmlHelper html, Int32 width, Int32 height, UInt32 length = 4, String alternateText = "", ImageFormat captchaFormat = null, Color? foreColor = null, Color? backColor = null)

{

    var captchaSecretGenerator = DependencyResolver.Current.GetService<CaptchaSecretGenerator>();

    var captchaSecretPersister = DependencyResolver.Current.GetService<CaptchaSecretPersister>();

    var captchaImageProducer = DependencyResolver.Current.GetService<CaptchaImageProducer>();

    var captchaImageTransformer = DependencyResolver.Current.GetService<CaptchaImageTransformer>();

 

    var secret = captchaSecretGenerator.GetSecret(length);

 

    captchaSecretPersister.Store(secret);

 

    using (var img = captchaImageProducer.GetImage(width, height, secret, foreColor ?? Color.Black, backColor ?? Color.Transparent, captchaImageTransformer))

    using (var stream = new MemoryStream())

    {

        img.Save(stream, captchaFormat ?? ImageFormat.Png);

 

        var tag = String.Format("<img src=\"data:image/{0};base64,{1}\" width=\"{1}\" height=\"{2}\" alt=\"{3}\"/>", (captchaFormat ?? ImageFormat.Png).ToString().ToLower(), Convert.ToBase64String(stream.ToArray()), width, height, alternateText);

 

        return new HtmlString(tag);

    }

}

It is unpractical to pass all components, so we are relying on MVC’s built-in dependency injection framework. I used Microsoft Unity as my Inversion of Control (IoC) container, and to make it integrate with MVC, I installed the Unity.Mvc NuGet package:

image

Then I had to register the actual implementations for my services, this is usually done in the App_Start\UnityConfig.cs file’s RegisterTypes method:

container.RegisterInstance<CaptchaSecretGenerator>(RandomCaptchaSecretGenerator.Instance);

container.RegisterInstance<CaptchaImageProducer>(GdiCaptchaImageProducer.Instance);

container.RegisterInstance<CaptchaSecretPersister>(SessionCaptchaSecretPersister.Instance);

container.RegisterInstance<CaptchaImageTransformer>(NullCaptchaImageTransformer.Instance);

container.RegisterInstance<CaptchaSecretValidator>(CaseInsensitiveCaptchaSecretValidator.Instance);

The code from Unity.Mvc automatically hooks Unity with the DependencyResolver class, so we don’t have to do it ourselves. For an example implementation, I once wrote a post on it that you can check out, if you are curious.

Now, we need two things: a view and a controller. Let’s look at the view first (simplified):

@Html.Captcha(50, 25)

@using (Html.BeginForm("Validate", "Home"))

{

    @Html.TextBox("secret")

    <button>Validate</button>

}

As you can see, the form will post to the Validate method of an HomeController. The output of the Captcha method doesn’t have to be inside the form, because it merely renders an IMG tag.

As for the controller, the Validate method is pretty straightforward:

public ActionResult Validate(String secret)

{

    var captchaPersister = DependencyResolver.Current.GetService<CaptchaSecretPersister>();

    var captchaSecretValidator = DependencyResolver.Current.GetService<CaptchaSecretValidator>();

 

    var storedSecret = captchaPersister.Retrieve();

    var isValid = captchaSecretValidator.Validate(storedSecret, secret);

 

    if (isValid == true)

    {

        return this.View("Success");

    }

    else

    {

        return this.View("Failure");

    }

}

It tries to obtain the services from the DependencyResolver, validates the supplied secret key and then returns the proper view, accordingly.

Conclusion

So, which implementation do you prefer? The Web Forms one, unsurprisingly, only needs a single class, CaptchaImage, and, of course, a host page; the assembly containing it can be referenced by other projects and used very easily. As for the MVC version, we need to have the Captcha extension method, the IoC bootstrapping/registration code, a view and a controller with a Validate method similar to the one presented. The extension method and the controller may come from another referenced assembly, it needs some work, but can definitely be done.

Of course, this is a sample implementation, things can be done in a myriad of alternative ways. I’d like to hear from you about the problems with this particular implementation, and alternative ways to do it. By the way, feel free to use and modify the code anyway you want to, I will soon make it available in my GitHub account.

Automating Microsoft Azure with PowerShell Review

Introduction

I was again asked by Packt Publishing to review one of their books, this time, it was Automating Microsoft Azure with PowerShell. It came in good time, because I am starting to use Azure more and more, and PowerShell is a timesaver – actually, it is the only way to do lots of things. I have reviewed other books on Azure, which you can find at my blog, here.

The book starts with an introductory chapter, where PowerShell and Azure are introduced, and then goes to the real thing. Not all APIs are covered, namely, Machine Learning, DocumentDB, BizTalk, Stream Analytics, etc, etc, which is not really surprising, since it seems that every month a new service pops out. The book is ~150 pages long, distributed between 10 chapters, which is perfectly acceptable for the amount of topics it covers. The target audience is clearly administrators with little knowledge of Azure.

The author is John Chapman, which can be followed at Twitter as @chapmanjw.

Chapter 1: Getting Started with Azure and PowerShell

This chapter offers an introduction to PowerShell and how to install the Azure integration, retrieve subscription files and connecting to Azure. At the end of it we see how to create a blank website using PowerShell.

Chapter 2: Managing Azure Storage with PowerShell

This one is about storage. It explains about the major storage options that Azure has to offer – Table storage, Blobs, Queues and Files. Basic operations are discussed and we are presented with an example of a backup system.

Chapter 3: Managing Azure Virtual Machines with PowerShell

Next we have a discussion of the APIs available for the management of virtual machines (VMs). We learn how to create the many kinds of VMs existing in the Azure gallery, and performing all the typical operations, including creating snapshots and managing its storage.

Chapter 4: Managing Azure SQL Databases with PowerShell

In this chapter we learn how to create SQL servers and databases, configuring access to them, executing queries and finally exporting and importing data to and from.

Chapter 5: Deploying and Managing Azure Websites

Chapter 5 is about Azure Websites, the old name for Azure Web Apps. We learn how to create websites and how to provision them. Here I got the feeling that a lot is missing.

Chapter 6: Managing Azure Virtual Networks with PowerShell

A short chapter on how to configure virtual networks. Again, a lot more could be said on this.

Chapter 7: Managing Azure Traffic Manager with PowerShell

Azure Traffic Manager is Azure’s load-balancing mechanism. It explains how to configure websites for using the different load balancing techniques and load balancing profiles.

Chapter 8: Managing Azure Cloud Services with PowerShell

Cloud Services is another way to host VMs. The chapter explains how to create and manage cloud services, roles and endpoints and how retrieve Remote Desktop connection files.

Chapter 9: Managing Azure Active Directory with PowerShell

This chapter explains the basics of the Azure Active Directory (AD), the main authoritative source of identities in an Azure virtual network. We learn how to create and configure the basic options of an AD, managing users, groups and password policies. The example at the end of the chapter is about bulk creating users in the AD.

Chapter 10: Automating Azure with PowerShell

The final chapter talks about one of the automation mechanisms in Azure. We learn how to create an automation account and how to add runbooks to it.

Conclusion

The book is very succinct, and some topics would require substantially more coverage. It does provide some information enough to cover the basic usage of the covered Azure services.

What’s New in C# 6.0

Introduction

Visual Studio 2015 will be officially RTM on July 20th, Microsoft announced. With it comes a new version of the .NET framework (actually, two), .NET 5.0, and inside of it, support for a new version of the C# language, C# 6.0. Yeah, the numbers don’t match, keep that in mind! Winking smile

If you are curious, Visual Studio 2015 will also include .NET 4.6. This will provide a migration path for those of us who are stuck with .NET 4.x code and can’t afford the breaking changes that .NET 5 will introduce. More on this in a future post.

For the moment, I am going to talk about what’s new in C# 6.0, in no particular order. Some of you may be familiar with parts of it, and some might even be expecting a bit more, but unfortunately, some features that were previously announced didn’t make it to the final version.

Auto-Property Initializers

It is now possible to provide an initial value for auto-implemented properties without resorting to a custom constructor. Here’s how, in two examples:

public class MyClass

{

    public int MyNumericProperty { get; set; } = 1;

    public bool MyBooleanOtherProperty { get; set; } = (MyNumericProperty > 0);

}

Did you notice how we can even use simple expressions in the initialization block? Pretty cool!

Getter-Only Auto-Properties

Similar to the previous example, we can now have getter-only properties, that is, without any kind of setter. We just need to provide an initialization value:

public class Math

{

    public static double PI { get; } = 3.14159265359;

}

Alternatively, we can define its value in a constructor:

public class Math

{

    public static double PI { get; }


    static Math()

    {

        PI = 3.14159265359;

    }

}

Expression-Bodied Methods and Properties

Not sure of the actual interest of this one, but, hey, it’s here: the ability to supply the body for properties and methods from simple expressions.

public class MyClass

{

    public int Add(int a, int b) => a + b;


    public string TimeOfDay => DateTime.Now.TimeOfDay;

}

nameof Expressions

nameof expressions avoid the need to hardcode names or use complex reflection or LINQ expression tricks. It’s better to show it in action:

void ThrowArgumentNullExceptionUsingNameOf(string param1)

{

    throw new ArgumentNullException(nameof(param1));    //"param1"

}


var className = nameof(MyClass);                    //"MyClass"


var propertyName = nameof(myInstance.Property);    //"Property"

Exception Filters

This is about the ability to filter exceptions in a catch block based on more than the exception class itself:

try

{

    //…

}

catch (MyException ex) if (ex.Code == 42)

{

    //…

}

catch (MyOtherException ex) if (Check(ex))

{

    //…

}

Notice that you can use methods in the filter clause, not just simple comparisons.

String Interpolation

This is one of my favorites: adding field, variable and method calls in the middle of a string, and having it interpreted at runtime:

var variable = $"This is i: {i}";

var property = $"A property: {this.Property}";

var method = $"Filename: {Path.GetFullPath(filename)}";

var format = $"Short date: {DateTime.Now:d}";

Very similar to String.Format, but easier to use.

Null-Conditional Operator

Another personal favorite! No need for repeated null checks in deep property accesses or event handlers, the compiler takes care of it for us:

var p = myInstance?.myProperty?.myNestedProperty;


public event EventHandler MyEvent;


public void OnMyEvent(EventArgs e)

{

    this.MyEvent?.Invoke(this, e);

}

If either myInstance or myProperty are null, null will be returned. It even works for events, as you can see.

Using Static Members

Besides bringing namespace types into context, using can now be used to do the same with static methods! For instance, take Console.WriteLine:

using WriteLine = System.Console.WriteLine;

//static method WriteLine only

WriteLine("Hello, World");



using System.Linq.Enumerable;

//all extension methods of Enumerable

var numbers = new [] { 1, 2, 3 };

var even = numbers.Where(x => (x % 2) == 0);

This will come in handy, to avoid type clashes. We just import the methods we’re interested in.

Index Member Syntax

A new notation for creating dictionary instances is introduced:

var dict = new Dictionary<int, string>

{

    [1] = "one",

    [2] = "two"

};

Async in Catch and Finally Blocks

Using async in a catch or finally block is now valid:

try

{

    //...

}

catch (Exception exception)

{

    await LogAsync(exception);

}

finally

{

    await ReleaseAsync();

}

Extension Add Methods in Collection Initializers

Starting with C# 4 (.NET 4), we could use an explicit enumeration syntax for creating collections (actually, any kind of classes that provided an Add method with a compatible parameters). Now extension methods are supported as well:

public static void Add(this ICollection<string> col, int i)

{

    col.Add(i.ToString());

}


var col = new List<string>{ 1, 2, 3 };

Here we are creating a List of strings, but we have an extension method that knows how to add integers to collections of strings.

Conclusion

All weighed up, there are some nice additions, others I don’t really see the point, but eventually I may.

You can read everything about it in the Roslyn site at GitHub: https://github.com/dotnet/roslyn and https://github.com/dotnet/roslyn/wiki/Languages-features-in-C%23-6-and-VB-14.

 

Generating GDI+ Images for ASP.NET MVC Views

This post is about applying the same technique I presented for ASP.NET Web Forms, but this time for MVC.

We need to have an ActionResult that does the actual work of converting whatever we draw in the Graphics context into an image with an inline Data URI. Here’s a possible solution, where you only specify the dimensions of the image to be generated:

public sealed class InlineImageResult : ActionResult

{

    private readonly Image bmp;

 

    public InlineImageResult(Int32 width, Int32 height)

    {

        //the PixelFormat argument is required if we want to have transparency

        this.bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);

 

        this.Graphics = Graphics.FromImage(this.bmp);

        //for higher quality

        this.Graphics.CompositingQuality = CompositingQuality.HighQuality;

        this.Graphics.SmoothingMode = SmoothingMode.HighQuality;

        this.Graphics.InterpolationMode = InterpolationMode.High;

        //make the background transparent

        this.Graphics.Clear(Color.Transparent);

    }

 

    public Graphics Graphics { get; private set; }

 

    public override void ExecuteResult(ControllerContext context)

    {

        using (this.bmp)

        using (this.Graphics)

        using (var stream = new MemoryStream())

        {

            //PNG because of transparency

            var format = ImageFormat.Png;

 

            this.bmp.Save(stream, format);

 

            var img = String.Format("<img src=\"data:image/{0};base64,{1}\"/>", format.ToString().ToLower(), Convert.ToBase64String(stream.ToArray()));

 

            context.HttpContext.Response.Write(img);

        }

    }

}

Now, we need to create an instance of this result and draw in it, in a controller’s action method:

[ChildActionOnly]

public ActionResult Image()

{

    var result = new InlineImageResult(200, 50);

    result.Graphics.DrawString("Hello, World!", new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Blue), 0, 0);

 

    return result;

}

Notice the ChildActionOnly attribute: it tells MVC that this action method is only meant to be used in child action (RenderAction) call, not as a stand-alone action, like this:

<p>

    @{ Html.RenderAction("Image"); }

</p>

As you can see, this provides a very convenient way to generate images on the fly. You just need to learn about the drawing methods in GDI+.