Bogus errors from ASP.NET compiler#

I just wasted another hour, trying to figure out, what exactly ASP.NET was trying to tell me, when giving me an "ASPNET: Make sure that the class defined in this code file matches the 'inherits' attribute, and that it extends the correct base class (e.g. Page or UserControl)." message on compiling my ascx file.

Ok, so I used a custom namespace, but I've done that hundreds of times, so that shouldn't be the problem. I also had a custom base class inheriting from UserControl. Also, nothing I haven't done before. So what was the issue now?!

I basically retyped everything concerning the namespace and class names in all files, but nothing helped. So I reverted to commenting out my code. This helped me find the issue: I used a

<% if (somethingOrOther) { %> Some code here <% } %>

construct in my ascx-file (Please don't start an argument on whether this is good practice or not. I know it's not the cleanest way to do things, but that is not the concern here :-) ), and actually forgot to put in the closing <% } %>. Ok, my fault, but shouldn't you get a better Compiler message than "ASPNET: Make sure that the class defined in this code file matches the 'inherits' attribute, and that it extends the correct base class (e.g. Page or UserControl)."?!

So, if you encouter this error (and believe me, I've had it more than once due to typos), and are 100% positive you've spelled everything correctly, check for unbalanced parentheses!

 |  |  |  |  | 
Wednesday, March 18, 2009 5:43:48 PM (W. Europe Standard Time, UTC+01:00)
Comments [0]  | 

 

Be careful when reusing ListItems#

Yesterday, I had one of those WTF moments. I had a page with a form for entering two addresses. Both had the same fields, including a RadioButtonList with identical items. Since the items are resourced, I decided to optimize the performance by reusing the ListItems like so:

ListItem[] items = new ListItem[2];
items[0] = new ListItem(this.GetString("salutation.Mister"), "Mr");
items[1] = new ListItem(this.GetString("salutation.Misses"), "Mrs");
this.salutation.Items.AddRange(items);
this.salutation2.Items.AddRange(items);

Simple eh. Everything seems to be ok. And was I amazed, when I tested it, and I always got the SelectedItem to be the one selected in salutation2. I double-checked every location were I was storing the values, in case I forgot to change the field name after copy/pasting. But everything was correct, as far as I could tell. I even checked the values submitted by the browser, they were also correct.

Finally, it hit me: The ListItem has a Selected property, and it is used to find the RadioButtonLists SelectedItem property. And since I reused the items, the first list parses its items on postback, sets the appropriate ListItem's Selected property to true. Same thing happens with the second RadioButtonList. And since the ListItems are used in both lists, the last one wins.

So, I changed my code to look like this:

ListItem[] items = new ListItem[2];
items[0] = new ListItem(this.GetString("salutation.Mister"), "Mr");
items[1] = new ListItem(this.GetString("salutation.Misses"), "Mrs");
this.salutation.Items.AddRange(items);
items = new ListItem[2];
items[0] = new ListItem(this.GetString("salutation.Mister"), "Mr");
items[1] = new ListItem(this.GetString("salutation.Misses"), "Mrs");
this.salutation2.Items.AddRange(items);

Now everything works as it should. So next time, be careful when reusing your ListItems!

 |  |  |  | 
Tuesday, March 17, 2009 12:12:24 PM (W. Europe Standard Time, UTC+01:00)
Comments [0]  | 

 

SharePoint DateTimeField control and the order of its properties#

Today, I was building a nice little page layout for SharePoint and wanted to use SharePoint DateTimeField control. Since the field I wanted to edit was DateOnly, I set the corresponding property, leaving me with this code:

<SharePointWebControls:DateTimeField runat="server" id="dtfArticleStartDate" DateOnly="true" FieldName="ArticleStartDate" />

Seems fine to me, but ASP.NET did not like it. Or rather, the control did not like it. I got an ArgumentException with the following StackTrace:

 

[ArgumentException: FieldName value is not specified.]
Microsoft.SharePoint.WebControls.FieldMetadata.get_Field() +150
Microsoft.SharePoint.WebControls.DateTimeField.CreateChildControls() +310
System.Web.UI.Control.EnsureChildControls() +87
Microsoft.SharePoint.WebControls.DateTimeField.set_DateOnly(Boolean value) +29
ASP.MYNEWSPAGE_ASPX__2072755151.__BuildControldtfArticleStartDate()

FieldName value is not specified?! As you can see in my code above, it is indeed specified. But the stack trace gives us more information: The exception occurs in the compiled ASPX file.

  • ASP.MYNEWSPAGE_ASPX__2072755151.__BuildControldtfArticleStartDate():
    - We are building my DateTimeField control.
  • DateTimeField.set_DateOnly:
    - We are setting the DateOnly property.
  • FieldMetadata.get_Field:
    - Getting the field is where the exception occurs.

Note my ASPX-code again: I first set DateOnly="true" and then FieldName="ArticleStartDate". Oh my god, this can't be true... The solution is very simple: change the order of the attributes/properties:

<SharePointWebControls:DateTimeField runat="server" id="dtfArticleStartDate" FieldName="ArticleStartDate" DateOnly="true" />

Against all good practices, the SharePoint team actually created a direct dependency between two properties. At least the stack trace directly tells you where things go wrong, so the solution is obvious. Nonetheless, I thought, this was worth noting. It actually made me laugh, when I encountered it. Another one of those nice little pitfalls when working with SharePoint :-)

Wednesday, November 19, 2008 5:37:25 PM (W. Europe Standard Time, UTC+01:00)
Comments [0]  | 

 

All content © 2010 , Christoph Herold