Friday, 9 September 2011

Exception thrown the first time an NUnit test that opens a SQL connection is run

When running an NUnit test that opens a SQL connection, the first time the test is run you may get an error similar to the following:

System.Data.SqlClient.SqlException : A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - The pipe is being closed.)

Running the test again then passes.

This can happen in this scenario: NUnit has run data access code, creating a connection, then SQL Server is restarted. If this is the case, the cause of the exception is as follows. If SQL Server is restarted after ADO.NET has built a connection using the same connection string as that used by the failing test, ADO.NET will attempt to reuse that connection from the connection pool without checking whether the connection is invalid. Because SQL Server has been restarted the connection is no longer valid and the exception is thrown.

To demonstrate this, restart SQL Server, then run the test. The test will fail. If the test is run again, it will pass. Next, close NUnit, then restart SQL Server and reopen NUnit (in either order) and rerun the test. The test will pass.

Friday, 12 August 2011

Manage Nuget Packages error

I suddenly started getting a weird error when trying to open the Nuget package manager (by right clicking the project in VS Solution Explorer and selecting the Manage Nuget Packages option). A dialogue appears containing the following error message and stack trace:

The composition produced a single composition error, with 2 root causes. The root causes are provided below. Review the CompositionException.Errors property for more detailed information.

1) Not implemented (Exception from HRESULT: 0x80004001 (E_NOTIMPL))

Resulting in: An exception occurred while trying to create an instance of type 'NuGet.VisualStudio.SolutionManager'.

…

It turns out this is a known problem if your solution contains an Installshield LE Setup project.

http://docs.nuget.org/docs/reference/known-issues

The workaround is to temporarily unload all Installshield LE setup projects in the solution. The Nuget package manager should now open correctly. Alternatively, if you close the solution, open a solution that does not contain any Installshield LE setup projects, open the Nuget package manager, then go back to the original solution, Nuget will open fine without unloading the setup projects.

Tuesday, 12 July 2011

WCF CommunicationException TCP error

When trying to get a WCF service working over TCP, if the following CommunicationException is thrown on calling the ServiceHost object’s Open method:

A TCP error (10013: An attempt was made to access a socket in a way forbidden by its access permissions) occurred while listening on IP Endpoint=0.0.0.0:8080.

The likely causes are (1) the endpoint is being used by another running process or (2) a firewall is blocking access to this port.

To resolve this, run the following netstat command to see all sockets in use:

netstat –a

If this endpoint is listed in the output from netstat, try changing the service endpoint address to use a different port. (If the service is running on a computer with Windows Firewall, the Windows Security Alert dialogue may appear - the dialogue provides an option to allow access through the firewall.)

If the error is still being thrown, check that the port is not being blocked by a firewall.

Tuesday, 5 July 2011

How to make NHibernate ignore rows with an incorrect discriminator for an association subclass

If you are mapping a class hierarchy to a single table in NHibernate by using a discriminator column to differentiate between the subclasses, if one of the concrete subclasses is being used as an association for another type you might run into the situation where incorrect data (i.e. discriminator value) in the database causes NHibernate to throw an exception complaining that it cannot find the class. (This can also happen if you are using the where attribute to exclude a reserved entity from being picked up.) The default behaviour is to throw an NHibernate.ObjectNotFoundException exception on accessing a row that cannot be mapped to the expected entity. Alternatively you can tell NHibernate to ignore this situation and substitute a null value for the missing association.
You do this by setting the not-found attribute of the many-to-one element to "ignore”. For example:

<many-to-one class="Engineer" column="EngineerID" name="Engineer" not-found="ignore"></many-to-one>

Monday, 27 June 2011

The end of .NET is in sight?

Since the first week of June there have been a number of internet posts claiming that Microsoft are planning to dump the .NET platform in a bid to be seen as pursuing a platform independent strategy. For example:

http://www.i-programmer.info/professional-programmer/i-programmer/2591-dumping-net-microsofts-madness.html

This article provides a more balanced look at the story:

http://arstechnica.com/microsoft/news/2011/06/windows-8-for-software-developers-the-longhorn-dream-reborn.ars

The Microsoft Windows division have recently announced that they are providing HTML5 and Javascript APIs in Windows 8, and haven’t mentioned any planned new .NET features. As a result, some .NET developers have been demanding to know what Microsoft plans are for .NET. The Microsoft response has been, wait and see – we’ll explain all at the Build event in September. As a result theres a lot of hysteria about .NET being flushed down the toilet.

This announcement has basically been about the UI on Windows clients. The VS team has been working on better HTML5/Javascript support since VS 2010 came out last year. So Microsoft have decided the future of the UI involves HTML5/Javascript. So does virtually every other vendor. I wouldn’t be surprised if they do deprecate WPF and/or Silverlight and replace these with a new Windows client presentation technology, as there has been a disappointing takeup of these technologies.

I think that it is highly unlikely that Microsoft are going to expect developers to write middle tier components in Javascript, or any other dynamically typed language that lacks the safety of a static type system. I have not seen any mention of any plans to replace the CLR with new middleware. So I think it likely that the .NET platform will continue to be used for application services. There is a lot of .NET middleware functionality like WCF that is also going to have to be replaced if they retire the whole platform.

As far as the UI on web applications goes, again they have been providing better support for HTML5/Javascript, and have integrated support for the open source jQuery framework. The VS team are working on improving client side HTML5/Javascript debugging tools. They are still going to provide a web application framework to support HTML5/Javascript application development. If they keep the .NET platform, then I think it likely they will continue to develop ASP.NET to support HTML5 features.

This story is more about mismanaged communications with the developer community than anything else.

It should also be noted that much of the hype behind this story is coming from open source protagonists. It should also be pointed out that periodically Java gets a kicking in response to a bungled Oracle management initiative. For example:

http://www.devx.com/Java/Article/45527

http://www.readwriteweb.com/enterprise/2011/01/why-the-future-of-java-is-with.php

Before coming to any firm conclusions about the death of .NET I suggest we wait and see what Microsoft announces in September.

Friday, 29 April 2011

Lack of NHibernate HQL support for question mark character in column name

If you’re faced with a database that contains reserved characters in some of its column names, NHibernate allows you to escape a column name in the mapping file by wrapping the column name in backticks, for example:

<class name="Foo">
   <property name="Bar" column="`Bar?`" />
</class>


This convention is used by NHibernate to generate SQL with the column name wrapped appropriately (e.g. [] for SQL Server). This works as intended for ICriteria queries and for HQL queries returning tuples in the following form:

session.CreateQuery("select Bar from Foo").List();

For SQL Server this results in the following SQL:

select foo0_.[Bar?] as col_0_0_
from Foo foo0_


The problem occurs if you use the entity selection form of the HQL query in conjunction with the generic List method:

session.CreateQuery("select foo from Foo foo").List<Foo>();

In this scenario, when constructing the SQL statement NHibernate interprets the question mark as a position parameter placeholder and substitutes the question mark with the parameter, i.e. the query winds up containing this column

foo0_.[Bar@p0]

instead of

foo0_.[Bar?]

Unfortunately this is a fault in NHibernate 3.1:

http://stackoverflow.com/questions/5805617/escaping-a-question-mark-character-in-a-column-name-in-nhibernate

Wednesday, 9 March 2011

Deploying an MVC .NET 4 application on IIS 7.5

I recently incorporated MVC 3 into an existing web application project.  In the process I upgraded the target framework to .NET 4.0.  I faced a number of issues on deploying the application to IIS 7.5.

The first problem was an Internal Server Error 500 HTTP response from the server.  The solution to this is to check the web.config file and remove the system.web/httpModules and system.web/httpHandlers sections.  For my application these were redundant and I was able to simply remove them.  If any modules and/or handlers are still needed by the application these should be moved to system.webServer/modules and system.webServer/handlers respectively.

The next error I faced was a Internal Server Error 500.21 mysteriously complaining that Handler PageHandlerFactory-Integrated has a bad module ManagedPipelineHandler in its module list.  It seems this was caused by ASP.NET 4 not being correctly registered with IIS 7.5.  The solution is to check that the version of .NET installed on the computer running IIS matches the version targeted by the application (on my computer this is v4.0.30319), and run the aspnet_regiis tool for the correct .NET version, e.g.:

%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i

You'll need to run this as an administrator.  You also need to check in IIS that the application pool used by the app is set to .NET 4.0 and Integrated managed pipeline.

If you're accessing a database and you haven't configured impersonation, you may need to set up a login for the ASP.NET identity. In ASP.NET 4 by default the application pool runs under the Windows account APPPOOL\[application pool name].  If you're using the default settings this will be APPPOOL\DefaultAppPool.  If you've upgraded to .NET 4, you'll have to create a login for each database your application accesses for the application pool Windows account.  (Alternatively if you have an existing login set up for the IIS 7 or 7.5 account you can change the application pool identity to this account.)

Having done these tasks I was able to run the application and log in, but as soon as I tried to access any MVC controller the server complained with a 404 response error.  After much googling I found this was fixed by applying hotfix KB980368.

This should now get you into the controller action.

One final error may crop up if you are restarting Cassini or IIS while testing the above, and this is related to any use of the Html.AntiForgeryToken method in views.  The default configuration is for a machine key to automatically generated: this will be invalidated each time IIS is restarted.  This is not a bug in the application: this is how it is supposed to work in production.  To clear this error you will need to clear out your application's cookies from your browser.  If you want to avoid this while testing - or in production if the ASP.NET process is being recycled (e.g. IIS restarts or if your application is being hosted in a web farm scenario) - you can hardwire a machine key by inserting a machine key section and either using a machine key generator tool to generate the machine key section e.g. aspnetresources.com/tools/machineKey or by manually creating a machine key section in system.web.