by Njål

Quick row count from Microsoft SQL Database

 

Recently, I’ve been involved in a cloud provider project where I had to do a row count on a Microsoft SQL Database table with more than 50.000.000 rows in it.

Doing

SELECT COUNT(*) FROM myTable

took about 10 seconds – since it performs a full table scan.

 

Here’s an alternative way (still accurate) of doing it that takes under 1 sec:

SELECT SUM (row_count)
FROM sys.dm_db_partition_stats
WHERE object_id=OBJECT_ID('myTable')   
AND (index_id=0 or index_id=1);

 

You can run this from Microsoft Entity Framework as well:

long total = dbContext.Database.SqlQuery<long>("SELECT SUM (row_count) FROM sys.dm_db_partition_stats WHERE object_id=OBJECT_ID('myTable') AND (index_id=0 or index_id=1);").First();

by Njål

The directory specified for caching compressed content is invalid. Static compression is being disabled.

image

 

After adding this in my web.config (Azure Project)…

<staticContent>
    <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
</staticContent>

…IIS refused to serve any static content – such as js and png files. Log entries in Event Viewer said:

The directory specified for caching compressed content
C:\Users\xxx\AppData\Local\dftmp\Resources\b503ce54-3fba-4772-beaa-415d94ffc214\temp\temp\RoleTemp\iisexpress\IIS Temporary Compressed Files\9ef2ab2d-28fc-4554-a09c-5ba867eb1d19 is invalid.
Static compression is being disabled.

The problem was that .svg files were already added to the staticContent list in my applicationHost.config – but still – the error message shown in the Event Viewer is pretty useless. There is nothing wrong with the directory specified to store compressed content.

So if you suddenly get this error – undo any changes in Web.config (remove all config under staticContent) and restart IIS (Express).

by Andreas

Email validation – finally a .NET regular expression that works!

imageNote: this is only relevant for .NET 3.5 and earlier. In .NET 4 the System.Net.Mail.MailAddress class includes validation and will throw an exception if instantiated with an invalid address. See comments below. 

Validating an email address sounds simple, and it really is! Until your fancy validator is released into the real world and people’s actual email addresses start pouring in, instead of the three email addresses you’ve been testing while developing: your work address, your Gmail address and an old Yahoo address you created in 2001.

chris-@somedomain.com
!habla-hobla%wow@somedomain.com
!def!xyz%abc@example.com
joe_blow_@somedomain.com
love/hate=relationship@example.com
$ilovemoney1234@example.com

They are, believe it or not, all valid according to the RFC spec. That doesn’t mean that you’ll be allowed to actually register them everywhere. Some (most?) email providers have their own rules that are much stricter than the specifications, simply because it makes no sense to allow all sorts of rubbish.

But if you’re writing a system allowing people to register using their email address, and you confirm their ownership of the given address by sending a confirmation email you really can’t be any stricter than the RFC and this is where the problem lies. I was also under the impression that “blah, how often would THAT become an issue?!”, but recently I got feedback from three different users within just a few weeks that they were unable to register. So I thought I’d better find a regular expression that actually works.

I’ve tried them all.. examples from Microsoft, Stack Overflow, random forums, cooked up my own and also converted a couple from other languages. It wasn’t until yesterday I stumbled across an old blog post by Phil Haack called I Knew How To Validate An Email Address Until I Read The RFC. He did all the hard work (i.e. reading the #¤%&”¤ RFC specs), and came up with an expression that so far seems to be working. So I thought I’d better save it here, because I know I will need this one again:

string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
                + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
                + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
            
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
return regex.IsMatch(emailAddress);

 

So thanks to Phil for his efforts! Let us know if anyone finds a flaw in this one as well…

by Njål

Intelligencia UrlRewriter – Ashx Sessions getting lost

image

When debugging a Windows Azure website I kept getting null Sessions for my ashx pages. They worked perfectly on  IISExpress, so I thought this was a Azure flaw. It turned out that it was IIS 7.5 + Url Rewriting (I’m using the Intelligencia module) that caused the problem.

 

 

After adding this to my Web.config everything worked like expected again – also in IIS 7.5

<configuration>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" >
     ...
     ...
  </system.Webserver>
</configuration>

Also – make sure your ashx code implements IRequiresSessionState

public class ApiHandler : IHttpHandler, IRequiresSessionState
{
}
by Andreas

Microsoft.Office.Interop.Word – replace bookmarks programmatically

Replacing bookmarks in Word documents programmatically is fairly straight forward. The Microsoft.Office.Interop.Word namespace has a set of methods that allows simple access, but there is one short-coming: when replacing the bookmark, the bookmark itself is completely removed. This might be fine in most situations, but in our case we wanted to allow our users to set the bookmark values over and over again, within the same document.

This required a bit of research, but eventually I managed to get it to work (and it turned out to be extremely simple..). The following code should have enough comments to explain the details of what’s going on, but I ended up having to get a reference to the original bookmark in the Word document (god bless the COM..). This bookmark is then replaced with the desired text (e.g. [CompanyName] => “Contoso”). Now, this is where it gets a bit interesting. I re-add the bookmark, as per this article but before that’s done I set the new range values based on the length of the replacement word (“Contoso”). The result is that the bookmark encapsulates your new text, keeps its original name (“CompanyName”) and most importantly: stays within its original StoryType. The StoryType is a read-only property determining which part of a document the bookmark is found, for instance the body, header or footer. Without this, the default is used and you will not be able to support bookmarks anywhere else than within the main body of your Word document.

 

public void BookMarkReplaceInternal(string bookmark, string file, string newText)
{
    Microsoft.Office.Interop.Word.Application _app = null;
    Microsoft.Office.Interop.Word.Document _doc = null;

    try
    {
        // open document
        _app = new Microsoft.Office.Interop.Word.Application();
        _doc = _app.Documents.Open(file, _missing, _missing, _missing, _missing, _missing, _missing, _missing, _missing, _missing);

        // find bookmark
        var bm = _doc.Bookmarks[bookmark];

        // get COM object reference
        object rng = bm.Range;

        // get original bookmark start position and name
        var bmStart = bm.Range.Start;
        var bookmarkName = bm.Name;

        // replace bookmark with new text
        bm.Range.Text = newText;

        // calculate bookmark range (use original bookmark start position, add length of new contents 
        ((Microsoft.Office.Interop.Word.Range)rng).Start = bmStart;
        ((Microsoft.Office.Interop.Word.Range)rng).End = bmStart + newText.Length;
        
        // re-add bookmark with updated range
        _doc.Bookmarks.Add(bookmarkName, rng);

        _doc.Save();
    }
    finally
    {
        if (_doc != null) _doc.Close(true, _missing, _missing);
        if (_app != null) _app.Quit(true, _missing, _missing);
    }
}
by Njål

Visual Studio 2012 Fakes – ShimNotSupportedException when debugging tests

 

image

When testing VS2012 Ultimate I tried to use the new Microsoft Fakes framework to mock a simple static method. Running the test went fine, but I kept getting a ShimNotSupportedException when debugging the test. 

After goggling and trying all kinds of stuff I finally managed to debug the test by following these steps:

  1. Deleted the local.testsettings file (both in VS and on disk)

  2. Deleted the <solution>.vsmdi file (both in VS and on disk)
  3. Made sure IntelliTrace had these settings (not sure if this mattered):

    image

  4. Restarted VS2012
  5. Made sure that no .testsettings file were selected here

    image

Debugging of tests now works fine!
(Running/debugging the tests from Resharper still does not work – but I can live with this.)

I tried to add a new .testsettings file (with CodeAnalysis and everything else disabled) – but this makes the ShimNotSupportedException reappear again.

Similar Fakes/ShimNotSupportedException/Debug issues have been reported to MS, so I hope they get this resolved soon.

———————————————————————————————————–

Another sad fact is that the Fakes framework is only available in the Ultimate edition of Visual Studio 2012 – which retails at over USD 13,000. This makes absolutely no sense at all. ALL developers should use unit testing as part of their tool belt – and isolating tests using a mocking framework plays a key role. Microsoft Moles could be used for free in the previous VS 2010 version – and it worked great. This is very disappointing.

Please vote for this issue here: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2919309-provide-microsoft-fakes-with-all-visual-studio-edi

by Njål

Telenor 3G modem + Python + C# = SMS Gateway

Bilde av Option Icon 225 modemThe past year we have been using an Android phone running SmsSync as a SMS gateway (connected to the server through USB). This setup requires that SMSSync is started & running and that the phone is sharing internet through the usb cable +++. If the server rebooted – then the SMS Gateway wouldn’t work until we set it up again. Not an ideal setup.

So I set out to replace it with something that was robust, stable and reboot friendly. It turned out the solution to this problem was in my desk drawer. An old Telenor 3G Option Icon 225 modem that we didn’t use anymore. I inserted a Network Norway SIM card into it – and shoved it into a usb port. The modem was locked and would only accept Telenor SIM cards. I should have guessed it. 

Based on this blogpost by Dogbert – I was able to unlock the modem using these steps (I had to use pywin 2.1.4):

 

  1. Install python 2.6.x (32 bit version): http://www.python.org/download/releases/2.6/
  2. Install pywin32 – 2.1.4 – for python 2.6: http://sourceforge.net/projects/pywin32/files/
  3. Install pyserial: http://sourceforge.net/projects/pyserial/files/
  4. Download the unlocker (http://sites.google.com/site/dogber1/blag/msm-unlock-v1.6.zip) and unpack it (e.g. into the directory C:\msm)
  5. Download a firmware update for the 3G modem from Option or T-Mobile
  6. Unpack the firmware update into the directory used above (e.g. C:\msm)
  7. IMPORTANT: The superfire.exe file of the update is packed. For the newest update, the superfire.exe can be used as it is.
  8. Remove the SIM card from the modem and plug it in . Make sure that you have the latest drivers from the option website installed before you start msm_unlock.py. Also, close all the tools for the stick (‘connection manager’ etc.).
  9. Write down the unlock code. Unplug the stick, replug it and apply the unlock code with msm_apply.py. If the unlock code is not accepted, search the comments for a posting by “muxx” – he has given detailed instructions on how to manually enter the unlock code.
  10. Unplug and replug the stick once more and you’ve got yourself an unlocked 3G modem.

After unlocking the modem it was time to test it. I first started out in Putty – connecting to the COM3 port – which it was running at. Sending some AT* commands worked fine.

I then downloaded Stefay Mayr’s excellent .NET GSMCOMM Library – and imported the DLL’s into a new Visual Studio project. It turned out sending an SMS was extremely easy:

 

//Connect to modem
var comm = new GsmCommMain(3, 9600, 1000); //ComPort, BaudRate, Timeout
comm.Open();

//Send SMS
var sms = new SmsSubmitPdu("Unicode ÆØÅ \n\n Supported!", "+4795441144");
comm.SendMessage(sms);

 

The gateway has been tested the last couple of days – and it seems to work flawlessly.

by Njål

C#: Removing duplicate entries using LINQ

Here’s a pretty neat line of code that removes duplicate entries (ID is specified by you) from a IEnumerable:

class MyTestObject{
    public string MyKey;
    public int SomeValue;
    ...
}


//myList contains MyTestObjects - some of these objects
//have the same MyKey value, and I only want objects with unique MyKey values

var uniqueCollection = myList.GroupBy(x => x.MyKey).Select(y => y.First());

by Andreas

IsNullOrEmpty() extension for generic lists (List<T>)

The .IsNullOrEmpty() and .IsNullOrWhitespace() utility methods for string objects really helps cleaning up the code compared to the old fashion

if (myString == null || myString.Trim().Equals(""))
  ...

This should definately have been implemented for other classes as well, like the List or the Dictionary. But until that happens, add your own extensions:

    public static class Extensions
    {
        public static bool IsNullOrEmpty<T>(this List<T> list)
        {
            return list == null || !list.Any();
        }

        public static bool IsNullOrEmpty<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
        {
            return dictionary == null || !dictionary.Any();
        }

    }

Then you’ll be able to check whether your List is null or empty in a single statement:

List<long> myNumericValues = new List<long>();
if (myNumericValues.IsNullOrEmpty())
{
    ...
}
by thorhalvor

NCrunch = time saved

NCrunch is an automated continuous testing tool for Visual Studio .NET. It takes responsibility for running automated tests so that you don’t have to.

Instead of going through these steps when doing Test Driven Development:

  1. Write tests
  2. Run tests
  3. Write code
  4. Run tests
  5. Refactor code
  6. Run tests

NCrunch will take care of all the “Run tests” and you can therefore concentrate on writing and refactoring your tests and code.

How does it work?

I will give some simple examples below but you can also go to NCrunch’s About-page where you can see a video.

First of all, will you get new column with red/green/black dots on every line of code.

Green = Covered by successfull test
Red =  Covered by test but failing
Black  = indicating that there are no tests for this line of code.

It will test while you write and you get feedback while coding. No need to compile or save the document.

A specific example of the most basic steps is shown below:

A: You see a green dot for every line of code. That means at least one test is testing these lines and it is also successful.
B: If I hold the mouse over the dot at line 45 I can see that there are 4 passings tests for this part of code.
C: If I comment line 43-46, the color of the dots will immediately change because some tests are now failing. And some code is untested.
D: Holding the mouse over the red dot at line 42 gives a summary of why it is red. This part of code is covered by 3 passing tests and 1 failing.

This was only the basics of NCrunch. Other things it can do is for example: Code Coveage, Performance metrics, Inline Exception Details, Paralell Execution ++

My advice is therefore: Download, Install and Enable it. Try to not focus on it in the beginning, just “let it do its job”, get familiar with the new “dots” and explore its features step by step.