måndag 19 maj 2008

DropDownList databinding versus manually adding ListItems: divergence of behavior

Symptom:
The following two ways of rendering data from a given datasource may yield two completely different results.

Datasource:
List<foo> items = new List<foo>();
{
   new Foo { Text = "A", Value = null },
   new Foo { Text = "B", Value = null },
   new Foo { Text = "C", Value = null }
}

Figure 1, databinding:
ddl.DataSource = items;
ddl.DataTextField = "Text";
ddl.DataValueField = "Value";
ddl.DataBind();

Figure 2, manually adding items:
foreach(Foo item in items)
   ddl.Items.Add(new ListItem(item.Text, item.Value));

Figure 1 will yield the following result:
<select ...>
   <option value="">A</option>
   <option value="">B</option>
   <option value="">C</option>
</select>

Figure 2, however, slightly deviates from this behavior, in that all values are assigned, even though they were null in the datasource:
<select ...>
   <option value="A">A</option>
   <option value="B">B</option>
   <option value="C">C</option>
</select>

Cause:
The reason why Figure 2 renders different client code, is the following way in which the Value for a ListItem is retreived (whereas the native databinding method doesn't bother with the detour of using ListItems, but simply renders the source as HTML):
public string Value
{
   get
   {
      if (this.value != null)
         return this.value;
      if (this.text != null)
         return this.value;
      return String.Empty;
   }
   ...
}

Thus, the value retreived in Figure 2 is that of the Text property, since the Value property is null.

Outcome:
While there is nothing particularly discomforting about any of the two approaches to rendering the same data, it is worth remarking that there are differences between them, and that code written in one way cannot always be rewritten in another, without unexpected side-effects.

Inga kommentarer: