Thursday, October 9, 2008

Web Dev Best Practices

This has come up in various conversations recently and I was bored so I was googling for html best practices. I thought this article from Apple was quite good.

Tuesday, September 30, 2008

Forcing ASP .Net Validators and ValidationSummary to use CssClass

Here's something strange. If I create a validator using the following mark up:

<asp:requiredfieldvalidator id="rfv_txt" runat="server" errormessage="Required" CssClass="errorText" />

and my css class is:

errorText {
color: purple;
}

My validator still renders with red text. Checking the markup, I see that ASP .Net has added an inline style attribute (style="color: red"). Obviously, inline styles take precedence over class styles. But why is this inline style being applied at all?

I found this blog post that fixed the issue by setting the Forecolor to Color.Empty but it could only be done server-side. I figured there must be a way to set this client-side and after much annoyance, I found it:

<asp:requiredfieldvalidator id="rfv_txt" runat="server" errormessage="Required" CssClass="errorText" Forecolor="" />

So in order to set the color of validators or ValidationSummary via a CSS class you must set both the CssClass property and set the Forecolor property to an empty string. Why ASP .Net? Why?

Friday, August 1, 2008

WPF Data Binding Not Refreshing When Bound to Static Object

And the WPF Data Binding wierdness/frustration continues ...

I have a DataTemplate where DataType is defined. (In other words, WPF magic figures out when to use the template based on the type that is being bound). The Template includes a ComboBox which is bound to a static object in my UserControl class. The SelectedItem of the combobox is bound to a property of the DataTemplate's type (which, in this case, is a linq entity object).

It looks something like this:



My problem was that when I changed the DataContext of the UserControl which in turn changed the DataContext of this DataTemplate's parent control and the DataTemplate itself, the data in the ComboBox didn't change. In other words, while all the controls around it were being re-bound, this particular control wasn't.

Grrr.

After much googling, I found a cheap - but helpful - solution. Force the ComboBox to rebind every single time but adding a IValueConverter (which does nothing but return the value) to the binding.

Here is the article with the solution.

Seriously, these WPF Data Binding issues are ridiculous. I mean what exactly was Microsoft testing this shite for? It surely wasn't real-world examples or even with it's own new technology (Linq to SQL for example).

Thursday, July 31, 2008

Type casting your User Control Class in ASP .Net 2.0+

I ran into a little bit of a strange issue today:

I created a User Control that was being used multiple times on a page. It contained a few public methods and properties that allowed me to delegate loading and saving of the data to the control.

Since I have a personal aversion to typing out the same thing for controls with different names, I wanted to just loop through the Controls, check for the type, cast, and call the method. Seems simple right?

Not so much.

First I had a bit of trouble getting the actual type to cast. I googled and found a solution:

((ASP.controls_myControlName_ascx) myControl1).LoadMethod();

Super. The code ran just dandy on my local machine.

However, I ran into a bit of trouble when we deployed the code to our testing environment. It couldn't figure out what ASP.controls_myControlName_ascx. Of course, this happened when my internet was down and I was working at home and everyone was freaking out.

To fix the deployment issue, first, I got rid of the "ASP." prefix. Then it wouldn't compile on my local machine. Bah.

In googling, I came across this article: Understanding Page Inheritance in ASP.Net 2.0 by Rick Strahl. I used his solution for Pages and created an abstract base class which inherited from UserControl and contained abstract public methods. I put the abstract class into the App_Code folder and wa-la! I could cast the controls to the base class and call the methods and set public properties. Yay!

Sort of. It's actually kind of a lame solution but it works and is acceptable.

Tuesday, May 27, 2008

Random Annoying Crap about WPF Data Binding & Linq to SQL

For a new project at work, we are using WPF and Linq to Sql. In some ways data binding in WPF is very sexy and suave. In other ways, it's aggravating - there are things that are so easily done in WinForms and ASP .Net, like, say, re-binding data to a control after it's changed, that are bitch to figure out in WPF. At least for me they are.

In theory, WPF can update itself whenever the source changes. In reality, it's not quite as simple as it sounds.

First of all, if you happen to be extending the generic ObservableCollection and have a method in your new class that adds items to the collection, using the Add() method will update the control while using Items.Add() will not update the control. Why? Who knows?

public class ObservableStringCollection : ObservableCollection
{
public ObservableStringCollection()
{
Add("First");
Add("Middle");
Add("Last");

}

public void AddMe(string s)
{
Add(s); //I notify controls I'm bound to!
Items.Add(s); //I don't notify!
}
}


Secondly, Linq to Sql is not observable so anytime you SubmitChanges(), any control bound to your Linq classes doesn't get updated. I got around this by re-setting the ItemsSource property. Ok, fine. Here's the strange part: using ToArray() on the Linq collection will set the source correctly, while using AsEnumerable() will not set the source correctly. AsEnumerable() will set the source correctly the first time it's bound.


tvPages.ItemsSource = CMSUtility.DataContext.CMS_Pages.ToArray(); // I work!
tvPages.ItemsSource = CMSUtility.DataContext.CMS_Pages.AsEnumerable(); // I only work the first time!


Currently, I'm working on extending the Linq DataContext to be somewhat observable.

I wrapped the Linq DataContext class and implemented the INotifyPropertyChanged interface. Then I overrode the SubmitChanges method to fire the notification event.

public class ObservableDataContext : LinqClassesDataContext, INotifyPropertyChanged
{
public ObservableDataContext() : base("Data Source=.;Initial Catalog=DB;Integrated Security=True") { }

public ObservableDataContext(LinqClassesDataContext dc) : base(dc.Connection, dc.Mapping.MappingSource) { }

public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
{
base.SubmitChanges(failureMode);
NotifyPropertyChanged("Nodes");

}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}

#endregion
}
}

This way I can attach an event to the PropertyChanged for classes that I bind with.

That's the theory anyway. In practice, it's *sort of* working - I am able to get the Linq SubmitChanges to notify my source object and rebind to my control. However, when it binds to the control again, it doesn't use my DataTemplates. That's for another post I guess.

I'm off to yoga ...

Monday, May 12, 2008

DBNull is my Nemisis: Part Deux

******
This is the second part of my rant about DbNull. Go here to read the first part.
******

Ok. So now you have a utility method that lets you check for null whether it's null, DbNull, or, if bound to a datagrid, "&nbsp;"

What if you want to Convert that object, which might be null or DbNull, to a Type? What if you'd like to write it in pretty code? Well then you'd use this lovely method:

public static T ConvertToType(object o)
{
if (o == DBNull.Value || o == null)
return default(T);
return (T)o;
}


There are few things to note about this method. The first is that it will throw an exception if o can't be cast to type T. This very possibly might be what you want.

The second thing to note is the use of default(T). The default method is a useful little thing that allows .Net Generics to work with both value (structs) and reference (class) types. Basically, default(T) will return the default value of a value type, i.e. 0 for int or System.Int32, or null for a reference Type.

What if you don't want the method to throw an exception when converting? What if you'd like to use the equivalent to the "as" operator?

You might replace the last line of the method with this:

return o as T;


Then you would get a compiler error. Why? It's quite simple really. The "as" operator only works on reference types because only reference types can be null. One solution to this problem is to return default(T) if the casting fails.

public static T ConvertToTypeOrDefault(object o)
{
try
{
return ConvertToType(o);
}
catch (Exception e)
{
//this will return null for nullable types & the default value for non-nullable types
return default(T);
}
}


However, what if you really really want the convert method to return null. The short answer is that you can't; the long answer is that you can. :)

While you can't make a method that could return value types return null, you can force the method to only take certain Types using Generic constraints. In this case, we'd want the method to only accept reference types.

I tried to get this to work using a variety of methods until my trial and error finally ended in success. First, I tried returning T? (i.e. Nullable) but since reference types are already Nullable and Generic Nullable class only takes value types. Bah. So I tried restricting T to System.Nullable. Nope - static classes can't be used as constraints. Then, I tried restricting T to System.Object. Nope - Object is a special class and can't be used in this way. (Awww, it's special) . Next, I tried constraining T to new(), which essentially constrains T to classes that have a default constructor. Still nada - constraining to new() had no effect on the compiler erroring when I tried to return null.

Finally, after skimming the MSDN introductory article on Generics, I landed on the solution! T can be constrained by "class" (and conversely, by struct).

public static T ConvertToTypeOrNull(object o) where T : class
{
if (o == DBNull.Value)
return null;
return o as T;
}



Viola!

It's true that the ConvertTypeToDefault method is essentially the same for ConvertTypeToNull when T is a class. One advantage of using the ConvertTypeToNull is that it doesn't require the overhead of exception handling.

Thinking about default and value types brings up another issue though: What if you want to know if something is null OR if it's the default value. In other words, you are converting the Potential-DbNull object to a struct and want to know if it has no value.

You could add an additional method:


public static bool isNullOrDefault(object o)
{
bool bIsNull = isNull(o);
if (!bIsNull && o is ValueType)
{
bIsNull = ConvertToType(o).Equals(default(T));
}
return bIsNull;
}

public static bool isNullOrDefault(object o, bool webBound)
{
bool bIsNull = isNull(o, webBound);
if (!bIsNull && o is ValueType)
{
bIsNull = ConvertToType(o).Equals(default(T));
}
return bIsNull;
}


Something to note is that I'm not using the == operator to compare the default type with what's returned by ConvertToType. Why? Simple - the compiler doesn't let me. Again, because at compile-time the type that T represents is ambiguous, the compiler doesn't know if T supports the use of the == operator so it complains. Fortunately, the Java style .Equals method, while a bit ugly, does the trick just fine.

Also, the above method will throw an exception if the object can't be converted to the type. It seems logical to me, but you could use a different ConvertToType* method if you wanted.

(If you want to know more about what the webBound bool is for, check out my first post on DbNull.)

So there you have it! A DbNullUtility class to make your life just a little bit easier. Hooray for me and fuck DbNull! (Bad Religion anyone??)

Saturday, May 10, 2008

DBNull is my Nemisis

Despite what I told interviewers when looking for a new job last summer, I definitely prefer C# over Java. Having learned to program mostly in C++ with all it's (dangerous) flexibility, the fact that Java did not implicitly convert primitives to their object counter-parts (i.e. double and Double) - not to mention the endlessly long names - filled me with endless internal rage. Endless. My rage was especially acute when dealing with Java web services talking to C# web services. I'm angry just thinking about it.

C# seems to be a happy medium between the hand holding of Java and the cryptic compiler errors of C++. (Oh those compiler errors! I think fondly back on the time I continued to get a vTable error even after removing all code from the class file.) I do miss operator overloading but I generally am able to live without it ... except in one very important circumstance: DbNull.

I hate DbNull with a passion not quite reaching my hatred for no primitive/object conversion in Java but relatively close. I'm sure it's because it reminds me of dealing with this annoying aspect of Java. If you are unfamiliar with this lovely aspect of the C# language, I hope you stay blissfully ignorant and stop reading now. However, in case you've decided against ignorance, DbNull is the object that is returned when a database cell is null or, in the helpful words of MSDN, "Represents a null value." That's right. DbNull is null. Now, as a logical person, you'd think that then this statement would evaluate to true:

//where the cell in the DataRow dr is null
if(dr[0] == null) {
... do something
}


You'd think it would evaluate to true. You'd think that the committee of dudes (and hopefully, some ladies!) would have thought that, in this instance, we should override the Equals method and make DbNull == null always evaluate to true.

You'd think so but you'd be wrong.

This means that any time you are checking for nulls in something populated from a database, you must check for equality with DbNull.Value. I guess this is ok if everything came out of the database and was never changed, but perhaps that's not the case; perhaps some of the data is from the database and some isn't; perhaps an action such as casting with 'as' is happening on some fields. Or perhaps you'd simply like to use the ?? operator instead of less readable ? : syntax. If you want to do any of those things or if you're just a general fan of logic and non-bloated, readable code, well too bad for you. Write ugly code or scrap your idea.

So I decided to rectify this situation as best I could by writing a DbNull Utility class. I've had this idea floating around in my head ever since I first encountered this bullshit, but haven't gotten around to doing anything about it until now. On the upside, in working on this little project, I got a chance to delve a little more into C# Generics and that was exciting.

The first order of business is to write a method that checks if an object is null or DbNull:


public static bool isNull(object o)
{
return (o == DBNull.Value || o == null);
}


Easy enough.

Maybe you decide to test this out. Maybe you use ASP .Net and a datagrid because it seems like a simple utility test. Maybe you write an ItemDataBound method to change the value of a cell when it's null. Maybe you run the code and find that the value isn't changed. Then you think "What the fuck?"

Little did you know that DbNull's stupidity continues. When a DbNull value is bound to a datagrid, it's value is changed to "&nbsp;" I'll admit, I do understand the logic behind this on some level - it ensures that the cell renders properly in all browsers (ahem, netscape). Nevertheless, I spent many an hours trying to figure out what the hell was going on. This was back in my days of VB .Net using .Net 1.1. To make it even awesomer, converting the object to a string and checking for equality with " " didn't work. Oh no, you had to convert it to a Char Array and check for length and each element. In .Net 2.0 that no longer seems to be the case, but I've included a check for this behavior anyway. (Note: I can't remember - and am too lazy to go dig up the code - if null is bound with the trailing semi-colon or not so I check either way. Feel free to leave this out.

public static bool isNull(object o, bool webBound)
{
if (webBound)
{
string s = o as string;
if (s != null)
{
if (s == "&nbsp;")
return true;
Char[] c = s.ToCharArray();
if ((c.Length == 5 || (c.Length == 6 && c[4] == ';')) &&
(c[0] == '&') && (c[1] == 'n') && (c[2] == 'b') && (c[3] == 's') && (c[4] == 'p'))
return true;
}
}
return isNull(o);
}



Since this post is getting a bit lengthy (and because I fear I'm coming off as a rage-aholic), I'm going to end this post here and continue with the methods that convert to a type in the next post.