Tools improvements

Richard Blewett reminded me that the XmlReader.ReadSubtree method makes it even easier to use LINQ to XML with a streaming approach. The code sample below will load nodes from an arbitrary XML files and yield them to the caller as they’re read from file:

I was implementing a client report (RDLC) using the Microsoft Report Viewer control and I wanted to set the background color of a table field based on value from my object source. At first I used the Color.ToKnownColor() method, but discovered that this does not work for all colors. I needed to convert to Hex. Here is the little extension method I used:

In the model below the phone number for an artist is actually a complex type (a little over engineered, I know, but I was just exploring how well this works).

The complex type consists of 4 ‘fields’: CountryCode, AreaCode, Number and Extension:

Each ‘field’ has properties set:

The great part is that this is fully supported by the DDL generator, so right click on the Entity Framework Designer in Visual Studio 2010 and choose ‘Generate Database From Model…’ and the ‘Artist’ table will be generated as:

-- --------------------------------------------------

-- Entity Designer DDL Script for SQL Server 2005, 2008, and Azure

-- --------------------------------------------------

-- --------------------------------------------------

-- Creating all tables

-- --------------------------------------------------

-- Creating table 'Artists'

CREATETABLE [dbo].[Artists] (

[Id] intIDENTITY(1,1) NOTNULL,

[Name] nvarchar(100) NOTNULL,

[IsIndividual] bitNOTNULL,

[Phone_CountryCode] nvarchar(4) NOTNULL,

[Phone_AreaCode] nvarchar(5) NOTNULL,

[Phone_Number] nvarchar(10) NOTNULL,

[Phone_Extension] nvarchar(10) NULL

);

GO

-- <snip other tables>

-- --------------------------------------------------

-- Creating all PRIMARY KEY constraints

-- --------------------------------------------------

-- Creating primary key on [Id] in table 'Artists'

ALTERTABLE [dbo].[Artists]

ADDCONSTRAINT [PK_Artists]

PRIMARYKEYCLUSTERED ([Id] ASC);

GO

-- <snip other primary and foreign key>

-- --------------------------------------------------

-- Script has ended

-- --------------------------------------------------

Notice that by default each column is prefixed with the name of the complex type, this is of course needed to ensure column names stay unique across multiple complex types in a single entity.

Entity Framework 4 enables lazy loading of entities by default. I’m not going to argue about whether that is good or bad, but there is something you should be aware of. If you’re like me, then over the years you’ll have learned that most classes that implement IDisposable should be used using a ‘using’ statement. This is especially true if you’re connecting to a database. So using Entity Framework your code may look something like this:

1:using ( MyEntities db = newMyEntities () )

2:{

3:var query = from e in db.Employees

4:where e.EmployeeId == employeeId

5:select e;

6:

7:return query.SingleOrDefault();

8:}

9:

This code will run fine and return a single employee. If however the Employee entity has a relationship things get a little interesting. Suppose the Employee has a relationship with a Department entity (via a property named ‘Department’). The department does not get loaded because db.LazyLoadingEnabled is true (by default).

Now suppose the above code is part of a WCF operation. The WCF operation want to return the Employee to the caller. Here is what happens: When WCF starts serializing the Employee object it sees the Department property and will try to access the property, since it setup to do lazy loading it will now go back to the database to load the department row. BUT hold on, the ‘using’-statement has already disposed of the object context and closed the database connection. What is the error that you’ll see? Well it starts with a CommunicationException: “The underlying connection was closed: The connection closed unexpectedly”.

This may throw you off and make you look for a WCF issue, but you’ll be looking in the wrong area. The actual cause of the error is on the server and the fact that the ObjectContext has been disposed yet is being used.

One solution would be to increase the lifespan of the object context and not dispose of it. This, to me, feels wrong. So instead I’ll just disable lazy loading.This can be done in the code:

Etienne Trembley found the solution to a problem that’s been haunting me since I installed IE9 beta. As it turns out IE9 prefers IPv6 over IPv4 AND on a Windows 7 64bit machine the hosts file (in c:\windows\system32\drivers\etc) does not provide an IPV4 entry to make localhost look at 127.0.0.1. Adding the localhost entry in the host file solves the issues!

For many years the mantra for implementing business logic in your line of business application has been: “don’t put it in the database, don’t put it in the user interface”. In other words, apply the layers design pattern if at all possible, together with implementing the Model-View-ViewModel (MVVM) or Model-View-Controller (MVC) pattern. Technologies like Entity Framework help us convert data in the database to .NET objects and add logic. Life is good.

Then it is time to create a report. Traditionally reports are run against the database and any self respecting reporting technology will to this day still offer you the option of building a report by querying directly against the database. Out the door goes the reuse of your .NET based business logic, right? No need to fear, Visual Studio offers a solution. Starting with Visual Studio 2005 Microsoft started shipping the ReportViewerControl with Visual Studio. Where SQL Server Reporting Services is full fledged reporting solution, with it’s own server, scheduling engine, user interface, the ReportViewerControl is only a small part of the food chain. The ReportViewerControl will render a report defined by an RDLC file against the data you feed into it. The data can still come from a database, but also from a WCF Service, any .NET object or SharePoint.

Let’s look at a sample. The sample will work on the AdventureWorks2008R2 database which can be downloaded from CodePlex. I’ve then created two views: CustomerView and OrderView. These views limit the data to Massachusetts and join a couple of table to make for more demo-friendly data.

Production.Product ON Sales.SalesOrderDetail.ProductID = Production.Product.ProductID ON

Person.Address.AddressID = Sales.SalesOrderHeader.ShipToAddressID

WHERE (Person.StateProvince.StateProvinceCode = N''MA'')

'

GO

Next step is to create a WCF service application, add an Entity Framework model and drag the two views onto the model:

Next we’ll implement two methods to use the Entity Framework model to select the data and return a list of CustomerView or OrderView objects. Note: Normally you would not select all the contents in a view, but since we know that the number of rows in our views are already limited in numbers there is no problem here.

1:using System;

2:using System.Collections.Generic;

3:using System.Linq;

4:using System.Runtime.Serialization;

5:using System.ServiceModel;

6:using System.ServiceModel.Web;

7:using System.Text;

8:

9:namespace AdventureServices

10:{

11:publicclassAdventureService : IAdventureService

12:{

13:

14: #region IAdventureService Members

15:

16:publicList <CustomerView > GetReportCustomerData()

17:{

18:using ( AdventureEntities db = newAdventureEntities () )

19:{

20:var query = from customer in db.CustomerViews select customer;

21:return query.ToList();

22:}

23:}

24:

25:publicList <OrderView > GetReportOrderData()

26:{

27:using ( AdventureEntities db = newAdventureEntities () )

28:{

29:var query = from customer in db.OrderViews select customer;

30:return query.ToList();

31:}

32:}

33:

34: #endregion

35:}

36:}

37:

38:

Next step is to create a report client. We can use any Windows or ASP.NET application and add start using the ReportViewerControl, but Visual Studio also offers a report application template. Very useful for quick demos:

Create the project (skip the wizard), then delete the Report1.rdlc. Add service reference to you AdventureServices and then add a new report using the Report Wizard (on my machine I’ve had poor luck adding the service reference as part of the wizard steps.

On the first screen of the wizard give the dataset a name (CustomerDataSet), select the service reference as a datasource and pick CustomerView as the available dataset.

On the next screen drag the fields we want to display to the ‘Value’ grid. More complex grouping per row and column is also possible.

Since we’re doing a very basic report the next screen offers no selectable options, although we’re starting to see part of our report.

Next we pick a style. There are a couple to choose from.

We click finish to close the wizard. Our report looks like this:

Use the designer and the tool box to enhance the report just a little:

Now the next step is to make sure our form will display this report. Go to the Form1 designer, select the ReportViewerControl and look for the smart tag in the top right hand corner of the control.
Activate the smart tag and you’ll see that you have to option to select a report. Select the report you’ve just created:

Notice how at the bottom of the forms designer there now is a design time control:

The design time binding source allows us to feed data into the report. So far the ‘links’ that we created to the service have only been used to pull in the schema of the data to be used. The actual data needs to be fed into the report when the form is run. For this we implement a call to our AdventureService:

Note: Even though our service does not take any parameters to filter the data I hope you can see that it would only take a small amount of coding to add a couple of fields to the form and pass any kind of selection to the service. I leave the actual implementation of that up to you, when you’re building your ‘real’ report.

I just had an email in my inbox recommending "The Art of Unit testing" by Roy Osherove. I guess I’ll put in another order at Amazon.

I've been doing unit testing for a long time, but since I'm largely self-taught I can probably learn something. Perhaps I’ll even sign up for a course at DevelopMentor. I know all the basics, I feel the biggest challenge with unit testing larger applications is managing test data.

Time for the first Augusta Developer Event of 2010. Join us for a morning filled with information about Silverlight. Shawn, Chris and Mark will present a variety of topics and we've planned a group discussion, so make sure you come prepared with questions, examples and your experiences.

WhenFebruary 24th, 2010 at 9:00am.

What is Silverlight?Shawn Robichaud – 15 min Introduction to Silverlight for decision makers, architects and developers.

Choosing the right technologyMark Blomsma - 30 min Silverlight vs. WFP vs. Windows Forms vs. ASP.NET. A session for decision makers, architects and developers. Which technology to use for which scenario?

Choosing the right technology – group discussionEveryone - 30 min Silverlight vs. WFP vs. Windows Forms vs. ASP.NET. A session for decision makers, architects and developers. Which technology would YOU use for which scenario? Please come prepared with questions, examples and ready to share your experiences.

Silverlight and Section 508 complianceMark Blomsma – 30 min “Section 508 requires that all Web site content be equally accessible to people with disabilities. This applies to Web applications, Web pages and all attached files. It applies to intranet as well as public-facing Web pages.” (http://usability.gov).

“We are pleased to present you with the 2010 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Visual C# technical communities during the past year.”

I’ve once again been honored with the Microsoft Most Valuable Professional Award. This is the seventh year running that I’ve been lucky enough to receive this great award and I it’s great to be part of the group of people that receive this award.

Registration for the 4th quarter MSDN (.NET) Northeast Roadshow has just opened up! This totally FREE event will be held on Tuesday, December 15th. Thankfully, we were able to secure more convenient hours this time around. The event will run from 9:00 am thru 3:30 pm in the Florian Hall of the Central Maine Commerce Center in Augusta. (a.k.a. Public Safety/M.E.M.A) These events target .NET developers and analysts, or those actively training to become one. Microsoft Developer Evangelists Chris Bowen and Jim O’Neil will be making the drive up from their regional offices in Massachusetts in order to lead the presentations.

I just ran into a little problem when attempting to run a Visual Studio unit test on my Windows 7 machine. I downloaded log4net.dll and wanted to use it in a project, but when running the unit test I ran into the following error:

Failed to queue test run 'Mark@L-ONE 2009-10-11 14:08:38': Test Run deployment issue: The location of the file or directory 'c:\users\mark\documents\visual studio 2008\projects\sources\developone.myproject.unittests\bin\debug\log4net.dll' is not trusted.

Turns out that a downloaded file is blocked. You can unblock the file by right clicking the file and choosing “Unblock”.

Make sure you remove all copies of the assembly (if you have copy local = true) and then recompile.

LinqPad

A must have for people using LINQ to SQL and Entity Framwork. Helps a lot with figuring out what the exact SQL statement is that get generated from your LINQ statement. See: www.linqpad.net

VMWare Converter, VMWare Workstation and VirtualPC

These tools are invaluable in creating clean testing environments and separating multiple development environments on a single machine. VMWare converter allows you to grab a physical harddrive and convert it into a virtual machine. Very useful for Windows 7 migration scenarios! See: www.vmware.com, www.microsoft.com/virtualpc

Live Mesh

Is only in beta, but already an invaluable tool for remote desktop connections across firewalls and synchronizing files across (virtual) machines. See: www.mesh.com

I’ve been using the ReportViewer control in Visual Studio quite a bit to create RDLC (offline) reports that are based on the result of LINQ queries against object trees. It’s been a while since there has been a new release of this control and Visual Studio 2010 did not include anything major with regards to the ReportViewer control. I asked around and got an email from Robert Bruckner answering my two main questions:

1. Yes, the ReportViewer control in VS2010 will run on both .NET 3.5 as well as .NET 4.0.2. Yes, the ReportViewer control in VS2010 will support Export to Word for RDLC (offline) scenarios.

Thanks Robert (and the rest of the people working on this technology), great news!

Improving the security of the .NET Framework applications by using the .NET Framework 2.0 security featuresImplement code access security to improve the security of a .NET Framework application. (Refer System.Security namespace)

I’m playing around with code generation using Visual Studio 2008 T4 and I needed to pull in some data. Easiest way to create the data is using Excel and then pull it into a dataset. Using the right connection string this becomes very easy.

In our Maine Microsoft Certification Study Group we recently had a discussion about using regular expression. Today I found myself writing a RegEx to check for illegal characters in a formula (string). I thought I’d share the solution:

privatebool FormulaContainsIllegalCharacters( string formula )

{

bool result = false;

try

{

Regex r = newRegex( @"(!)|(@)|(#)|(\$)|(%)|(&)" );

result = r.Match( formula ).Success;

}

catch { } // ignore any regular expressions errors -> return false

return result;

}

In my case I’m not interested in handling exceptions. If a technical error occurs I will accept the input. Notice that I needed to put a “\” before the $ sign, since the $ is a reserved character marking the end of a line.I don’t need to put each character in “( )” brackets, but for personal preference I just find it easer to read.

Today I had to fix a bug in some code involving a program creating multiple files where each file needed to have a unique machine generated filename. I was building my own unique name using the DateTime.Now.Ticks().ToString() as part of the name. Apparently on some machines the Ticks are not going to be unique. So I looked at the Path.GetTempFile() method, but I needed to control the location of the temporary files. Next stop: Path.GetRandomFileName().

Documentation:The GetRandomFileName method returns a cryptographically strong, random string that can be used as either a folder name or a file name. Unlike GetTempFileName, GetRandomFileName does not create a file. When the security of your file system is paramount, this method should be used instead of GetTempFileName.

I regularly get asked for references on which books are interesting for people starting with C# and .NET. I'm not good at remembering books, but usually squeeze out a reference. Today I ran across a good list of Essential Reading compiled by my DevelopMentor colleague Tony Sneed. I'm shamelessly copying it here since I concur with his list.

The xs:integer type is specified as a number with no upper or lower bound on its size. For this reason, neither XML serialization nor validation map it to the System.Int32 type. Instead, XML serialization maps the xs:integer to a string while validation maps it to the Decimal type that is much larger than any of the integer types in the .NET Framework.

A lot is being blogged about the availability of VS 2008 SP1 and TFS SP1. It contains fixes and many new features and sound almost too good to be true, but I checked, it's not an April fool's joke

A little lost in the noise about new features is the fact that .NET Framework 3.5 SP1 will include .NET CLR 2.0 SP2. I've been unable to find anything about this other than this one post by Eric Eilebrecht, but any CLR update is significant.

The last couple of weeks I've been working on migrating an ASP.NET application from using a Visual FoxPro database to using SQL Server 2005. My application has it's logic in library DLL and with some layering uses Typed DataSets to connect to the database.

The method 'GetByPrimaryUser'is defined on the TableAdapter and using the GUI designer in Visual Studio I manage my typed datasets. All SQL is stored within the Typed DataSets. There is very limited use of stored procedures.Migrating the .NET code from using a Visual FoxPro database to using SQL Server 2005 has involved the following:

Change the connection string property on every datatable to use the SQL Server connection string instead of the FoxPro connection string.

Opening every single query and changing the SQL parameters from question marks '?' to named parameters like '@user'.

Rechecking the mapping of the columns in the datatable, sometimes these would get messed up. Especially in cases where non-database columns where added to the datatable.

Rechecking column expressions.

Some areas of the code accessed the OleDbDataAdapter and OleDbConnection within the typed dataset, this had to be replaced with SqlDataAdapter and SqlConnection.

FoxPro does not support the .NET light weight transactions, so code to custom manage the transaction could be deleted and a simple 'using( TransactionScope tx = new TransactionScope() )' could be implemented.

There where several areas where 'adapter.Update(row)' did not work with FoxPro, so the Insert/Update/Delete had to be called manually in the data access layer. With SQL Server there are no problems and this 'fix-it' code could be removed.

After following these steps some of the datatables would generate unexplicable validation errors. Not wanting to waste too much time I just re-created those typed tables and re-added the queries on those tables.

The .NET Framework is huge and I still frequently find new things in .NET 2.0 which I had not seen before. Last week I stumbled across the update in Math.Round(...).In .NET 1.x the .NET Framework would only support the American way of rounding numbers. This means that:

decimal y = 2.5M;decimal x = Math.Round(y, 0); // x = 2

For Dutch people this wrong. We would expect x to be '3'.In .NET 2.0 there is a new overload, allowing you to specify how the Round method should work.