Figuring out what assembly is trying to load a specific (missing) DLL version in .NET

If you ‘re running into an error similar to this one:

The type initializer for 'YourNamespace.Program' threw an exception.
---> System.IO.FileLoadException: Could not load file or assembly 'log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=8774c74090335470' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
   at YourNamespace.Program..cctor()
   --- End of inner exception stack trace ---
   at YourNamespace.Program.Main()

Then post is for you!

What’s happening here is that Program is referencing a log4net dll version 1.2.15.0. But another, currently unidentified, DLL that Program is referencing is looking for version 1.2.11.0 .

There are two ways of fixing this.

  1. Adding an assembly redirect in the app.config or web.config
  2. Recompiling the unidentified DLL with log4net version 1.2.15.0

In this post I’ll focus on the recompiling approach. The first thing we need to do is identify the unidentified DLL we talked about above. To do this:

  1. Open the “Developer Command Prompt for VS2015” as an administrator.
    • Not sure if you really need to be an admin; doing it just in case.
  2. Type “fuslogvw” and hit enter
  3. Click the Settings button
  4. Select “Log bind failures to disk” and click OK
  5. Click the “Delete All” button
  6. Make your dll error happen again
  7. Click the Refresh button on fuslogvw
  8. You should see the dll binding failure displayed on the report
  9. Double click the failure.
  10. The report is an HTM file that you can open with your preferred web browser.
  11. This report will tell us the name of the unidentified DLL
  12. You can now recompile the now identified DLL with the same DLL version that your main Program is referencing.
    • If the identified DLL does not belong to you, meaning you can’t recompile it, you need to add an assembly redirect on your app.config or web.config.

TVP Helper for Dapper ORM

I’ve used this TVP (Table Valued Parameter) helper for Dapper for quite some time now and I thought I’d share it here in case someone also thinks it is super cool.

It’s really just a wrapper around the existing AsTableValuedParameter method that comes with Dapper. The wrapper helps you quickly build a DataTable from any type of collection.

With this small helper method:

public SqlMapper.ICustomQueryParameter ToTvp<T>(
    IEnumerable<T> enumerable,
    params Func<T, object>[] columnSelectors)
{
    if (columnSelectors.Length == 0)
    {
        Func<T, object> getSelf = x => x;
        columnSelectors = new[] { getSelf };
    }
    var result = new DataTable();
    foreach (var selector in columnSelectors)
    {
        result.Columns.Add();
    }
    foreach (var item in enumerable)
    {
        var colValues = columnSelectors.Select(selector => selector(item)).ToArray();
        result.Rows.Add(colValues);
    }
    return result.AsTableValuedParameter();
}

You can now create TVP parameters super easy and feed them to Dapper like this:

string[] names = GenerateNames(generatedNamesCount);
var namesTvp = ToTvp(names);
conn.Execute(
    "[dbo].[User_InsertFromSimpleTvp]",
    new {Names = namesTvp},
    commandType: CommandType.StoredProcedure);

 

string[] names = GenerateNames(generatedNamesCount);
User[] users = names.Select(x => new User {Name = x, Email = x + "@1800.com"}).ToArray();
var usersTvp = ToTvp(users, x => x.Name, x => x.Email);
conn.Execute(
    "[dbo].[User_InsertFromComplexTvp]",
    new {Users = usersTvp},
    commandType: CommandType.StoredProcedure);

git push hangs when windows git client pushes to TeamFoundation Git Server

Look at the bottom of this blog post for the solution to this issue.

I’m using the regular Windows git client (1.9.5.msysgit.1 downloaded from git-scm.com) to push a repository with a 46KB file to a remote repository that is a Team Foundation Server Git repository.

When I do “git push” the console hangs for about 5 minutes (sometimes more) and then gives me a 401 error:

$ ls -la
total 29
drwxr-xr-x 4 pliska Administ 4096 Jun 22 14:02 .
drwxr-xr-x 13 pliska Administ 4096 Jun 19 11:40 ..
drwxr-xr-x 12 pliska Administ 4096 Jun 22 14:03 .git
-rw-r--r-- 1 pliska Administ 46157 Nov 19 2014 46KB.vsix

$ git push origin master -f
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 45.01 KiB | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)

The console hangs here for at least 5 minutes, after which I get these new lines:

error: RPC failed; result=7, HTTP code = 401
fatal: The remote end hung up unexpectedly
Everything up-to-date

I know my credentials are correct. When I enter wrong credentials I get an immediate error and don’t even see the first line from git push (the “Counting Objects” line).

I have been able to get this to work when

  1. (smaller file) The only file in the repo is 20KB in size, OR
  2. (use MS client and server) Instead of using the regular git client (1.9.5.msysgit.1), I use Visual Studio 2013, OR
  3. (use non-MS client and server) I push to a github remote (like this one).

From the three facts above. I’m thinking some of these things might be the cause of the issue:

  1. The TFS server does not like how the msysgit client sends the credentials. (But then why does it work fine for smaller files?)
  2. TFS does an extra credentials check for large files
  3. The TFS server has a setting that is not allowing large pushes into it. (But then why does it return a 401 error?)

After I commented on this Microsoft blog, Saeed from Microsoft suggested I use fiddler to see what is going on at the network level. I’m seeing the following:

git-401

We’re still not sure what this means, I need to research further. Saeed mentioned he has seen this when there is a misconfigured load balancer or proxy in the network, but my TFS server is not behind any of those. I’ll see if I can remote into the box and push directly to the local server just to see what happens.

I’ve googled this issue quite a bit and from this post’s suggestion, I ran the following command: git config http.postBuffer 524288000. Did this not fix it.

This page suggested this command: git config –global sendpack.sideband false . It also had a hex editor hack, I tried both with no success.

WE FIGURED OUT A SOLUTION!

The latest stable git client that you currently get from git-scm.com is version 1.9.5 and is three months old. If you use the current release candidate version 2.4.4.2 (you can download it here), things work fine.

I didn’t know this build existed, I don’t think a link exists to it from git-scm.com . Saeed pointed me in the right direction. Thank you very much Saeed! You were incredibly helpful!

Setting up ninject 3.2 on a WCF service

This is a step by step guide on how to create a WCF Service using Ninject to resolve (inject) its dependencies.

We start from scratch by creating a New C# WCF Service Project and end with an example of the service being instantiated with its dependencies resolved by Ninject. The code that resulted from this guide can be found here.

1. Create the WCF service project

new-wcf-service-project

2. Run Install-Package Ninject.Web.Common.WebHost from the package manager console.

  1. Make sure that you are using NuGet 1.6 or higher. Using an older version will result in missing references.
  2. Figured out this step after reading this.

3. Run Install-Package Ninject.Extensions.Wcf

  1. Figured this step out by looking at the Ninject examples on github

4. Teak your svc’s markup so the ServiceHost element has this attribute: Factory=”Ninject.Extensions.Wcf.NinjectServiceHostFactory”

&lt;%@ ServiceHost
     Language=&quot;C#&quot;
     Debug=&quot;true&quot;
     Service=&quot;WcfServiceWithNinject.Service1&quot;
     CodeBehind=&quot;Service1.svc.cs&quot;
     Factory=&quot;Ninject.Extensions.Wcf.NinjectServiceHostFactory&quot; %&gt;

You’re all done!

To see it in action, let’s create something to inject:

public class Repository : IRepository
{
    public IEnumerable&lt;Widget&gt; GetWidgets()
    {
        return new [] {
            new Widget {Name = &quot;Widget1&quot;, Price=11},
            new Widget {Name = &quot;Widget2&quot;, Price=22}
        };
    }
}
public interface IRepository
{
    IEnumerable&lt;Widget&gt; GetWidgets();
}
public class Widget
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

We now need to add the Ninject binding in App_Start\NinjectWebCommon.cs. This file was generated when you installed the Ninject.Web.Common.WebHost NuGet package. At the bottom of the file you’ll find the RegisterServices method, add the binding there:

...
private static void RegisterServices(IKernel kernel)
{
    kernel.Bind&lt;IRepository&gt;().To&lt;Repository&gt;();
}  
...      

Let’s make Service1 (automatically generated when you created the new WCF Service project) use the Repository:

public class Service1 : IService1
{
    private IRepository _repo;
    public Service1(IRepository repo)
    {
        _repo = repo;
    }
    public string TellMeHowManyWidgets()
    {
        return string.Format(
            &quot;We have {0} widgets.&quot;, _repo.GetWidgets().Count());
    }

Remember to add the new method to the service interface as well:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    string TellMeHowManyWidgets();
    ...

We’re finally ready to see this working. Select the Service1.svc file on the Solution Explorer and hit F5, this will make the WCF Test Client appear. Double click the TellMeHowManyWidgets method and hit the Invoke button.

ninject-generated-wcf-servcie

There it is! Our service replied with “We have 2 widgets”. This proves that the IRepository dependency was fulfilled by Ninject with a Repository object.

“Highlight all occurrences of selected word” extension on Visual Studio 2013

I love the Highlight all occurrences of selected word Visual Sutdio 2012 extension. But yeah, it does not run on Visual Studio 2013… unless you tweak it.

Download the tweaked version here.

Or if you want to tweak it yourself, follow these instructions:

  1. Download the extension from the official site. You will get a SelectionHighlight.vsix file.
  2. Rename SelectionHighlight.vsix to SelectionHighlight.zip
  3. Extract the zip file
  4. Open the extension.vsixmanifest file in a text editor
  5. Edit <VisualStudio Version=”11.0″> to <VisualStudio Version=”12.0″>. Save the file.
  6. Select all the extracted files including your edited one (they are around 6). Zip the files.
  7. Rename the resulting *.zip file to *.vsix.
  8. Double click the .vsix file to install the tweaked extension.

 

 

Validating AD credentials when the user’s password “must be changed at next logon” using C#

We have several AD controllers in our setup. On controllers running Windows Server 2008 R2, this is not an issue. But if your code is hitting AD controllers running Windows server 2003, the PrincipalContext.ValidateCredentials method will always return false on users that have the “user must change password at next logon” checkbox checked; even if the username and password combination is valid.

The code below is a workaround for the Windows 2003 servers. It pretty much unchecks the checkbox, then validates the credentials, and then re-checks the checkbox.

var adContext = new PrincipalContext(ContextType.Domain, adLocation, adContainer, adAdminUsername, adAdminPassword);

var initialValidation = adContext.ValidateCredentials(username, password);
Console.WriteLine("Initial validation returned: " + initialValidation);

if (!initialValidation)
{
    // maybe validation failed because "user must change password at next logon".
    // let's see if that is the case.

    var user = UserPrincipal.FindByIdentity(adContext, username);
    if (user.LastPasswordSet == null)
    {
        // the user must change his password at next logon. So this might be
        // why validation returned false

        // uncheck the "change password" checkbox and attempt validation again

        var deUser = user.GetUnderlyingObject() as DirectoryEntry;
        var property = deUser.Properties["pwdLastSet"];
        property.Value = -1;
        deUser.CommitChanges();

        // property was unset, retry validation
        adContext.ValidateCredentials(username, password);
        Console.WriteLine("Secondary validation returned: " + adContext.ValidateCredentials(username, password));

        // re check the checkbox
        property.Value = 0;
        deUser.CommitChanges();
  }
}

SQL query results into Excel

It is easy to pull data from a MS SQL table or view into excel, the UI is very straight forward for that. But that is not the case when you want a custom sql query to be the one pulling data from the database. 

To do this in Excel 2010, you need to first set up the connection to the database and then set up the query:

Setting up the connection

image

image

 

image

This is where you set the server location, login, AND the database you want to query:

image

Leave the default table empty:

image

Double click your newly created data source

image

Building the Query

The screenshot below pops up automatically when you double click the data source (see screenshot above). We don’t want to add any tables:

image

We want to use our hand written SQL:

image

Enter your SQL:

image

Chances are you’ll run into this, hit ok

image

Your query has been built, hit the exit button:

image

Tell Excel where to put the data from your query:

image

You’re done!

You can now right click on any cell that has data from your query and hit Refresh when you want Excel to pull fresh data from the database:

image

LINQ query to CSV

The C# code below generates a CSV (comma separated value) string with the header row and data obtained from a LINQ query.

For example: A query like this:

dc.Users.Select(u => new
{
    user_id = u.UserId,
    username= u.Username,
    first_name = u.FirstName,
    last_name = u.LastName,
    creation_date = u.CreationDate
});

Would result in a CSV string like this one:

user_id,username,first_name,last_name,creation_date
"abf577a5-dc76-4719-9375-001a445d0c3d","jdoe","John","Doe",2011-03-29T14:50:28
"24b888cf-b02b-413e-8542-007e7ee572a6","jdoe2","John","Doe2",2009-05-29T19:52:32

And now to the code:

var users = dc.Users.Select(u => new
{
    user_id = u.UserId,
    username = u.Username,
    first_name = u.FirstName,
    last_name = u.LastName,
    creation_date = u.CreationDate
}).ToArray();

var usersCsv = GenerateCsv(users);

And make sure the following methods are delcared:

/// <summary>
/// This method generates CSV data out an array of anything. The array
/// elements could be of anonymous type
/// </summary>
private string GenerateCsv(Array items)
{

    var rowType = items.GetType().GetElementType();
    var colNames = rowType.GetProperties().Select(p => p.Name).ToArray();

    // create the header row
    var retVal = new StringBuilder();
    retVal.AppendLine(string.Join(",", colNames));

    // now create the body
    foreach (var row in items)
    {
        var rowItems = new string[colNames.Length];
        for (int i = 0; i < colNames.Length; i++)
            rowItems[i] = this.FormatCell(rowType.GetProperty(colNames[i]).GetValue(row, null));

        retVal.AppendLine(string.Join(",", rowItems));
    }

    return retVal.ToString();
}
private string FormatCell(object item)
{
    if (item == null)
        return "";

    if (item.GetType() == typeof(DateTime))
        return ((DateTime)item).ToUniversalTime().ToString("s");

    return "\"" + item.ToString().Replace("\"", "\"\"") + "\"";
}

Customizing the Contact form in Outlook 2010

Most of my Outlook contacts are personal contacts, not business contacts. So I don’t have their business phone or address. By default the business phone field is the first on the list of phones on the contact form. And the business address is the only one that shows by default.

With a lot more work that what it should be, I was able to change the fields from this:

image

To this:

image

I was only able to do this on New Contacts, I did not continue trying to figure out how to edit my existing contacts to use this new field format.

 

To do so go to Outlook 2010 and add the Developer Menu Item by going to “File > Options > Customize Ribbon“ and select the Developer item on the tree view:

image

Hit the OK button to save your changes.

Go to your contacts and hit the “New Contact” button:

image

 

Change the fields to your liking by hitting on the drop down arrow next to the field name:

image

Go to the Developer item on the Ribbon and select Publish Form As:

image

Give your new form a Display Name and a Form name and hit Publish.

image

The form name is the one you’ll look for when setting the form as the default form, the Display name is the one you’ll see on the “New Contact” button.

Close the “New Contact” window you have open, if it asks you if you want to save changes say no.

image

We now want to make our new published form the default Contact form. To do this , right click on the Contacts folder:

image

Hit properties. Then update the “when posting to this folder, use” field to your new form and hit OK to save your changes:

 

image

Your new contact form will now be used on all new Contacts.

Sadly I could not find a straight forward way to make existing contacts use the new Form. If you figure out how to do this, let me know!

C# controlled lights via USB port

At work, we thought it would be cool if we could turn on siren lights when a server goes down.

Step #1 to make this happen was to be able to control simple electronics from custom code. I love C# and the USB port is what is common now so I researched and found the FT245RL “USB to FIFO” chip. This chip made it really easy for me. It plays well with drivers known by Windows.

I bought the FT245RL from SparkFun on a breakout circuit for ease of soldering. For details about chip, take a look at this DataSheet.

When I plugged in the chip to the USB port, Windows 7 immediately recognized it and installed the drivers for it. You can use a couple of drivers the default is the simpler one to use where it turns the USB port into a virtual serial (COM) port.

Writing to serial ports is really standard so this is the code that outputs a byte through the chip:

private static void WriteByte(byte byteToWrite)
{
    using (SerialPort vcp = new SerialPort())
    {
        vcp.BaudRate = 9600;
        vcp.DataBits = 8;
        vcp.StopBits = StopBits.One;
        vcp.Parity = Parity.None;
        vcp.PortName = &quot;COM5&quot;;

        vcp.Open();

        vcp.Write(new byte[] { byteToWrite }, 0, 1);

        vcp.Close();

    }

}