Category Archives: Blog

CSC : warning CS1685: The predefined type ‘System.Runtime.CompilerServices.ExtensionAttribute’ is defined in multiple assemblies in the global alias

In one of my ASP.NET MVC 5 projects that targets .NET 4.5.1, I noticed that I was getting a new compiler warning at build time:

CSC : warning CS1685: The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias

On a hunch, I fired up JetBrains dotPeek, loaded all of the assemblies in my bin directory, and did a Type search (Navigate -> Go to Everything / Type...). It turns out that Json.NET actually implements its own version of ExtensionAttribute:

// Type: System.Runtime.CompilerServices.ExtensionAttribute
// Assembly: Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
// MVID: 2CCEAD7E-60D5-4E86-87A2-3819FCE6C567
// Assembly location: (redacted)\bin\Newtonsoft.Json.dll

using System;

namespace System.Runtime.CompilerServices
{
  /// <remarks>
  /// This attribute allows us to define extension methods without
  ///             requiring .NET Framework 3.5. For more information, see the section,
  ///             <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>,
  ///             of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a>
  ///             column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>,
  ///             issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>.
  /// 
  /// </remarks>
  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
  internal sealed class ExtensionAttribute : Attribute
  {
  }
}

Back in my web project, I looked at the properties for Newtonsoft.Json and noticed that the Runtime Version was set to v2.0.something. After reading through this Json.NET discussion thread on the matter, I decided to reinstall the NuGet package:

PM> Update-Package Newtonsoft.Json -Reinstall

And voilà! Newtonsoft.Json‘s properties once again showed that Runtime Version points to v4.0.30319, and the compiler warning went away. This modified my .csproj file, and diffing it immediately revealed the source of the problem. Newtonsoft.Json‘s hint path had somehow been set to this:

<HintPath>..packages\Newtonsoft.Json.6.0.3\lib\net20\Newtonsoft.Json.dll</HintPath>

Instead of this:

<HintPath>..packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>

Hope this helps.

The File Nesting extension in Visual Studio 2013 Ultimate

If you don’t know about the File Nesting extension from Visual Studio, watch the demo video on Channel9. It’s a very nice productivity tool.

After installing the File Nesting extension in Visual Studio 2013 Ultimate, right-clicking and nesting individual files worked, but right-clicking on, e.g., the Scripts folder and selecting File Nesting -> Auto-nest selected items did nothing.

Flummoxed, I had a peek in Tools -> Options, and lo and behold, there is a settings page for File Nesting. By default, all of the rules were disabled. Once I tweaked the options, auto-nesting started working as expected.

Setting these options to true made auto-nest work for me.

Setting these options to true made auto-nest work for me.

Just a little tip that will hopefully save you some headaches.

Using EFProf and MiniProfiler simultaneously in an ASP.NET MVC 5.1, Entity Framework 5 Code-First Project

We’re already using the excellent Entity Framework Profiler (EFProf) to gauge EF performance in our application. However, we wanted more information about the overall application performance, and thus turned to MiniProfiler.

Installing MiniProfiler was easy enough, but upon running the application, I got an error:

Unable to determine the provider name for connection of type ‘HibernatingRhinos.Profiler.Appender.ProfiledDataAccess.ProfiledConnection`1[[System.Data.SqlClient.SqlClientFactory, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]‘.

Hmm. That’s weird. So I commented out my EFProf initialization code:

//EntityFrameworkProfiler.Initialize();

And MiniProfiler worked fine.

I then wrote a test application to try to isolate the problem, and got a different error:

System.NotSupportedException: Underlying ProfiledCommand is not cloneable

It turns out that MiniProfiler expects its DbCommand to implement ICloneable:

/// <summary>
/// clone the command, entity framework expects this behaviour.
/// </summary>
/// The .
public ProfiledDbCommand Clone()
{ // EF expects ICloneable
    var tail = _command as ICloneable;
    if (tail == null) throw new NotSupportedException("Underlying " + _command.GetType().Name + " is not cloneable");
    return new ProfiledDbCommand((DbCommand)tail.Clone(), _connection, _profiler);
}

Unfortunately, dotPeek reveals that EFProf’s ProfiledCommand does not implement ICloneable:

namespace HibernatingRhinos.Profiler.Appender.ProfiledDataAccess
{
  public class ProfiledCommand : DbCommand
  {
  // ...
  }
}

Fortunately, there is a workaround: initialize MiniProfiler before initializing EFProf. Or, in source code form, do this in Global.asax:

protected void Application_Start()
{
    // ...

    MiniProfiler.Settings.SqlFormatter = new StackExchange.Profiling.SqlFormatters.SqlServerFormatter();
    MiniProfilerEF.Initialize();

    EntityFrameworkProfiler.Initialize();
}

Instead of this:

protected void Application_Start()
{
    // ...

    EntityFrameworkProfiler.Initialize();

    MiniProfiler.Settings.SqlFormatter = new StackExchange.Profiling.SqlFormatters.SqlServerFormatter();
    MiniProfilerEF.Initialize();
}

And EFProf and MiniProfiler will coexist happily together.

(Note that this means EFProf initialization happens in Global.asax instead of in PreApplicationStartMethod installed by the EFProf NuGet package.)

Version information:

  • ASP.NET MVC 5.1.0
  • Entity Framework 5.0.0
  • EFProf Build 2225
  • MiniProfiler 2.1.0

Awesome customer service at 47 Hats

Over the holiday lull, I have been devouring Patrick McKenzie’s blog about all things microISV. One of the entries was a book review for Bob Walsh’s “MicroISV Sites that Sell!” e-book. Patrick highly recommended the book, so I figured, “What the heck? I expect the advice it contains to return my expenditure many times over.”

Without delay, I headed over to 47 Hats to purchase the title. Unfortunately, I was unable to add it to the cart, so I emailed Bob to ask whether the title was still available, and if not, how to obtain a copy.

Imagine my surprise when he promptly replied with a free copy of the book and a cheerful message that said, “Enjoy!” You see, it was actually New Years Eve. Unbeknownst to me, Bob was editing and rearranging his site, so the cart functionality was temporarily broken. Rather than telling me to wait a few hours and try again, he gifted me a copy so that I could get on with my day. It was a classy gesture, and it perfectly exemplified Patrick’s exhortations for outstanding customer service.

So, Bob, thank you for the excellent customer service, and thank you for the book!

Now, back to reading.

Unable to start debugging on the web server

If you’re getting this error when trying to debug an ASP.NET Web application on IIS7 or greater, check the system.webServer element in your Web.config.  If you have the httpErrors element configured, you won’t be able to debug.  For your local dev environment, remove or comment out the httpErrors element, and you should be good to go.

<WAG>
From my ASP.NET 1.1 days, I have a hazy memory of Visual Studio’s debugging startup process requesting a bogus URL on the target Web site, and then doing something with the 404 response prior to launching the debugging session.  Obviously, if it’s expecting a 404 or the page to contain certain text, redirecting to an error page will prevent you from launching the debugger successfully.
</WAG>

If you happen to know specifically why this happens, please leave a comment (or contact me if comments are closed), and I will gladly update this entry.

Cannot find 'servicereferences.clientconfig' in the .xap application package

I’m new to Silverlight development.  I was banging my head against the wall, trying to figure out what I had done to break our Silverlight app.  After all, the only changes I made were to add a Service Reference to a new WCF service, and to initialize the WCF proxy in App.xaml.cs.

Fortunately, after a little Google sleuthing, I came upon the solution, as shared by David Sandor:

[The code] is trying to read from the ServiceReferences.config file that can not be read at that point in the Silverlight application’s lifecycle.

Bingo, that was it.  Moving my proxy initialization code to Application_Startup fixed the problem.

It makes sense now, but, man, these types of bugs can be maddening.

ImageCodecInfo: Encoder and Decoder information

If you’ve ever been curious about the GDI+ encoders and decoders available on your system, you can call ImageCodecInfo.GetImageEncoders() and ImageCodecInfo.GetImageDecoders(), respectively, to find out more:

Encoders:

ImageCodecInfo.GetImageEncoders().ToList().ForEach(
    enc =>
    {
        Console.WriteLine(enc.FormatDescription);
        Console.WriteLine("tCLSID: {0}", enc.Clsid);
        Console.WriteLine("tCodecName: {0}", enc.CodecName);
        Console.WriteLine("tFilenameExtension: {0}", enc.FilenameExtension);
        Console.WriteLine("tFlags: {0}", enc.Flags);
        Console.WriteLine("tFormatDescription: {0}", enc.FormatDescription);
        Console.WriteLine("tFormatID: {0}", enc.FormatID);
        Console.WriteLine("tMimeType: {0}", enc.MimeType);
        Console.WriteLine("tVersion: {0}", enc.Version);
    });

On my Windows Server 2008 machine, the above code returns the following:

BMP
        CLSID: 557cf400-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in BMP Codec
        FilenameExtension: *.BMP;*.DIB;*.RLE
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: BMP
        FormatID: b96b3cab-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/bmp
        Version: 1
JPEG
        CLSID: 557cf401-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in JPEG Codec
        FilenameExtension: *.JPG;*.JPEG;*.JPE;*.JFIF
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: JPEG
        FormatID: b96b3cae-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/jpeg
        Version: 1
GIF
        CLSID: 557cf402-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in GIF Codec
        FilenameExtension: *.GIF
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: GIF
        FormatID: b96b3cb0-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/gif
        Version: 1
TIFF
        CLSID: 557cf405-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in TIFF Codec
        FilenameExtension: *.TIF;*.TIFF
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: TIFF
        FormatID: b96b3cb1-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/tiff
        Version: 1
PNG
        CLSID: 557cf406-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in PNG Codec
        FilenameExtension: *.PNG
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: PNG
        FormatID: b96b3caf-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/png
        Version: 1

Decoders:

ImageCodecInfo.GetImageDecoders().ToList().ForEach(
    enc =>
    {
        Console.WriteLine(enc.FormatDescription);
        Console.WriteLine("tCLSID: {0}", enc.Clsid);
        Console.WriteLine("tCodecName: {0}", enc.CodecName);
        Console.WriteLine("tFilenameExtension: {0}", enc.FilenameExtension);
        Console.WriteLine("tFlags: {0}", enc.Flags);
        Console.WriteLine("tFormatDescription: {0}", enc.FormatDescription);
        Console.WriteLine("tFormatID: {0}", enc.FormatID);
        Console.WriteLine("tMimeType: {0}", enc.MimeType);
        Console.WriteLine("tVersion: {0}", enc.Version);
    });

Again, on my Windows Server 2008 box, the above code returns the following:

BMP
        CLSID: 557cf400-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in BMP Codec
        FilenameExtension: *.BMP;*.DIB;*.RLE
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: BMP
        FormatID: b96b3cab-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/bmp
        Version: 1
JPEG
        CLSID: 557cf401-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in JPEG Codec
        FilenameExtension: *.JPG;*.JPEG;*.JPE;*.JFIF
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: JPEG
        FormatID: b96b3cae-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/jpeg
        Version: 1
GIF
        CLSID: 557cf402-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in GIF Codec
        FilenameExtension: *.GIF
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: GIF
        FormatID: b96b3cb0-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/gif
        Version: 1
EMF
        CLSID: 557cf403-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in EMF Codec
        FilenameExtension: *.EMF
        Flags: Decoder, SupportBitmap, Builtin
        FormatDescription: EMF
        FormatID: b96b3cac-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/x-emf
        Version: 1
WMF
        CLSID: 557cf404-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in WMF Codec
        FilenameExtension: *.WMF
        Flags: Decoder, SupportBitmap, Builtin
        FormatDescription: WMF
        FormatID: b96b3cad-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/x-wmf
        Version: 1
TIFF
        CLSID: 557cf405-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in TIFF Codec
        FilenameExtension: *.TIF;*.TIFF
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: TIFF
        FormatID: b96b3cb1-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/tiff
        Version: 1
PNG
        CLSID: 557cf406-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in PNG Codec
        FilenameExtension: *.PNG
        Flags: Encoder, Decoder, SupportBitmap, Builtin
        FormatDescription: PNG
        FormatID: b96b3caf-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/png
        Version: 1
ICO
        CLSID: 557cf407-1a04-11d3-9a73-0000f81ef32e
        CodecName: Built-in ICO Codec
        FilenameExtension: *.ICO
        Flags: Decoder, SupportBitmap, Builtin
        FormatDescription: ICO
        FormatID: b96b3cb5-0728-11d3-9d7b-0000f81ef32e
        MimeType: image/x-icon
        Version: 1

ImageCodecInfo is located in System.Drawing.Imaging.

Why am I writing this? On more than one occasion, I have found myself writing code to enumerate these values; I’d rather just have a place to look them up.

Project Euler: Problem 1 (in F#)

I have already done Project Euler Problem 1 in C#. Since I am currently learning F#, I thought I’d give it another shot:

let rec sumMultiples(data) =
    match data with
    | [] -> 0
    | head::tail when (head % 3 = 0 || head % 5 = 0) -> head + sumMultiples(tail)
    | _::tail -> sumMultiples(tail)

It produces the correct result, but seeing as how LINQ considerably simplified the C# version, and since I am a complete F# and functional programming n00b, I suspected there must be a better way.

I hate it when I’m right.

This solution is better, in my opinion:

List.sum(List.filter (fun n -> n % 3 = 0 || n % 5 = 0) [1..999]);;

Anyhow, I know I have a lot left to learn, so I’m looking forward to exploring the functional side of programming in the coming months.

Update 2010-01-08: Ooh, better yet:

[1..999] |> List.filter (fun n -> n % 3 = 0 || n % 5 = 0) |> List.sum;;

Pipelining FTW!