Thursday, 30 July 2009
Report Viewer Fun And Games
1)An object data source may not appear in the Website Data Sources window when you try to set the object data source for a SQL Server 2005 Reporting Services report in Visual Studio 2005. I couldn't understand why the buttons in the Website Data Sources window were greyed out. It turns out to be a known bug and the hot-fix for it is at http://support.microsoft.com/kb/939768
2) The 'XXX' parameter is missing a value : There are loads of posts for this and none of the posts I read supplied the resolution that fixed my particular problem. I was trying to set the parameter of a local report in the page load handler. When I views the page I kept getting the error message. When I tried to set a breakpoint, the code was not being hit, which lead me to believe that something fundamental was happening way earlier in the process. I reasoned that there was a null check being carried out and failing the code before my code to set the parameter was being called. I wondered if there was any way to allow nulls, and there was (is).
In the Report Parameters dialogue box there is a Check box labelled Allow null value. Selecting this solved my problem.
Tuesday, 19 May 2009
ASP.NET Unit Testing and TypeMock
Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.
Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle - and for the launch will be giving out FREE licenses to bloggers and their readers.
The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.
Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.
The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.
Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.
Go ahead, click the following link for more information on how to get your free license.
Wednesday, 13 May 2009
Towards a New Architect
- The Pragmatic Bookshelf | Pragmatic Thinking and Learning
- Heuristics for User Interface Design
- agile pommodoro technique free e-book - Google Search
- Steve Eichert - Agile Advice from Fred George
- http://www.pomodorotechnique.com/resources/cirillo/ThePomodoroTechnique_v1-3.pdf
- Amazon.co.uk: refactor your wetware
- The Omni Group - OmniGraffle
- david anderson agile management - Google Search
- feature crews microsoft - Google Search
- osgi - Google Search
- liquibase - Google Search
- Heuristics for User Interface Design
Monday, 27 April 2009
Progressive.Net Tutorials 2009
Thursday, 12 March 2009
error ASPPARSE: Could not load type 'Global'
All went well up until the point I tried to build the deployment project. The build failed with the "error ASPPARSE: Could not load type 'Global' " error. I looked for a solution on the Web and It turns out that Asp_net compiler wants a "bin" folder with all the dll references inside the project (the one you are tyring to build). After some more research I found the answer to my problem.
There is an element in the wdproj file (the MSBuild file created by the WDP) called 'SourceWebPhysicalPath'. This contained the value '..\PDR' (where PDR is the name of my Web application). Using a text editor to change this value to '..\PDR\bin' fixed the problem. The complete element is
<SourceWebPhysicalPath>..\PDR\bin</SourceWebPhysicalPath>
Thursday, 5 February 2009
Watchout, there's a Host about
I was pairing with Remco (start a blog man!) today and we came across an interesting assumption. The code we were looking at created a redirect URL using the following code.
return Redirect("http://" + Request.Url.Host + "/" + url.Trim('/'));
'Host' returns the "host component of this instance". No bad thing, until you start to test on a server using a port other than port 80. Your code may well break because the URL you are constructing doesn't contain the port number that your Web application is running on. To fix this you can use Request.Url.Authority. 'Authority' return the "DNS host name or IP address and the port number for a server".
Tuesday, 3 February 2009
ActiveRecord Configuration
The quick-start documentation that comes with ActiveRecord provides the following example configuration.
<?xml version="1.0" encoding="utf-8" ?>
<activerecord>
<config>
<add key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="connection.connection_string" value="Data Source=.;Initial Catalog=test;Integrated Security=SSPI" />
</config>
</activerecord>
I couldn't get this to work. After a bit of fiddling I ended up with the following.
<?xml version="1.0" encoding="utf-8" ?>
<activerecord>
<config>
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.connection.connection_string" value="Server=.;Initial Catalog=TestDatabase;User Id=UserNameGoesHere;Password=PasswordGoesHere " />
</config>
</activerecord>
The main differences are the 'hibernate' prefixes in the keys and the replacement of Data Source with Server in the connection string. This configuration worked against a SQL Server 2005 installation.
Monday, 2 February 2009
The Microsoft Loopback Adapter
I had a situation once where the IP address of an SMTP server had been hard-coded and I could only run the application successfully if the server was available. This meant that developing off-site was a problem. Then, from somewhere in the back of my mind, I remembered about the Microsoft Loopback Adapter (MSLA). This is a software network adapter i.e. you don't have to physically install a NIC. Installing this network adapter (add new hardware and choose the Microsoft Loopback Adapter from the list) allows me to easily route a given IP address to my local machine. For instance, if I manually assign the IP address of the MSLA to 192.168.0.100, then any requests bound for this IP address from my machine will end up at my machine. It's like saying "route any requests to 192.168.0.100 to 127.0.0.1". I installed a local SMTP server and my application sent emails to this local server via the MSLA. All I had to do was to remember to disable the network adapter when I was back on-site and wanted to use the real SMTP server.
Friday, 23 January 2009
Wednesday, 21 January 2009
Cooking Up An Application
One of the things I like to do at the weekend is cook a nice meal. I enjoy the whole process of selecting and preparing the ingredients and then putting them together to produce something that (usually) tastes good and leaves me wanting more. It occurred to me, whilst I was walking the dog this morning 1, that software development is quite a lot like cooking in many ways. I did a quick search on the Web and chuckled to myself as I read the advice given to people who wanted to cook. You could almost take the advice, word for word, and apply it to software development. Let me share some examples.
The cook's version
"Nobody likes a dirty kitchen, and a dirty kitchen is no fun to cook in either (not to mention unsanitary). With a little conscious effort, you can keep your kitchen clean while you cook. "
The developer's version
Nobody likes dirty code, and dirty code is no fun to develop either (not to mention unsanitary). With a little conscious effort, you can keep your code clean while you develop.
The cook's version
Be organized before you start cooking. It is important to have all of your ingredients and equipment assembled before you start cooking. This will help you follow the recipe more easily and prevent any messing around looking for ingredients and equipment that you didn't realise you needed—or maybe don't even have!
The developer's version
Be organized before you start developing. It is important to have all of your requirements and tools assembled before you start developing. This will help you follow the recipe more easily and prevent any messing around looking for requirements and tools that you didn't realise you needed—or maybe don't even have!
The cook's version
Stick to the recipe. When you are a beginner cook, you should follow the recipe exactly. As you cook more, you will become more at ease with making changes to a recipe and still create successful dishes.
The developer's version
Stick to the patterns. When you are a beginner developer, you should follow the patterns exactly. As you develop more, you will become more at ease with making changes to a pattern and still create successful applications.
The cook's version
Clean up. It is easier if you can clean as you go but don't worry if this doesn't come naturally at first. After a while, you'll work out that this is easier than cooking in a mess! Just make sure that you clean up after yourself when you have finished cooking, and don't forget any spills on the floor or cupboard doors.
The developer's version
Clean up. It is easier if you can clean as you go but don't worry if this doesn't come naturally at first. After a while, you'll work out that this is easier than developing in a mess! Just make sure that you clean up after yourself when you have finished coding, and don't forget any spills in the test code.
The cooks version
Enjoy your experience. Cooking is fun and a creative activity. When you feel a little more confident, start experimenting with different ingredients and come up with your own creations.
The developer's version
Enjoy your experience. Developing is fun and a creative activity. When you feel a little more confident, start experimenting with different applications and come up with your own creations.
1 : If you find yourself needing thinking time buy yourself a dog. Larger ones need lots of walking and this is an ideal time to let your brain sort stuff out.
Monday, 19 January 2009
Duplication, NUnit, Row Tests and MVC Views
I'm working on a project that uses the ASP.NET MVC framework. Learning how to use this is fun and I like the fact that I am able to write code that feels cleaner to me. We are working with preview 4 at the moment but should be moving to the release candidate as soon as it becomes available. I'm really looking forward to some of the "post preview 4" features, such as Model Binder support and the AcceptVerbs attribute. One of the nice things about developing with this framework is that it makes unit testing Web sites a whole lot easier. This is because the "controller" part of MVC is just a standard class that you can write unit tests against.
I came up with a neat piece of code as I was writing a test that checked the value of a variable stored in ViewData. I'm not saying it's new or original, just that it evolved naturally from my use of Test Driven Development (TDD). The value being checked was an enumeration, which was used to control an aspect of the Web page style. The value was different for each action on the controller and we had eleven actions. I wanted to test that the expected value was present in the view returned from each action. I have an example of the sort of thing that I was trying to do that you can download from my Google Code project. Here is the unit test I wrote for the example (I use 'MethodUnderTest_Scenario_ExpectedBehaviour' as my test naming convention).
[Test]
[Category("Unit")]
public void Index_IndexActionCalled_ViewDataContainsExpectedColour()
{
// arrange
var theExpectedColour = Colour.red;
// act
var homeController = new HomeController();
var viewResult = homeController.Index()as ViewResult;
// assert
Assert.That(viewResult, Is.Not.Null);
if (viewResult == null || !(viewResult.ViewData["Colour"] is Colour))
{
Assert.Fail("ViewData does not contain a Colour.");
return;
}
var actualColour = (Colour)viewResult.ViewData["Colour"];
Assert.That(actualColour, Is.EqualTo(theExpectedColour));
}
Once I made this test pass I moved on to the next one.
I got this second test passing and noticed that there was a lot of duplication in my test code. It is good TDD practice to treat test code the same as production code, so my next step was to refactor the test code. The sections outlined in blue above show the code differences and those differences are 1) the expected colour and 2) the name of the method being called. To refactor this I would need to have a test that takes parameters. I could then pass in the expected colour and the name of the method to be called. Reflection could then be used to call the method. This is where NUnit RowTest attributes come into play. RowTest attributes are part of nunit.framework.extensions.dll. Adding a reference to this dll allows me to create parameterised unit tests. The next stage of my refactoring was to implement a parameterised unit test.
[Test]
[Category("Unit")]
public void About_AboutActionCalled_ViewDataContainsExpectedColour()
{
// arrange
var theExpectedColour = Colour.blue;
// act
var homeController = new HomeController();
var viewResult = homeController.About() as ViewResult;
// assert
Assert.That(viewResult, Is.Not.Null);
if (viewResult == null || !(viewResult.ViewData["Colour"] is Colour))
{
Assert.Fail("ViewData does not contain a Colour.");
return;
}
var actualColour = (Colour)viewResult.ViewData["Colour"];
Assert.That(actualColour, Is.EqualTo(theExpectedColour));
}
The method signature was changed to take the name of the method to be called and the expected colour. The call to homeController.About() is now carried out using reflection. This test passed and so I added a new Row attribute to test the call to homeController.Index().
[RowTest]
[Row("About", Colour.blue)]
[Category("Unit")]
public void About_AboutActionCalled_ViewDataContainsExpectedColour(string methodName, Colour expectedColour)
{
// arrange
var theExpectedColour = expectedColour;
// act
var homeController = new HomeController();
// Use reflection to call the action method
var controllerType = homeController.GetType();
var methodToTest = controllerType.GetMethod(methodName);
Assert.That(methodToTest, Is.Not.Null, string.Format("No method called {0} found.", methodName));
var viewResult = methodToTest.Invoke(homeController, null) as ViewResult;
// assert
Assert.That(viewResult, Is.Not.Null);
if (viewResult == null || !(viewResult.ViewData["Colour"] is Colour))
{
Assert.Fail("ViewData does not contain a Colour.");
return;
}
var actualColour = (Colour)viewResult.ViewData["Colour"];
Assert.That(actualColour, Is.EqualTo(theExpectedColour));
}
Adding new tests for this scenario simply becomes a case of adding more Row attributes. I made a couple of final changes before I was happy with this test. I felt the reflection code distracted from the intent of the test, so I used the "Extract Method" refactoring to pull that code out into a separate method. I also renamed the methodName parameter to actionName. Using methodName wasn't wrong, I just feel that actionName describes the intent of what is being tested better. We are calling action methods on a controller. It's just a little more explicit than saying we are calling methods on a controller. Also, my naming convention is not quite right for this test because About is no longer the method under test. I decide to use HomeController_ActionCalled_ViewDataContainsExpectedColour as a method name to describe the intent of the test.
[RowTest]
[Row("About", Colour.blue)]
[Row("Index", Colour.red)]
[Category("Unit")]
public void About_AboutActionCalled_ViewDataContainsExpectedColour(string methodName, Colour expectedColour)
{
// arrange
var theExpectedColour = expectedColour;
// act
var homeController = new HomeController();
// Use reflection to call the action method
var controllerType = homeController.GetType();
var methodToTest = controllerType.GetMethod(methodName);
Assert.That(methodToTest, Is.Not.Null, string.Format("No method called {0} found.", methodName));
var viewResult = methodToTest.Invoke(homeController, null) as ViewResult;
// assert
Assert.That(viewResult, Is.Not.Null);
if (viewResult == null || !(viewResult.ViewData["Colour"] is Colour))
{
Assert.Fail("ViewData does not contain a Colour.");
return;
}
var actualColour = (Colour)viewResult.ViewData["Colour"];
Assert.That(actualColour, Is.EqualTo(theExpectedColour));
}
[RowTest]
[Row("Index",Colour.red)]
[Row("About",Colour.blue)]
[Category("Unit")]
public void HomeController_ActionCalled_ViewDataContainsExpectedColour(string actionName, Colour expectedColour)
{
// arrange
var theExpectedColour = expectedColour;
// act
var homeController = new HomeController();
var viewResult = CallControllerMethodAndReturnViewResult(homeController, actionName) ;
// assert
Assert.That(viewResult, Is.Not.Null);
if (viewResult == null || !(viewResult.ViewData["Colour"] is Colour))
{
Assert.Fail("ViewData does not contain a Colour.");
return;
}
var actualColour = (Colour)viewResult.ViewData["Colour"];
Assert.That(actualColour, Is.EqualTo(theExpectedColour));
}
private static ViewResult CallControllerMethodAndReturnViewResult(Controller controller, string methodName)
{
var controllerType = controller.GetType();
var methodToTest = controllerType.GetMethod(methodName);
Assert.That(methodToTest, Is.Not.Null, string.Format("No method called {0} found.", methodName));
return methodToTest.Invoke(controller, null) as ViewResult;
}
I like the result of this refactoring. The code is neat, compact and easily understandable. Any developer looking at this code should quickly be able to understand the expected behaviour of the code under test.
Friday, 16 January 2009
SVNX Security Certificate Problem
I'm looking at how I can usefully use Google products. Someone at the company I am working at uses Google Code to host code examples, which seems like a good idea to me. I set myself up with a Google Code account, fired up SVNX and tried to connect to my new SVN repository. The connection failed because the certificate issued by Google was not trusted by SVN. A quick Google search came up with Importing SSL certificates into svnX . This post explains how to use the command line to import a certificate and after following the instructions I was able to connect successfully to the repository.