Workaround for NullReferenceException in DBComparer

DBComparer 3.0 is a great tool if you want to synchronize your SQL Server database environments and don’t have hundreds of dollars to spend on Red Gate’s SQL Compare.  It’s simple to use and free.

http://dbcomparer.com/

I used it for a couple of weeks without any problem until one day when I tried to compare with a particular server and it crashed:

DBComparer NullReferenceException

Looking at the error message, we can deduce that the WriteRecentList() function saves the names of the servers you have typed in the recent servers list.  This is sort of like the recent files list found in some applications.

SettingsBase is part of the .NET Framework, and this part of the code is probably used to persist application settings.  A little digging around on the MSDN library reveals this:

Specific user data is stored in a file named user.config, stored under the user’s home directory. If roaming profiles are enabled, two versions of the user configuration file could exist. In such a case, the entries in the roaming version take precedence over duplicated entries in the local user configuration file.

A look in the user.config file confirms our theory that this is where the list of recent servers are stored.  However, DBComparer is only designed to support 10 recent server names (5 on each side of the comparison).  Any more than that and it blows up.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <userSettings>
    <DBCompare.Properties.Settings>
      <setting name="RecentServerName11" serializeAs="String">
        <value>server1</value>
      </setting>
      <setting name="RecentServerName12" serializeAs="String">
        <value>server2</value>
      </setting>
      <setting name="RecentServerName13" serializeAs="String">
        <value>server3</value>
      </setting>
      <setting name="RecentServerName14" serializeAs="String">
        <value>server4</value>
      </setting>
      <setting name="RecentServerName15" serializeAs="String">
        <value>server5</value>
      </setting>
      <setting name="RecentServerName21" serializeAs="String">
        <value>server6</value>
      </setting>
      <setting name="RecentServerName22" serializeAs="String">
        <value>server7</value>
      </setting>
      <setting name="RecentServerName23" serializeAs="String">
        <value>server8</value>
      </setting>
      <setting name="RecentServerName24" serializeAs="String">
         <value>server9</value>
      </setting>
      <setting name="RecentServerName25" serializeAs="String">
        <value>server10</value>
      </setting>
    </DBCompare.Properties.Settings>
  </userSettings>
</configuration>

As a workaround until this bug is fixed, you can delete some or all of the server names in the value tags to make room for more and prevent the error.

Advertisements

Same Markup, Same Browser, Different Results

Here is a simple HTML5 page I created:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="utf-8" />
 <title>Inconsistent Rendering</title>
</head>
<body>
 <span style="height: 1px; overflow: visible; background-color: Green;">
 <h1>This is a test.</h1>
 </span>
</body>
</html>

And here is that page rendered in Internet Explorer 8.  In one case it’s being served on my laptop, and the other on the local intranet.

Test file on localhost

Test file on intranet

The markup, the Web servers, and the browser are all set up 100% the same.  These should be identical, shouldn’t they?  What’s the problem?  The answer is Compatibility View.

Compatibility View is a “feature” of Internet Explorer that causes it to ignore modern Web standards.  That would be fine, except Compatibility View settings vary by zone, and different zones have different defaults.  Also, the Compatibility View button in the address bar isn’t always available, which means there’s no visual indicator as to what mode you’re in, and you can’t change modes for the current page easily.

Compatibility View settings can be accessed in the Tools –> Compatibility View Settings menu, but if you’ve developed a standards compliant intranet site, you need a better fix than simply asking each individual user to reconfigure their browser.  Group Policy is one option, but there is a much simpler solution.  Just add the following meta tag to your pages, and it will force IE 8 to use the !DOCTYPE declaration in the page to determine the rendering mode.

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

If you’re experiencing rendering inconsistencies with the same markup being served from different environments, have a look into Compatibility View. It just might be the culprit.

Mercurial HTTP Error 500: Access is denied on 00changelog.i

Today I created a new Mercurial repository on a Windows server.  I cloned it, made some changes, tried to push, and was greeted with this:

C:\myapplication>hg push
pushing to http://servername/myapplication
searching for changes
abort: HTTP Error 500: .hg\store0changelog.i: Access is denied

My user account had write permission to the myapplication folder on the server, and the odd thing is that I’ve created repositories there before and never had a problem pushing changes.  I compared 00changelog.i to the same file in another repository that was working.  Turns out I was using anonymous authentication and IUSR was missing write permission.  I gave full control to IUSR on hg\store folder and…

C:\myapplication>hg push
pushing to http://servername/myapplication
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 114 changes to 114 files

Success!

If you’re having problems pushing to a central server with Mercurial, make sure the IIS anonymous authentication account (IUSR or IUSR_MachineName) you have write permission to the hg\store folder and subfolders in your repository.

Conditional Validation with Data Annotations in ASP.NET MVC

In the simple blog engine I’m building, I encountered a scenario where I wanted to display different UI elements depending on whether the user was logged in:

Comment Form
Not logged in

 

Comment Form Logged In
Logged in

 

When the user is authenticated, their name and email is known, so it’s unnecessary to display them on the comment input form.  While it would be possible to hide just those fields, I decided to make separate partial views and display them in the Post view with the following code:

<%
    if (Model.AllowComments)
    {
        var commentControlName = Request.IsAuthenticated ? AuthenticatedCommentFormControl" : "CommentFormControl";
        Html.RenderPartial(commentControlName, new DotBlog.Models.ViewModels.CommentViewModel(Model.PostId));
    }
%>

This is the view model I used for both partial views:

public class CommentViewModel
{
    ...

    [Required]
    [StringLength(50)]
    [DisplayName("Name")]
    public string CommenterName { get; set; }

    public DateTime Date { get; set; }

    [Required]
    [StringLength(100)]
    public string Email { get; set; }

    [StringLength(100)]
    [DisplayName("Web Site")]
    public string WebSite { get; set; }

    [Required]
    [StringLength(1024)]
    [DisplayName("Comment")]
    public string CommentText { get; set; }

    ...
}

As you can see, I’m using data annotations to enforce required fields and string lengths.  The problem is, even though the name and email aren’t always displayed, they are still required.  I needed a way to validate certain fields conditionally.  Here are the options I came up with:

  • Stop using data annotations and find a different solution for validation
  • Use two different view models: one for each partial view
  • Use actual conditional data annotations, like the library built by Simon Ince.
  • When the form is posted, remove the fields from the model state so they’re not validated.

 

Let’s look at each of these individually:

Stop Using Data Annotations

Data annotations are not the only way to specify validation rules, but they’re easy to implement.  xVal was fine for ASP.MVC 1.0, but is now deprecated.  Custom validation code with ModelState.AddModelError() is flexible, but requires extra work.

Use Two Different View Models

Since I’m using two partial views for the comment form (one for authenticated users and one for guests), I could use a dedicated view model for each.  One would omit the data annotations on name and email and therefore not cause any validation problems.  This was my original implementation, but lead to unnecessary code duplication and other design problems.

Use Conditional Data Annotations

Simon Ince has built a cool library for conditional annotations that allows you to write code like this:

public class ValidationSample
{
    [RequiredIf("PropertyValidationDependsOn", true)]
    public string PropertyToValidate { get; set; }

    public bool PropertyValidationDependsOn { get; set; }
}

Conditionally Remove Fields from the Model State in the Controller

In the end, this is the solution I went with.  The controller executes this code when the form is posted:

if (Request.IsAuthenticated)
{
    ...

    // We don't need to validate user fields if user is logged in.
    ModelState.Remove("CommenterName");
    ModelState.Remove("Email");
}

By removing the fields from the model state, it won’t be invalid when they are missing.  This method is simple and avoids adding additional dependencies.

Entity Framework StoreGeneratedPattern Bug Persists

I’m using System.Data.SQLite v1.0.66.0 with Entity Framework 4.0 and Visual Studio 2010.  I designed some tables in SQLite and generated an Entity Data Model from those tables.  One of them (we’ll call it Person for the sake of argument) has an autogenerated integer primary key.  I manually set the StoreGeneratedPattern property to Identity in the designer, but when I started creating new rows in the database I encountered a problem.

I create new Person entities with a dummy PersonID of -1.  The first row inserts fine, but instead of generating a new ID it uses the dummy value.  That means when I insert the second row, it fails:

Abort due to constraint violation
PRIMARY KEY must be unique

I did a little Googling and realized I’m not the only person experiencing this:

It seems there is a bug in which the StoragePattern property is not updated in the SSDL when you change it in the designer, even though the CSDL is.

The impact of this is that you have to open the .edmx file in the XML editor and manually add the StorageGeneratedPattern property to the definition for your entity in the StorageModels section:

<EntityType Name="Person">
    <Key>
        <PropertyRef Name="PersonID" />
    </Key>
    <Property Name="PersonID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />
    <Property Name="Age" Type="integer" Nullable="false" />
</EntityType>

Even worse, you’ll have to do this for every identity column every time you update the model from the database because the property gets clobbered.  The workaround does work, technically, but it’s a major nuisance during development when things change often.

Identity columns are not uncommon, which means that this issue should have been uncovered early during testing.  Why didn’t Microsoft fix it right away?  According to some claims, it’s been around since EF 1.0.  In a couple of weeks I’m starting a new job where they use NHibernate.  It will be interesting to compare it to EF 4.0 and see if I run into the same kind of bugs.  Perhaps it will also help to wean me off graphical designers altogether.

Multi-Column Unique Constraints in SQLite.NET

While working on my blog engine project to learn ASP.NET MVC and Entity Framework, I encountered a common scenario.  I’m using SQLite on the back-end, and I needed a unique constraint across two columns.  As demonstrated in this stackoverflow question, you can specify a unique table constraint immediately after the column definitions when using the CREATE TABLE command.  However, for the purpose of rapid prototyping, I prefer using SQLite.NET and the graphical Server Explorer interface in Visual Studio rather than explicit DDL to define my tables.

The problem is that the GUI-based designer is still in development and doesn’t support unique table constraints.  One solution is to create a unique index instead.  Right-click one of the row headers in the table designer and select Indexes/Keys…

Table design context menu

In the Index Editor, add a new index.  Under the Misc category, set the Unique property to True, and under the Source category, list the columns you want in the index, separated by commas.

Index editor

This works because, as stated in the SQLite documentation:

INTEGER PRIMARY KEY columns aside, both UNIQUE and PRIMARY KEY constraints are implemented by creating an index in the database (in the same way as a “CREATE UNIQUE INDEX” statement would).

Using the Index Editor to create an index with Unique = True generates a “CREATE UNIQUE INDEX” statement behind the scenes, which can be verified by using the Generate Change Script… feature.

In summary, if you’re thinking about using Server Explorer to create a multi-column unique constraint in SQLite, just go with a unique index, since that’s how it’s implemented anyway.

How to Survive Your Technical Presentation

A few weeks ago I did a presentation on F# at a local user group meeting.  It was an opportunity to learn something new, network with other developers, and improve my communication skills.  Here are some of the things I learned from the experience.

My F# presentation

Know your subject well in advance

Building slides, writing code snippets and demos, and coming up with talking points are all difficult enough, not to mention the time it takes to practice your presentation thoroughly.  Don’t complicate matters by trying to learn a new language or technology from scratch.

Make friends with the experts in the room

Get knowledgeable attendees on your side right away.  During my F# talk, I turned to them when confronted with questions I couldn’t answer, and they bailed me out a couple of times.

Know your equipment inside and out

Try to keep things as simple as possible.  The fewer tools you have to manage, the less chance something will go wrong.  Arrive early so you can test your laptop, projector, and all your software.  Make sure to have fresh batteries for your presentation remote and microphone.  If at all possible, do a dry run with the actual equipment you’ll be using during your talk.

Don’t go over the allotted time

At one point while I was talking, a meeting attendee rose from his seat and left.  It wasn’t until then that I realized I had gone several minutes too long.  The room was packed, but everyone was too polite to mention that it was time to leave.

Ironically, I had worked very hard to fill that time with content.  But the important thing to remember is that talking at a user group meeting isn’t about filling dead air with noise; it’s about teaching and sharing information.  Only say what is necessary and relevant, and then let your audience go home.

Don’t be boring

This is probably easier said than done, but if you want to hold your audience’s attention, you can’t be dull and predictable.  Own your presentation and make it unique.  Record a video of yourself speaking and make sure you don’t look like a robot, with monotonous speech and stiff movements.

Read Confessions of a Public Speaker by Scott Berkun

I didn’t have to learn all these lessons on my own, and neither do you.  In his book, Scott captures years worth of public speaking wisdom in two hundred brief and entertaining pages.  I only wish I had read it earlier.