RSS

Model binding a collection with MVC and .NET 2.0

After about 3 hours of frustrating debugging, I came across a quirk/bug when using:

  • MVC
  • .NET 2.0 / 3.5
  • Model binding a collection

Imagine you have a collection of, say User objects.  And you would like to bind that collection to your view, but you only want to display some of the users.  For example, only admin users.  Your view would look something like this..

for (int i=0; i < Model.MyUsers.Count; i++)
{
    User user = Model.MyUsers[i];

    if(user.IsAdmin)
    {
        @Html.EditorFor(user)
    }
}

Now in .NET 4.0, your collection of “admin” users automatically gets bound to a collection in your controller. However, if you run your MVC application on .NET 2.0 framework (which includes 3.5 applications), your model binding will break once it gets to your controller (specifically, your MyUsers collection will be null)!

Why?

MVC uses an index notation in the name attribute of an html element to perform model binding when the request is submitted.  You can inspect the DOM to see this.

Let’s say you have a collection of three User objects, that you render into a <ul>, where each <li> contains a text box that allows someone to edit each user’s FirstName.  MVC will render the following HTML.

<ul>
    <li>
        <input type="textbox" name="MyUsers[0].FirstName" id="MyUsers_0_FirstName" value="Peter" />
    </li>
    <li>
        <input type="textbox" name="MyUsers[0].FirstName" id="MyUsers_0_FirstName" value="Brian" />
    </li>
    <li>
        <input type="textbox" name="MyUsers[0].FirstName" id="MyUsers_0_FirstName" value="Stewie" />
    </li>
</ul>

If you wanted to exclude “Peter” for some reason (i.e. he’s not an “admin” user) MVC will render HTML with Brian’s and Stewie’s objects indexed by 0 and 1, respectively. And when it binds on the request, your controller will receive a collection containing only two objects (Brian and Stewie).

However, .NET 2.0 does this a little differently. It will actually render the Brian and Stewie objects indexed by 1 and 2 (because that is their index in the original, non-filtered collection).

This makes model binding break on the request. Your controller will have a null collection!

The Solution

Upgrade to 4.0! (no, just kidding, I know this isn’t always possible). If you can’t run on 4.0, and you need a work-around, you can manually manipulate the HTML field name that MVC generates for your collection:

for (int i=0; i < Model.MyUsers; i++)
{
    int renderedUserCounter = 0;

    User user = Model.MyUsers[i];

    if(user.IsAdmin)
    {
        string htmlFieldName = string.Form("MyUsers[{0}]", renderedUserCounter);
        renderedUserCounter++;

        @Html.EditorFor(m => Model.MyUsers[i])
    }
}
 
Leave a comment

Posted by on August 16, 2012 in ASP.NET MVC, C#

 

Code Readability – JavaSript / jQuery Case Study

Because as developers, we feel the need to cram everything into one line of code.

Recently, over on Stack Overflow, I came across this post asking how to add a <li> element to an existing <ul> with jQuery.  This was the first response and became the accepted answer.

$("#content").append('<li><a href="/user/messages"><span>Message Center</span></a></li>');

Scan over this code and figure out what it does.  Tell yourself what it does as you read it.

How long did that take?  Were you able to scan it?  Or did you have to read almost every word?

We don’t read code–we scan it.

Code like this is extremely difficult to read.  More specifically, code like this is extremely difficult to scan.  When we read code (whether it’s old code we wrote, or someone else’s), we have an instinct to scan the code.  We look for keywords in the language, variable names, and method names.

The problem is that, when we write code, we instinctively feel like we have to write the fewest lines of code possible.  I used to do this all the time too.  And for me, subconsciously I felt that an extra line of code would slow my code down, or that my boss would see all those lines of code and think I was a bad programmer because I had to use more lines than someone else.  But then I realized the huge, huge value in readable code.

Consider the above example.  Let’s make this more readable and easier to scan.  We’re going to separate the declaration of the new HTML elements from the action of adding them to the UL:

// initialize the new HTML elements
var tabSpan = $('<span/>', {
     html: 'Message Center'
});
var messageCenterAnchor = $('<a/>', {
     href='/user/messages',
     html: tabSpan
});
var newListItem = $('<li/>', {
     html: messageCenterAnchor
}); 

// add the new list item
$("content ul").append(newListItem);

That way, it’s extremely easy to see what you are actually adding. Debugging is simpler, since if you have a problem with the declaration of an element, you can quickly see where your problems are.

Most developers that I see really undervalue the important of readable code. Whether you go back to your code a week or a year later, you can quickly see what’s going on.. You are able to scan your code instead of reading every line. And up front, it only costs a few extra key strokes.

Happy coding :)

 
Leave a comment

Posted by on February 2, 2012 in Coding Practices, JavaScript

 

Unit Testing, Extension Methods, and Efficiency.. Oh, my!

Improving unit testing, and use some sleek OOP too.

Let’s say that we want to test a call to a basic stored procedure, where @ClientID is required.

EXEC MYDB.MYSCHEMA.GetClients @ClientID = 10001

Now we want to test the database call in a unit test.  If we don’t pass in @ClientID, we should expect a SqlException, right?  So let’s test that.

// assign
int? testClientID = null;
bool missingClientIDErrorOccurred = false;

// act
try
{
MyDataAccess.GetClients(testClientID); 
}
catch (SqlException)
{
missingClientIDErrorOccurred = true;
}

// assert
Assert.IsTrue(missingClientIDErrorOccurred);

All looks good, right?  We expect a SqlException that says something like “Procedure X expects parameter Y, which was not supplied” (or something close to it).

But what happens if any other SqlException occurs?  Our test will pass.  Oops.  Can we narrow down our catch statement?  Absolutely.  We can find out if the SqlException caught is, in fact, caused by our missing @ClientID parameter by just checking the Message property of the exception.

catch (SqlException e)
{
	missingClientIDErrorOccurred = e.Message
	   .Contains("expects parameter '@ClientID', which was not supplied.");
}

Gravy. Now our test is just that much more accurate, and we shouldn’t have to worry later about incorrect test results. But wait… as OO programmers we like to be efficient, and hard-coding message strings is an obvious code-smell. Let’s improve it using extension methods.

public static bool CausedByMissingParameter(this SqlException exception, string missingParameterName)
{
	string missingParameterErrorMessage = 
	   string.Format(
	   	   "expects parameter '{0}', which was not supplied.", 
	   	   missingParameterName);
       return exception.Message.Contains(missingParameterErrorMessage);
}

Perfect, now we’re good to go. And of course we can reuse this extension method every time we want to write a similar test. Efficiency win. Now, the finish code looks pretty sleek and simple.

//act
try
{
	MyDataAccess.GetClients(testClientID); 
}
	catch (SqlException e)
{
	missingClientIDErrorOccurred = e.CausedByMissingParameter("@CommentID");
}
 
Leave a comment

Posted by on January 30, 2012 in ASP.NET MVC, C#, Unit Testing

 

Making Static Properties… Well, “Static”

When static properties exist multiple times in memory.

I find that static properties are especially useful for object factories.  For example, imagine that you have a “Role” class that represents a user’s role in the application.  It maps to the database, and has a few basic properties like RoleID and RoleName. I won’t go into detail on why I use static properties in this way, but just focus on the idea of static properties for a minute. This class will have a static getter property called “Administrator”, which returns a Role object that represents the administrator role.

So, why do we use static? A little CS101 recap, shall we?

  1. Static variables, properties, and methods are called from the Class, not from an instance of the class
  2. Only one copy of static variable exists in memory.

Ok, sensible choice here, because the Administrator Role object is the same across all threads of the entire application. There’s no sense in instantiating 100 Administrator role objects, when 1 will do. Plus, being static, it will called like

Role myRole = Role.Administrator;

This looks a lot like an enum type, which makes it easy to read and also makes more sense when you read it. Ok, now for the class itself:

public class Role
{
    // member data
    public int RoleID { get; set; }
    public string RoleName { get; set; }

    // static (factory) properties
    public static Role Administrator
    {
        get
        {
            return new Role
            {
                RoleID = 5,
                RoleName = "Administrator"
            }
        }
    } 
}

Now, let’s unit test our code real quick.

[TestClass]
public RoleTester
{
    [TestMethod]
    public void Test_That_Only_One_Copy_Exists_Of_Static_Properties()
    {
        // Assign - create our test variables
        Role adminRoleOne = Role.Administrator;
        Role adminRoleTwo = Role.Administrator;

        // Act - perform our test action(s)
        adminRoleOne.RoleName = "Hello, World!"    
            // if the static property is truly static, then 
            // adminRoleOne and adminRoleTwo will be 
            // referencing the same object, so both should 
            // now have a RoleName of "Hello, World!".

        // Assert - check our test results
        Assert.ReferenceEquals(adminRoleOne, adminRoleTwo);
        Assert.AreEqual(adminRoleOne.RoleName, adminRoleTwo.RoleName);
    }
}

But wait.. both of these tests FAIL! Does this mean that every time we call the static property, we get a new instance of the Administrator role? YEP.

The catch is, a static property has to be backed by a static variable in order to be truly static (one copy of the property in memory). Just calling the property static merely binds the property to the class (our “static fact #1″ from above). In order to achieve only one copy in memory, we need to back the property with static data:

public class Role
{
    // member data
    public int RoleID { get; set; }
    public string RoleName { get; set; }

    // static data
    private static readonly Role _administrator = new Role
    {
        RoleID = 5,
        RoleName = "Administrator"
    };

    // static (factory) properties
    public static Role Administrator
    {
        get
        {
            return Role._administrator;
        }
    }
 
Leave a comment

Posted by on January 25, 2012 in ASP.NET MVC, C#

 

How to Create a Website Icon

Bookmark your site in style.

Website icons (primarily known as “favicons”) are a great way to show off your logo and give your website a little something to help it stand out. The favicon shows up in three places:

  1. In the browser’s tab, when the website is open (in most browsers, this appears to the left of the web site title).
  2. As the icon for a bookmark.
  3. If you have a good browser (a.k.a. “anything but Internet Explorer”), and that browser has a bookmarks bar, your favicon will be the icon for the bookmark here as well.

FavIcon Appearances

FavIcons are super easy to set up:

  1. Generate your favicon.
  2. Take your .ico file and place it within your website directory (anywhere is fine, but I personally like to use an “images” folder).
  3. Create a link to the favicon in the <head> tag of your page.
    • Keep in mind that the favicon only appears on pages with this link. So if you have a template or master page that every page on your site uses, place it here! Otherwise, you’ll need to place it on every page in your site.
    • You must specify the relation attribute of your link to be “Shortcut Icon”.

Head Tag

 
Leave a comment

Posted by on January 6, 2012 in Uncategorized

 

Why I Dislike the #region Directive

I am in love Visual Studio.  Me and Microsoft have a secret relationship where I can secretly be in love with Visual Studio, all things .NET, and SQL Server, while publicly trashing their horrible inventions like Windows Mobile phones and Windows Vista.

To me, the #region directive is a horrible nuisance and an annoying invention.  There are two reasons that most people use #region, and both produce ugly code smells.

Example # 1 – “I have a really huge method that I want to collapse into sections”
Let me just go ahead and say that, if your method is that big, you should consider refactoring into smaller methods.  As developers, we want to produce beautiful, encapsulated OO code, right?  And part of that is dividing functionality into small components and functionality.  (As with anything, of course, there are exceptions and sometimes you just have to make a Super Method that is 100 lines long).  Typically, I go by the rule that one of my professors often preached–methods should not be more than 20-30 lines of code.  If they go over that, you should be able to (easily) refactor that into a sub-method.

Example # 2 — “I want to be able to use collapsing/code folding in Visual Studio without collapsing comments”
I like being able to hit that handy “Ctrl-M, Ctrl-O” combo and collapse everything to definition.  However, it irks me too that my comments are also collapsed.  I wish I could see my comments.  If we are constantly folding the code and hiding the comments, then why do we write the comments in the first place?  (There is, however, a notion that I firmly believe in that comments are bad–but that is another topic for another day).  Nonetheless, say we want to keep comments visible in our IDE when we collapse to definition.  So why should I have to write extra code (code that serves no purpose, mind you) just to change the way MY development environment looks or works?  Think about how much extra time you are going to spend to wrap EVERYTHING in a #region directive.

Then, along those same lines, think about refactoring.  When you move code around, you have to constantly make sure that your #region start and end directives are still in place.  If you move a section around, you have to make sure that you didn’t remove the #endregion tag with that code you just moved.  Annoying.

And I’ve also seen developers start a #region directive inside of one method, and end it outside of a second method (intentionally, too).  Yikes.

If we really want to be able to see our comments, we can write macros in VS to accomplish the code-folding without collapsing comments (this will be my next project–once I learn how to do a macro).

I love this quote from Kris on this post over at stackoverflow.

It’s one of my pet peeves that #regions absolutely stink. They might do something very obscure in the background (in wich case I might adjust my opinion) but I doubt that. What I do believe is:

  • #regions don’t increase readability
  • #regions make refactoring code harder because it’s easy to accidentally cut out one end but forget or miss the other, leaving you with a mess that won’t compile for no good reason.

Most of my c# career was spent maintaining existing code, in a team environment where I didn’t get to decide the coding standards so the grass might be greener elsewhere, but seriously, who thought of a dumb way to make a comment look like a compiler directive and made it able to break a build?…

 
Leave a comment

Posted by on December 29, 2011 in C#, Coding Practices, Visual Studio Tricks

 

DBNull – Using ToString() vs. Casting

You can use ToString on any indexed value in a DataRow, and it will return null if the field is DBNull:

string myNullableField = row["MyField"].ToString();

However, if you try to cast that same field as a string, you’ll get an exception:

string myNullableField = (string)row["MyField"]; //InvalidCastException!

But, the good thing about the InvalidCastException being thrown, is this gives us a nice little trick. We can use casting as a fail-safe. If we have a non-nullable field, and we get DBNull for ANY reason, we WANT the CLR to throw an exception (it makes it super-easy to debug):

string myNeverNullField = (string)row["MyField"];  
 //"MyField" is non-nullable. if we ever get NULL, 
 // something went wrong; let's raise a red flag 
 
Leave a comment

Posted by on December 21, 2011 in ASP.NET MVC, C#

 
 
Follow

Get every new post delivered to your Inbox.