2012-11-27

Specflow presentation @ NetPonto

Last saturday I did a presentation at the NetPonto community about Specflow testing (in Portuguese). The demos source code can be found at my github page.

2012-10-29

Forcing a Culture in the business logic

Not exactly a new topic, but a reminder. In my opinion, it's a good practise for your application business logic not to assume that it will be run in a particular Windows configuration, namely a specific culture. An "innocent" ToString() or Parse() method call in a double or DateTime struct is all that takes to break your code. Last week that happened at the office, some of our unit tests were only failing on some development machines. It turned out that some of team members have Windows configured to use GB English regional settings, while others have been using PT Portuguese settings. One approach to fix this is to force a culture in all calls of these methods (US English, for instance), but I think that is boring and easy to overlook. I prefer to force the culture for all calls, something like:

Thread.CurrentThread.CurrentCulture = 
   new CultureInfo("en-US");

 Here's how I have been doing it, depending on the component type.

WCF Service

Usually, I would put the code line in the Application_Start() method of the Global.asax class, since it would apply to every service in the project. However, the last time I've did it, we were using Castle Windsor for dependency injection, and this doesn't seem to work, as the container instantiates the service object in another thread. Solution: put the line in the service constructor.

Since we are also using ThreadPool for some of the tasks, I also had to add the line to the callback method.

Yes, I could also have used the <globalization> tag in the web.config, but that would imply activating ASP.NET compatibility in WCF, which I didn't want to (no problem on doing so, but I just wanted to avoid unnecessary entropy).

Console Application / Windows Service

Usually, I would just put the line in the Program class Main method, but since we are using TopShelf to abstract some of the Windows service boilerplate code, I had to put it elsewhere. Basically, in the WhenStarted() callback.

NUnit Test

Unit tests are basically class libraries, so there is no central point method. The best I came up with was putting the code in the StartUp method, for every unit test class. Since I'm being lazy, in reality I've only added it in every test class that was failing because of culture settings.

EF POCO objects and WCF

We have recently started to use Entity Framework using a Code First approach, including POCO classes. However, when we tried to use POCO object classes as parameters of web service calls, we got the following exception:

System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://tempuri.org/:foo. The InnerException message was 'Type 'System.Data.Entity.DynamicProxies.FooClass_F952F109218D94AD325682E75C75F0EFF0D59311269F52F267E249FB9D8F7196' with data contract name 'FooClass_F952F109218D94AD325682E75C75F0EFF0D59311269F52F267E249FB9D8F7196:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

What's happening? Well, it happens that a runtime, POCO objects are not really POCO, but proxies that wrap the original POCO objects. WCF knows the POCO type, but not the subtype of the proxy class. How to fix it? There are several approaches, we just opted by a simple workaround: all our classes that need to be passed as parameters for a web service calls now implement ICloneable interface and are cloned just before the call.

Perhaps a more elegant approach would be using a specific class for the parameter of the WCF service and implement a mapper between the two types, but if you need a quick workaround the clone approach does the trick.

2012-10-15

Using Fiddler for local requests

Although not documented here, an alternative way to use Fiddler to proxy local requests is to replace "localhost" in URLs by "127.0.0.1." (notice the extra dot!).

2012-10-10

Don't forget to GO after ALTER TRIGGER

Today I found peculiar issue while doing SQL scripts...

A couple of months ago, I did an SQL script that, among other things had an ALTER TRIGGER statement followed by an UPDATE statement. This particular trigger was supposed to add data to a history table. For some strange reason though, I was having trouble doing a particular update statement, because it was being undone. After a couple of hours, I found the cultrip: there was an update statement inside the trigger. What happened? I didn't do a GO statement between the trigger and the update statement.
(Yeah, maybe this is obvious for all the SQL gurus out there, but it was not for me. Lesson learnt. :))


2012-10-09

svn:ignore for Visual Studio

Similar to other source control systems, you can add an ignore list of files that should not be under source control. In subversion, this is the svn:ignore property. If you are using Visual Studio and the VisualSVN plugin, this can be achieved in the following way:

  • Right-click the solution > VisualSVN > Properties...
  • Click on New... > Advanced
    • In the Property name drop-down select svn:ignore
    • In the Property value text box put the list of expressions you want to ignore, separated by the space character.
Here is an example (work in progress, probably this will have the same content as my .gitignore):

*.suo
*.user
*.dbmdl
*.resharper
aspnet_client
thumbs.db
bin
Bin
obj
Obj
TestResults
debug
Debug
release
Release


You'll end up with something like this (TortoiseSVN):


Edit (2014-02-20)

Fixed an error in my example, each entry must be in a single line.

Update (2014-05-21)

Updated list.

2012-09-07

Could not load file or assembly ...


If you ever caught the infamous error:

Server Error in '/ws' Application.

Could not load file or assembly 'App_Web_6sedkqth, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

And application pool recycling, site restart or even the good old iisreset won't fix it, then it might be a problem with ASP.NET temporary files.

The solution is stopping IIS (alternatively, you can just stop a specific application pool):

iisreset /stop

Deleting all the files (or part of them, if just stopped a specific application pool) from the following directory:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

And restart IIS:

iisreset /start

Note: this is basically a repost from my previous blog.

TFS: what to do when someone in company leaves or their PC dies?

The title is self-explaning :)

cd C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE
tf workspace /delete workspace;mydomain\myuser /s:http://server:port/tfs_instance_name
 

A deleted workspace cannot be recovered.
Workspace 'workspace;mydomain\myuser' on server 'http://server:port/tfs_instance_name' has 32 pending change(s).
Are you sure you want to delete the workspace? (Yes/No) y

Typically the workspace has the same name as your machine.

Note: this is basically a repost from my previous blog.

Windows Azure Emulator with Microsoft Source Control

It appears that the Windows Azure emulator that comes with Windows Azure SDK doesn't like services with the Web.config file with the read-only attribute. It happens that that's exactly what SourceSafe and TFS do when a file is not checked-out. Do these guys work in the same company? Or does the Azure team use Subversion and git? ;)

Note: this is basically a repost from my previous blog.

Death to the .user!

A couple months ago, one of my VS solutions would just crash with a specific project. After a couple of hours, I've found the solution: close Visual Studio, delete all the "*.csproj.user" files, and reload the solution. My theory is that this was caused by TFS merges, since this solution had a few dozen projects and was frequently updated by various users, which in turn caused frequent conflicts. It's no wonder that these files are listed in .gitignore.

Note: this is basically a repost from my previous blog.

Country/language codes for CultureInfo

If you work frequently with internationalization/globalization you've probably questioned which cultures are supported in the CultureInfo class. As far as I know, there is no such page in MSDN. However, for the record, the code is composed by a two letter lower case ISO code for language (e.g. "pt", "en") and two letter upper case ISO code for country (e.g. "PT", "US"), separated by the hyphen character ("-"). Both of these codes are documented in Wikipedia as ISO 3166-1 alpha 2 and ISO 639-1, respectively.

Note: this is basically a repost from my previous blog.

Update (2013-03-12)

If you need to match cultures with countries (via the ISO 3 letter code), the following MSDN page might be useful: National Language Support (NLS) API Reference.

SessionState and ViewState in ASP.NET

Fine tuning ASP.NET applications is a very extensive topic. However, some features are enabled and may not be needed. For example, Session and ViewState are not really needed for simple pages (i.e. if your ASP.NET page is basically hosting a single page application in Silverlight). To do this, just open the .aspx (markup) file and add the last two attributes:

<%@ Page Language="c#" AutoEventWireup="true" CodeBehind="Foo.aspx.cs" Inherits="Acme.Foobar" EnableSessionState="false" EnableViewState="false" %>

Note: this is basically a repost from my previous blog.

.gitignore for Visual Studio 2010

If you are using an IDE to develop your applications (who doesn't these days?), you have probably stumbled on a lot of files that are automatically generated which you don't really need to add to source control. If you are using Visual Studio and plugins/extensions (such as ReSharper and NuGet) these are quite some files.  The ".gitignore" file was designed to solve just that: putting it in the root of your source control directory will prevent "git add ." commands from adding those files/directories. My current file is based on this one from github, with extensions from this one from stackoverflow, and finally a line that I added for ReSharper user files.

You can download the file here (be sure to remove the ".txt" extension).

Note: this is basically a repost from my previous blog.

2012-09-04

Creating a GIT repository in Windows for cloud storage

One of the cool uses for cloud storage (such as Dropbox, SkyDrive or Google Drive) is as a git source code repository for your pet projects. Here's how to get started it in Windows.
But first, a couple of assumptions:

  • You have in your first machine a "Projects/Sandbox" folder with an existing project (e.g. a Visual Studio solution) and a "Dropbox" folder synched with the cloud; on the second machine a "Projects2" without any code and " Dropbox2" folder synched with the cloud. "dropbox" is the name of the remote repository.
  • You've previously added you git "bin" directory to your PATH environment variable.
  • You have Powershell installed (it's available for Windows XP or later). And yes, you could use the "classic" command prompt, but it's not as cool :) Really, if you're not familiar it's a good time to start using it.
So, launch Powershell and do the following:

# creating the remote repository
cd "C:\Dropbox\repositories"
git init --bare sandbox.git

# creating the local repository and first commit
cd "C:\Projects\Sandbox"
git init .
git remote add gdrive "C:\Dropbox\repositories\sandbox.git"
git add .
git commit -m "Initial commit"
git push dropbox master

# on a second machine, getting the repository
cd "C:\Projects2"
git clone -o gdrive "C:\Dropbox\repositories\sandbox.git"

Since I'm no expert on git, feel free to drop any comment about it Also, these instructions are adapted from this post, and mostly unchanged, as Powershell uses a UNIX-like syntax (actually, it uses aliases to do this, but you get the same result).

Edit (2012-09-05):
It seems that Google Drive has some issues syncing some files (e.g. HEAD and config) on Windows 7. The problem has been reported by other users. A workaround I found is to restart Google Drive when that happens, but that's not really interesting. I don't have these problems with Dropbox, though, so I recommend it instead. Haven't tested with SkyDrive yet.

2012-08-31

Useful libraries and tools

This is one of the features I was missing from Community Server (and previous versions of Blogger): static pages. I've added two useful pages. The first one links to libraries that at some point I've used and recommend (currently only .NET and Silverlight, but eventually I might extend it to include JavaScript). It includes the license to know whether you can use on your project. The second one links to auxiliary tools that a developer should keep at hand.

2012-08-30

Unable to cast COM object of type...

Was the error that bugged me for three days, any time I tried to connect to a database in SQL Server Management Studio. Re-installing the Management Studio or the whole SQL Server wasn't working. Neither the workarounds for registering some specific DLLs, or event (gasp!) changing some GUIDs in the registry. What eventually fixed my problem was running the following command in the command prompt (Administrator Mode) and rebooting:

sfc /scannow

(SFC stands for System File Checker)

It's kind of weird that this issue has been around since 2005, officially reported to Microsoft in 2009 and it's still bugging people today (like me) using Windows 7, Visual Studio 2010 and SQL Server 2008 R2. For the record here is where I found the fix.

Yet Another Hello World

Here is my third blog on software development. Unlike my previous instalments, "Labs" @ XAML-PT and "Labs 2" @ pontoNETpt, this is not dependent on any community, nor will be in Portuguese. Nor it will be called "Labs 3", just my name and where my work mostly is around - .NET. It's a better choice for SEO purposes :) In terms of content, this will mostly follow "Labs 2", basically logging my experiments and issue fixing, in case I might need it in the future, and in the hope that it might useful for someone else.
Regarding my previous blogging, XAML-PT is lost and pontoNETpt is currently down, although it is expected to be up again in the near future (here). My old entries on my personal blog regarding .NET are still available here (in Portuguese).