Tuesday, November 11, 2008

How to not do validation

Yesterday when I was trying to do some online shopping I the e-commerce system in use perfomed input validation in a slightly suboptimal way. Here is what happened:

  • To be able check out the stuff in my shopping basket I had to create an account.
  • To create an account I had to enter username, password and address.
  • Go to checkout
  • Confirm to use the just entered address as the shipping address
  • On the following page where the pay button should be there's this small note "The city is not long enough"  WTF!?!
  • Try again with the city name in the other language as it is longer
  • Same story "The city is not long enough" ...
  • Only when changing the primary address the order goes through

A validation rule stating that the city cannot be just three letters are just plain stupid, secondly if there is a need to use stupid validation rules, then do the validation when the data is entered and not when it is used ...

This comic comes to mind.

Saturday, November 08, 2008

Debugging WPF databinding issues

Lately due to switching teams and project I've been doing much more WPF than before. I cannot say I have fully mastered the learning curve yet but I'm getting better and it is an interesting journey.

Occasionally the data bindings does not work as expected and then it is nice to get more information about them in order to figure out what went wrong.

The following is useful when you want to know why a particular binding is misbehaving (or rather you want to know where you screwed up...)

xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"



ItemsSource="{Binding <snip>, diagnostics:PresentationTraceSources.TraceLevel=High}"


The above information and MUCH more is presented by Beatriz Stollnitz



(This post is also a 'reminder to self')

Monday, November 03, 2008

C# quiz 9/?

Consider the following:

Guid globallyUnique1 = new Guid();
Guid globallyUnique2 = new Guid();
if (globallyUnique1 == globallyUnique2)
{
MessageBox.Show("This cannot be");
}
else
{
MessageBox.Show("Everything is well");
}

What is shown? Why?

Wednesday, October 15, 2008

Sandcastle to dead tree format woes

For reasons partially unknown to me, I was tasked with converting Sandcastle generated API documentation to dead tree format.

The best way seems to be feeding some magic XSLT to Sandcastle that would that would directly create PDF via XSL-FO or DocBook or whatever. However, I haven't been able to find such a thing and I'm not ready to put down that kind of work to create it myself at this point.

Another option I pursued was to print the CHM to XPS/PDF but this has its own cons. Firstly directly printing from CHM viewer strips CSS rendering ugliness. This is correctable by finding the correct html file from %TEMP% and a little search/replace magic and providing the stylesheets and images.

Having gotten this far I found out that the stylesheet needs to use something else but relative font size to keep the text legible.

Now as if this wasn't enough the browser or at least the PDF/XPS "printer" chokes on the sheer amount of input, still not finished after N hours, and this just for the documentation of a smallish test assembly. :(

This does not look feasible at this point.

Bright ideas appreciated!

Thursday, April 03, 2008

C# quiz 8/?

Now it's time for some one regarding serialization:

Given this serializable class:

    [Serializable]
public class Victim {
public static int InstanceCount;
public int Data { get; set; }

public Victim() {
InstanceCount++;
Data = 2;
}
}

and the following test code:

    class Program {
static void Main(string[] args) {
Victim v = new Victim();
v.Data = 3;
BinaryFormatter serial = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
serial.Serialize(ms, v);
ms.Seek(0, SeekOrigin.Begin);
v = (Victim)serial.Deserialize(ms);
Console.WriteLine("Data {0}", v.Data);
Console.WriteLine("Instances {0}", Victim.InstanceCount);
}
}

What is the output, and why?

C# quiz 7/?

If we compile the following code to a dll, for example using the following command line:

csc.exe /t:library Library.cs

namespace Library {
public class Library {
public const int FOO = 1;
public static readonly int BAR = 2;
}
}

And refer those in our test program:

    class Program {
static void Main(string[] args) {
Console.WriteLine(Library.Library.FOO);
Console.WriteLine(Library.Library.BAR);
}
}

Now, if we change FOO to 10 and BAR to 12 and recompile Library.dll without recompiling the test program, what is the output when we run the test program?

C# quiz: 6/?

Consider the following:

    class Test {
private int m_foo;
public int Foo {
get { return m_foo; }
}
public int set_Foo(int value) {
m_foo = value;
}
}

What happens when you compile, and why?


Wednesday, April 02, 2008

C# quiz: 5/?

Consider a console application with the following Main:

        static void Main(string[] args) {
System.Threading.Timer t = new Timer(dummy =>
{
Console.WriteLine("In callback: " + DateTime.Now);
GC.Collect();

}, null, 0, 1000);

Console.ReadLine();
t = null;
}

What does the code do? Does it matter if it is compiled Debug or Release, if so, why?


(To give proper credit where credit is due, this example is heavily inspired by CLR via C# by Jeffrey Richter)


C# quiz: 4/?

Given the following code:

    internal class Test {
public int Foo { get; set; }
public int Bar { get; set; }

#if CUSTOM
public override int GetHashCode() {
return Foo.GetHashCode() ^ Bar.GetHashCode();
}

public override bool Equals(object obj) {
if (object.ReferenceEquals(obj, null)) return false;
Test t = obj as Test;
if (t != default(Test)) {
return (Foo == t.Foo) && (Bar == t.Bar);
}
return false;
}
#endif
}

and the following test code:

            Dictionary<Test, string> dict = new Dictionary<Test, string>();
Test foo = new Test { Foo = 1, Bar = 2 };
dict[foo] = "Hello World";
foo.Bar = 42;
if (dict.ContainsKey(foo)) {
Console.WriteLine("it's there");
} else {
Console.WriteLine("it's not");
}

Answer the following questions:



  1. With CUSTOM not defined, what does the test code print?

  2. If CUSTOM is defined, does it change the outcome?

  3. What if Test is changed to a struct and CUSTOM is not defined, what is the output?

  4. If Test is a struct and CUSTOM is defined, what happens?

Tuesday, April 01, 2008

C# quiz: 3/?

Consider the following class:

    internal class Test {

public int Code { get; set; }

public static bool operator ==(Test lhs, Test rhs) {
if (object.ReferenceEquals(lhs, rhs)) return true;
if (lhs == null || rhs == null) {
return false;
} else {
return lhs.Code == rhs.Code;
}
}

public static bool operator != (Test lhs, Test rhs) {
return !(lhs == rhs);
}
}

What is the outcome of the following test code, and why?

            Test test1 = new Test { Code = 42 };
Test test2 = new Test { Code = 42 };
if (test1 != test2) {
Console.WriteLine("different");
} else {
Console.WriteLine("equals");
}

Monday, March 31, 2008

C# quiz: 2/?

Continuing on the series of C# and/or .NET Framework short questions:

        private void Foo(List<int> bar) {
bar = new List<int>();
// ...
}

With the method above and the code below:

        List<int> bar = null;
Foo(bar);
if (bar != null) {
Console.WriteLine("populated");
} else {
Console.WriteLine("still null");
}
If or else ?

EDIT: fixed typo in code sample.

C# quiz: 1/?

I'm starting a series with small questions C# and/or .NET Framework related questions:

First out, NaN values:

            double foo = double.NaN;
// ...
if (foo == double.NaN) {
Console.WriteLine("NaN");
} else {
Console.WriteLine("a number");
}

If or else ?

Wednesday, March 19, 2008

Safari - first impressions

I thought that I might give it a shot after all so I installed it. First impressions:

- it's a memory hog! 4 sites in 4 tabs consumes a whopping 210MB, while Firefox 3 beta 4 for the same sites consumes "only" 74MB

- the UI is ugly

- scroll wheel doesn't work properly in bookmarks

- close tab X button on the left !?!

- As I don't have mouse gestures, I often right-click and choose back. If I happen to have the cursor over a word, (quite likely), safari chooses to select the word and only select search with google or copy. WTF?

...my default browser isn't changing.

Tuesday, March 18, 2008

Safari for Windows - Apple spamming users

I have an ipod, and therefore I have ITunes installed. Today Apple Software Update popped up and greeted me with the following totally unrelated thing: Safari 3.1 (22.65Mb)

Safari for Windows is the fastest and easiest-to-use web browser for the PC.  It displays web pages faster than any other browser and is filled with innovative features -- all delivered in an efficient and elegant user interface.

For more information on Safari 3.1, please visit http://docs.info.apple.com/article.html?artnum=307467

Hmm, that sounds too good to be true.

...and why does it notify me about it in the first place?

Friday, March 14, 2008

Gotcha: Hidden [Flags] attribute on bitfield enumerations

 

Just got reminded of a still unfixed bug.

Consider an enumeration of the following kind:

    /// <summary>
/// Modes enumeration
/// </summary>
[Flags]
public enum Modes {
/// <summary>
/// Yes
/// </summary>
Foo = 1,
/// <summary>
/// No
/// </summary>
Bar = 2,
/// <summary>
/// Maybe
/// </summary>
Both = Foo|Bar
}

For the user of this enumeration, it is essential to know that it in fact is a bitfield (as specified by the FlagsAttribute).


However, both Intellisense and object browser fails to give any hint about this fact!?! (Yes, this occurs in both VS 2005 and VS 2008)


So for now, remember to document (within in the summary, so it is visible) this fact for your fellow developers.


Tuesday, January 15, 2008

New phone

I received my new phone today, this time I thought I'd try something different for various reasons, so I got a HTC Touch Dual. I haven't really used it enough yet to post any reviews, but first impression is quite nice. Unfortunately it still takes two weeks until I they switch over to the new SIM card (due to carrier change), so until then I cannot really use it fully. But yes, I will keep my old number...

On a related note, things don't seem as bright with the handsfree that I got, it was cheap yes, but first it had the wrong kind of mains plug on the charger, and secondly after I found an appropriate adapter, the thing won't charge !?!

Monday, January 14, 2008

Maximizing a WPF Window to second monitor

I'm trying to develop and application that utilizes a maximized window on the second monitor.

There's a few issues here. The first is that WPF doesn't offer the same information as WinForms about monitor configuration. WinForms has SystemInformation.MonitorCount and Screen.AllScreens[i].WorkingArea. WPF has SystemParameters.PrimaryScreen[Width/Height] and SystemParameters.VirtualScreen[Width/Height] which almost works (as long as you don't have more than two monitors) but not really. So back to using WinForms API...

Secondly, the obvious solution to display a form maximized on second screen was to me the following:

                fullScreenWindow.WindowStartupLocation = WindowStartupLocation.Manual;

Debug.Assert(System.Windows.Forms.SystemInformation.MonitorCount > 1);

System.Drawing.Rectangle workingArea = System.Windows.Forms.Screen.AllScreens[1].WorkingArea;
fullScreenWindow.Left = workingArea.Left;
fullScreenWindow.Top = workingArea.Top;
fullScreenWindow.Width = workingArea.Width;
fullScreenWindow.Height = workingArea.Height;
fullScreenWindow.WindowState = WindowState.Maximized;
fullScreenWindow.WindowStyle = WindowStyle.None;
fullScreenWindow.Topmost = true;
fullScreenWindow.Show();

However, when you try that you'll end up with a topmost maximized window on your primary display, which was not what we wanted.


Turns out that we cannot maximize the window until it's loaded. So by hooking the Loaded event of fullScreenWindow and handling the event along the lines of:

        private void Window_Loaded(object sender, RoutedEventArgs e) {
WindowState = WindowState.Maximized;
}

...it works.


Oh, and you want to make certain that you are running a dual monitor configuration so you do not put the window somewhere where it is off-screen.

Wednesday, January 09, 2008

UIAutomation - testing Calculator

I recently discovered that the UIAutomation library provided in .NET 3.0 doesn't only work for managed code but for any code.

Should you so be inclined, here's how to test that calc.exe provided by Windows in fact can calculate 2+2 correctly.

        [TestMethod]
public void TestAddTwoAndTwo() {

Process calc = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"c:\windows\system32\calc.exe";
calc.StartInfo = startInfo;
calc.Start();
Thread.Sleep(500);

AutomationElement window = AutomationElement.FromHandle(calc.MainWindowHandle);
AutomationElement twoButton = FindAutomationElementByName(window, "2");
AutomationElement plusButton = FindAutomationElementByName(window, "+");
AutomationElement equalsButton = FindAutomationElementByName(window, "=");

AutomationElement editField = window.FindFirst(TreeScope.Descendants, new AndCondition(
new PropertyCondition(AutomationElement.ClassNameProperty, "Edit"),
new PropertyCondition(AutomationElement.IsValuePatternAvailableProperty, true)));
calc.WaitForInputIdle();

InvokePattern clickTwo = twoButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
InvokePattern clickEquals = equalsButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
InvokePattern clickPlus = plusButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;

clickTwo.Invoke();

clickPlus.Invoke();

clickTwo.Invoke();

clickEquals.Invoke();
ValuePattern pattern = editField.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;

Assert.AreEqual(4, int.Parse(pattern.Current.Value,NumberStyles.AllowDecimalPoint|NumberStyles.AllowTrailingWhite));
}
        public AutomationElement FindAutomationElementByName(AutomationElement parent, string name) {
Condition c = new PropertyCondition(AutomationElement.NameProperty, name);
return parent.FindFirst(TreeScope.Descendants, c);
}


You'll also want a reference to UIAutomationClient.dll and the following using:

using System.Windows.Automation;

To find out what the application under test has eaten i.e. how to automate it, do use UISpy.exe provided with the Windows SDK .


And yes, the syntax is a tad verbose ...

Tuesday, January 08, 2008

LINQPad - Useful Linq tool

If you are using LINQ (or want to try it) and want to try out your query expressions dynamically you'll want to check out LINQPad.

Free (as in beer) and very useful!

Sunday, January 06, 2008

LINQ - DataContext.Dispose()

I'm playing around with LINQ for the moment. Actually I tried Entity Framework first, but could not get that to behave as I wanted (that is Table Per Class), so I let that rest for a while until they fix TPC support in a subsequent version and tried "plain" LINQ instead.

I can't say I'm really there yet, but one thing that bit me was that I out of old habit (or whatever) used code similar to the following:

            using (DataClassesDataContext db = new DataClassesDataContext();
{
return (from user in db.Users
where user.Name == name
select user).SingleOrDefault();
}

..and I thought that all was well. However, when testing a little bit more I got  ObjectDisposedException:s when returning

return (from user in db.Users select user).AsEnumerable();

instead of

return (from user in db.Users select user).ToList();

Turns out that even though DataContext implements IDisposable, you should not use a DataContext in a using statement or directly call .Dispose() or you'll end up with lots of brokenness.


(In addition I got all kinds of attaching and detaching issues, but I think I've sorted them now. Did I already tell you that this is my first attempt of using LINQ non-trivially?)