# Friday, December 23, 2011

Need to write your own model validator outside the scope of an application framework such as ASP.NET MVC? A short while ago, I needed to do just that. I was writing a WCF service with a relatively complex data model which required a much greater level of validation than the DataMember attribute’s IsRequired property could provide.

Here’s the solution I found. But first a bit of background.

Validation in ASP.NET MVC 
I’ve been using Data Annotations attributes for view model validation for years in the context of ASP.NET MVC for model validations, client and server side. I always took the server side validation for granted and looked at the client side with greater interest. When getting started with ASP.NET MVC, I used Steve Sanderson’s xVal library. Then I switched to ASP.NET MVC 3’s client side validation.

For client side validation, I’m really starting to like jQuery’s unobtrusive validation and the ASP.NET MVC’s HtmlHelper class and its GetUnobtrusiveValidationAttributes method. And for the server side, view model binding and the ModelState.IsValid property works fine.

Validation Without an App Framework 
But this post is not about client side validation or server side validation in ASP.NET MVC. I had to do the validation against the model in the WCF service which, as far as I know, does not have a nice model validation facility other than its own data model serialization which just throws a nasty exception should the data being passed over the wire not provide required data.

So why not use the same approach used by our friends in the ASP.NET MVC world. A little Google investigation turned up something that looked like exactly what I wanted. I found an answer posted to StackOverflow by Mike Reust which included a link to his DataAnnotationsValidatorRecursive library. (Gotta love StackOverflow.)

After some experimentation, I had made some tweaks to Mike’s code and came up with something that worked the way I wanted it to. Here’s a partial example of a data model and how the ValidateObject with it’s optional MinOccursOnEnumerable can be used to require one or more items to be included in a required complex enumerable type that will get recursively.

[DataMember(IsRequired = true), 
	Required(ErrorMessage = "Employer cannot be null."), 
	ValidateObject]
public Employer Employer { get; set; }


[DataMember(IsRequired = true), 
	Required(ErrorMessage = "Children cannot be null."), 
	ValidateObject(MinOccursOnEnumerable = 1)]
public Child[] Children { get; set; }

Using the recursive validation library is easy. Here’s an example:

//perform validation using DataAnnotations for custom validation messages
List<ValidationResult> results = new List<ValidationResult>();
bool isValid = DataAnnotationsValidator.TryValidateObjectRecursive<MyModelData>(model, results);

//now examine isValid and the results

And here’s the code for the validation extensions and ValidateObject attribute.

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System;

namespace MyValidator
{
	public static class DataAnnotationsValidator
	{
		public static bool TryValidateObject(object obj, ICollection<ValidationResult> results)
		{
			return Validator.TryValidateObject(obj, new ValidationContext(obj, null, null), results, true);
		}

		public static bool TryValidateObjectRecursive<T>(T obj, List<ValidationResult> results)
		{
			bool result = TryValidateObject(obj, results);

			var properties = obj.GetType().GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(ValidateObjectAttribute)));

			foreach (var property in properties)
			{
				var valAttrib = property.GetCustomAttributes(typeof(ValidateObjectAttribute), true).FirstOrDefault() as ValidateObjectAttribute;
				var value = obj.GetPropertyValue(property.Name);

				if (value == null || valAttrib == null) continue;

				var asEnumerable = value as IEnumerable;
				if (asEnumerable != null)
				{
					List<object> items = new List<object>();
					foreach (var enumObj in asEnumerable) items.Add(enumObj);
					foreach (var enumObj in items)
					{
						result = TryValidateObjectRecursive(enumObj, results) && result;
					}
					if (items.Count < valAttrib.MinOccursOnEnumerable)
					{
						string errorMessage = valAttrib.ErrorMessage ?? "MinOccursOnEnumerable validation failed.";
						results.Add(new ValidationResult(errorMessage));
						result = false;
					}
				}
				else
				{
					result = TryValidateObjectRecursive(value, results) && result;
				}
			}

			return result;
		}
	}

	public static class ObjectExtensions
	{
		public static object GetPropertyValue(this object o, string propertyName)
		{
			object objValue = string.Empty;

			var propertyInfo = o.GetType().GetProperty(propertyName);
			if (propertyInfo != null)
			{
				objValue = propertyInfo.GetValue(o, null);
			}
			return objValue;
		}
	}
}

You need to use the ValidateObject attribute on any complex type you want validated deeply. I found out the hard way that if you try to validate all reference objects, you get nasty results on DateTime properties.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MyValidator
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	public class ValidateObjectAttribute : Attribute
	{
		int _minOccurs = 0;
		//marker for object properties that need to be recursively validated

		public ValidateObjectAttribute() { }

		public int MinOccursOnEnumerable { get { return _minOccurs; } set { _minOccurs = value; } }

		public string ErrorMessage { get; set; }
	}
}

Of course you can take off on this or Mike’s original code and create your own validation library for a WCF service, a business logic layer, or whatever you need. Good luck and please update me on your validation adventures.

posted on Friday, December 23, 2011 7:20:25 AM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Monday, October 24, 2011

The world of .NET programming is full of objects that implement the IDisposable interface. File, Font, DataContext, Stream, DbConnection, and many more—all implement the IDisposable interface. And for good reason. They touch the outside world and the outside world is messy, full of resource allocations that can only be used one at a time and must be explicitly returned to their owner to be used by another caller.

So in this 8th installment of C# Basics, let’s take a look at how best to use the IDisposable interface by simply using the using statement. The using statement is really just syntactic sugar but it helps you produce much more readable and reliable code.

using (var myobj = new MyDisposable())
{
  myobj.DoSomething();
}

You can even stack them like this:

using (var myobj = new MyDisposable())
using (var otherobj = new MyOtherDisposable())
{
  var x = myobj.DoSomething();
  otherobj.DoAnotherThing(x);
}

Of course, you could write your own resource cleanup explicitly, but it can start to look a bit messy and as lazy as we often are, the cleanup often gets forgotten.

var myobj = new MyDisposable();
var otherobj = new MyOtherDisposable();
try
{
  var x = myobj.DoSomething();
  otherobj.DoAnotherThing(x);
}
finally
{
  if (otherobj != null) otherobj.Dispose();
  if (myobj != null) myobj.Dispose();
}

Use the using statement where you can. It's not a one size fits all syntax sugar, but it is sweet where it fits.

posted on Monday, October 24, 2011 8:06:14 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Wednesday, October 12, 2011

I’m gradually catching up with presentations from last month’s BUILD conference on Channel 9. Today I ran into a blog post by Samuel Jack in the UK on the topic of what’s new in C# 5.0. I recommend you read his blog, but more strongly recommend you watch Anders Hejlberg’s presentation on Channel 9 about C# 5.0 and VB 11.0.

Among my favorite goodies are the async and await keywords. For anyone who has put off learning how to write asynchronous application behavior because it is just too hard to understand, you are in luck. Wait a few more months, perhaps a year, and you can learn just a few easy concepts about how to use async and await keywords in your code and you will be an asynchronous coding wizard.

Exciting times!

posted on Wednesday, October 12, 2011 8:37:46 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, October 10, 2011

In this 7th installment of C# Basics, I’m going to cover the differences between the modifiers const, readonly, and static, specifically in reference to class members where the developer wishes to use the fields or properties in client code that cannot change the value of that member.

To illustrate and discuss the differences between each modifier, I’ve put together a contrived set of classes with the least amount of code I can think to add in order to review and to examine the differences in the IL (intermediate language) taken from Ildasm.exe. (Visit this nice page to learn how to use Ildasm.exe from with Visual Studio.)

using System;

namespace ReadOnlyConstant
{
  public class MyConstOnly
  {
    // assigned at declaration and used at compile time only
    public const int Age = 20;
  }

  public class MyReadOnly
  {
    // can only be assigned in declaration or constructor
    public readonly int Age = 0;
    public MyReadOnly()
    {
      Age = 20;
    }
  }

  public static class MyStaticOnly
  {
    // can be assigned within class but "readonly" for client
    private static int _age = 20;
    public static int Age { get { return _age; } }
  }
}

The goal in each class above is to create a public field or member that can be read by client code but cannot be changed by client code. Looking through the IL produced by compiling this code can also be instructive even if you do not fully understand each and every IL instruction. Take a look here at these classes under the compiled covers and notice that the MyConstOnly class does not have a getter method to retrieve Age nor is it's value set in the .ctor but only noted by the compiler in the .field definition for use by the compiler later should client code use it. Then read through to the client code and see its IL code as well.

// =============== CLASS MEMBERS DECLARATION ===================

.class public auto ansi beforefieldinit ReadOnlyConstant.MyConstOnly
       extends [mscorlib]System.Object
{
  .field public static literal int32 Age = int32(0x00000014)
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method MyConstOnly::.ctor

} // end of class ReadOnlyConstant.MyConstOnly

.class public auto ansi beforefieldinit ReadOnlyConstant.MyReadOnly
       extends [mscorlib]System.Object
{
  .field public initonly int32 Age
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       25 (0x19)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  ldc.i4.0
    IL_0002:  stfld      int32 ReadOnlyConstant.MyReadOnly::Age
    IL_0007:  ldarg.0
    IL_0008:  call       instance void [mscorlib]System.Object::.ctor()
    IL_000d:  nop
    IL_000e:  nop
    IL_000f:  ldarg.0
    IL_0010:  ldc.i4.s   20
    IL_0012:  stfld      int32 ReadOnlyConstant.MyReadOnly::Age
    IL_0017:  nop
    IL_0018:  ret
  } // end of method MyReadOnly::.ctor

} // end of class ReadOnlyConstant.MyReadOnly

.class public abstract auto ansi sealed beforefieldinit ReadOnlyConstant.MyStaticOnly
       extends [mscorlib]System.Object
{
  .field private static int32 _age
  .method public hidebysig specialname static 
          int32  get_Age() cil managed
  {
    // Code size       11 (0xb)
    .maxstack  1
    .locals init ([0] int32 CS$1$0000)
    IL_0000:  nop
    IL_0001:  ldsfld     int32 ReadOnlyConstant.MyStaticOnly::_age
    IL_0006:  stloc.0
    IL_0007:  br.s       IL_0009

    IL_0009:  ldloc.0
    IL_000a:  ret
  } // end of method MyStaticOnly::get_Age

  .method private hidebysig specialname rtspecialname static 
          void  .cctor() cil managed
  {
    // Code size       8 (0x8)
    .maxstack  8
    IL_0000:  ldc.i4.s   20
    IL_0002:  stsfld     int32 ReadOnlyConstant.MyStaticOnly::_age
    IL_0007:  ret
  } // end of method MyStaticOnly::.cctor

  .property int32 Age()
  {
    .get int32 ReadOnlyConstant.MyStaticOnly::get_Age()
  } // end of property MyStaticOnly::Age
} // end of class ReadOnlyConstant.MyStaticOnly

// =============================================================

You can read the MSDN full explanations of each modifier but here’s the basics:

const
Can only be assigned a value in declaration and can only be a value type or string. Use the const modifier when you KNOW the value won’t change. If you think it might change at a later date and your assembly is distributed as a compiled library, consider one of the other modifiers to assure that you don’t have a value you didn’t expect in your client code. (See use code sample below.)

readonly
Can assign a value at declaration or in the class constructor. It is important to note that if you use a reference type with modifiable members, your client code can still modify those members even if it cannot assign a value to the readonly reference. Note in the IL above that the initialization of the declared value occurs in the .ctor before the assignment in the .ctor, so if you are wondering which would be better, now you have some insight into that question.

static
Can assign the value of the private member anywhere within the class code. Note the initialization of the value in the static .ctor of the class. You could also assign the value in some other method later but with the public property implementing only a get, the client code cannot assign a value.

And here is the client code and it’s IL just below it. The most important point to note in the IL is that the client code is compiled with the const’s literal value, NOT a get to the class. This is why you must watch for the use of a const that could change with a new library. Make sure you compile your client code against that new library when you get it or you could be very sorry when the library is using one const compiled value and you’re using another.

namespace TestConsole
{
  class Program
  {
    static void Main(string[] args)
    {
      // compiler will replace with constant value
      // If the referenced assembly is changed to 40 and this is
      // not compiled again against that new assembly, the value
      // for mcoAge will still be 20. (See IL below.)
      int mcoAge = MyConstOnly.Age;

      MyReadOnly mro = new MyReadOnly();
      int mroAge = mro.Age;

      int msoAge = MyStaticOnly.Age;

      Console.WriteLine("{0} {1} {2}", mcoAge, mroAge, msoAge);
    }
  }
}

// output: 20 20 20

// and here is the IL with some of my own comments

// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit TestConsole.Program
       extends [mscorlib]System.Object
{
  .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // Code size       53 (0x35)
    .maxstack  4
    .locals init ([0] int32 mcoAge,
             [1] class [ReadOnlyConstant]ReadOnlyConstant.MyReadOnly mro,
             [2] int32 mroAge,
             [3] int32 msoAge)
    IL_0000:  nop
    IL_0001:  ldc.i4.s   20   //NOTE: literal value assigned - no mention of MyConstOnly class
    IL_0003:  stloc.0
    IL_0004:  newobj     instance void [ReadOnlyConstant]ReadOnlyConstant.MyReadOnly::.ctor()
    IL_0009:  stloc.1
    IL_000a:  ldloc.1
    IL_000b:  ldfld      int32 [ReadOnlyConstant]ReadOnlyConstant.MyReadOnly::Age
    IL_0010:  stloc.2
    IL_0011:  call       int32 [ReadOnlyConstant]ReadOnlyConstant.MyStaticOnly::get_Age()
    IL_0016:  stloc.3
    IL_0017:  ldstr      "{0} {1} {2}"
    IL_001c:  ldloc.0
    IL_001d:  box        [mscorlib]System.Int32
    IL_0022:  ldloc.2
    IL_0023:  box        [mscorlib]System.Int32
    IL_0028:  ldloc.3
    IL_0029:  box        [mscorlib]System.Int32
    IL_002e:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                  object,
                                                                  object,
                                                                  object)
    IL_0033:  nop
    IL_0034:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class TestConsole.Program

// =============================================================
posted on Monday, October 10, 2011 6:50:43 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, October 08, 2011

In this post I'm recording my own code sample for future reference. It is not meant to be perfectly usable or even a representation of best practices but a practical reminder note of the most common thread safe code I end up writing. The code is a thread safe singleton class that demonstrates the use of the lock keyword, the Interlocked class, ReadWriterLockSlim class, and one of the new concurrent collections available in .NET 4.0.

In the code below, I've only shown the ConcurrentDictionary being used. There is a gold mine of power in the other concurrent types to be explored in other posts.

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading;

namespace SafeThreads
{
  public sealed class DataCache
  {
    // Thread Safe Singleton Pattern
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++
    
    //volatile to insure assignment before read access
    private static volatile DataCache _instance;
    
    //the sync root object - clever name
    private static object _threadBolt = new object();

    private DataCache() { } //cannot create outside this

    public static DataCache Instance
    {
      get
      {
        if (null == _instance)
        {
          lock (_threadBolt)
          {
            if (null == _instance)
            {
              _instance = new DataCache();
            }
          }
        }
        return _instance;
      }
    }
    

    // Thread Safe with lock
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++

    private long _callCount = 0;
    private long _updateCount = 0;

    public long UpdateCountWithLock(long callCount)
    {
      lock (_threadBolt)
      {
        _callCount += callCount;
        _updateCount++;
        return _updateCount;
      }
    }

    // Thread Safe Interlocked class
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++

    public long UpdateCountWithInterlocked(long callCount)
    {
      Interlocked.Add(ref _callCount, callCount);
      Interlocked.Increment(ref _updateCount);
      return _updateCount;
    }

    private Tuple<int, string> _currentItem = 
      new Tuple<int, string>(0, string.Empty);

    public Tuple<int, string> CurrentItemInterlocked
    {
      get { return _currentItem; }
      set
      {
        Interlocked.Exchange<Tuple<int, string>>(ref _currentItem, value);
      }
    }


    // Thread Safe ReaderWriterLockSlim
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++

    private ReaderWriterLockSlim _slimLock = new ReaderWriterLockSlim();
    private Dictionary<string, int> _keys = new Dictionary<string, int>();
    private List<string> _values = new List<string>();

    public int Count
    {
      get
      {
        _slimLock.EnterReadLock();
        try
        {
          return _values.Count;
        }
        finally
        {
          _slimLock.ExitReadLock();
        }
      }
    }

    public string this[int index]
    {
      get
      {
        _slimLock.EnterReadLock();
        try
        {
          if (_values.Count > index && index > -1)
            return _values[index];
          else
            return null;
        }
        finally
        {
          _slimLock.ExitReadLock();
        }
      }
    }

    public string this[string key]
    {
      get
      {
        _slimLock.EnterReadLock();
        try
        {
          if (_keys.ContainsKey(key))
          {
            return _values[_keys[key]];
          }
          else
            return null;
        }
        finally
        {
          _slimLock.ExitReadLock();
        }
      }

      set
      {
        _slimLock.EnterWriteLock();
        try
        {
          if (_keys.ContainsKey(key))
          {
            _values[_keys[key]] = value;
          }
          else
          {
            _values.Add(value);
            _keys.Add(value, _values.Count - 1);
          }
        }
        finally
        {
          _slimLock.ExitWriteLock();
        }
      }
    }

    //demonstrate upgrade from read to write lock
    public AddUpdateResult AddOrUpdate(string key, string value)
    {
      AddUpdateResult result = AddUpdateResult.Unchanged;
      _slimLock.EnterUpgradeableReadLock();
      try
      {
        if (_keys.ContainsKey(key))
        {
          if (value == _values[_keys[key]])
            return result;
          else
            result = AddUpdateResult.Updated;
        }
        else
          result = AddUpdateResult.Added;

        //upgrade to write lock
        _slimLock.EnterWriteLock();
        try
        {
          if (result == AddUpdateResult.Updated)
          {
            _values[_keys[key]] = value;
          }
          else
          {
            _values.Add(value);
            _keys.Add(value, _values.Count - 1);
          }
        }
        finally
        {
          _slimLock.ExitWriteLock();
        }
        return result;
      }
      finally
      {
        _slimLock.ExitUpgradeableReadLock();
      }
    }

    public enum AddUpdateResult
    {
      Added,
      Updated,
      Unchanged
    };


    // Thread Safe Collections
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++

    private ConcurrentDictionary<string, string> _concurrentCache = 
      new ConcurrentDictionary<string, string>();

    public ConcurrentDictionary<string, string> ConcurrentCache
    {
      get { return _concurrentCache; }
    }
  }
}
posted on Saturday, October 08, 2011 4:34:40 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Tuesday, October 04, 2011

A year ago I posted a library that I enjoy using in one form or another called DomainAspects, an aspect oriented infrastructure or template for domain driven design in .NET applications. The library allows you to isolate cross cutting concerns such as exception logging and authorization from domain or business specific concerns. I promised to write more about the library but I got distracted with work and other topics.

In this post, I will introduce a new version of the library in which I mark the domain classes internal in order to isolate the implementation of the domain interface from the outside world making it impossible to create an instance of the domain implemenation directly. This change helps to enforce the use of the DomainAspects proxy wrapper to create and dispose of the domain object.

internal class ClassroomDomain : IClassroomDomain
{
  public List<string> GetStudents()
  {
    return new List<string>();
  }
}

I also wanted to explore the idea of getting away from XML configuration in part because Castle Project shuns it while supporting it for backward compatibility and in part because managing runtime configuration files can be problematic and convention is generally easier to support. Here's the aspect oriented service components being registered in the DomainFactory's static constructor:

container = new WindsorContainer(); //no more XML

container.Register(
  Component.For<IPrincipalProvider>()
  .ImplementedBy<PrincipalProvider>()
  .Named("PrincipalProvider")
  .LifeStyle.Transient,
  
  Component.For<IOperationAuthorizer>()
  .ImplementedBy<OperationAuthorizer>()
  .Named("OperationAuthorizer")
  .LifeStyle.Transient,
  
  Component.For<IOperationAuditor>()
  .ImplementedBy<OperationAuditor>()
  .Named("OperationAuditor")
  .LifeStyle.Transient,
  
  Component.For<OperationInterceptor>()
  .Named("OperationInterceptor")
  .LifeStyle.Transient);

Now, the DomainFactory's Create method uses the convention that the implementation has the same name without the "I" prefix on the interface name.

/// <summary>
/// Use this factory method to create a transient (one time use) instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Create<T>() where T : class
{
  var svc = container.GetService<T>();
  if (null == svc)
  {
    //resolution of type by convention MyClass implements IMyClass
    Type interfaceType = typeof(T);
    var implementedByName = interfaceType.AssemblyQualifiedName
      .Replace("." + interfaceType.Name + ",",
					"." + interfaceType.Name.Substring(1) + ",");
    Type implementedByType = Type.GetType(implementedByName);
    if (null == implementedByType) 
      throw new TypeAccessException(string.Format("Type {0} could not be found.", implementedByName));

    container.Register(Component.For(interfaceType)
      .ImplementedBy(implementedByType)
      .Named(implementedByType.Name)
      .Interceptors(InterceptorReference.ForKey("OperationInterceptor")).Anywhere
      .LifeStyle.Transient);
  }
  if (!isConfigured) throw initializationException;
  return container.Resolve<T>();
}

Now I remove the app.config from my projects and run my tests XML-config-free. There is a lot more fun stuff to explore in this library, so check back soon for more info on DomainAspects.

You can download the new code here: DomainAspects_v1_1.zip (30.25 KB).

posted on Tuesday, October 04, 2011 5:57:57 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Tuesday, September 27, 2011

In this sixth installment of C# Basics, I want to share a brief snippet of an extension method I’ve found useful that will introduce you to QDD as well. Quick and Dirty Design (QDD) is my name for having multiple tiny console application projects lying around in which I test little code snippets before putting them into something more serious. This is only necessary in projects in which TDD has not been used and no testing framework or tests are available for whatever reason.

But back to extension methods. From MSDN we learn:

“Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.”

As the MSDN article points out, the most common extension methods you may run into are the LINQ standard query operations. But don’t let that stop you from providing yourself with some very nice little extension methods like this one:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace IOTest
{
  class Program
  {
    static void Main(string[] args)
    {
      string phone1 = @"8015551212";
      string phone2 = @"(8a0d1d)d d5d5d5d-d1d2d1d2";

      if (phone1.StripNonNumeric() == phone2.StripNonNumeric())
        Console.WriteLine("true");
      else
        Console.WriteLine("false");

      Console.ReadLine();
    }
  }

  static class Ext
  {
    private static Regex nonNum = new Regex(@"[^0-9]");

    public static string StripNonNumeric(this string item)
    {
      return nonNum.Replace(item, string.Empty);
    }
  }
}
posted on Tuesday, September 27, 2011 7:17:51 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, September 22, 2011

I often need to encrypt a string and then decrypt it. Sometimes its to move some value from one server to another without the benefit of SSL. So for the fifth installment of C# Basics, I’ll share the a generic version of a little encryption utility I’ve used many times and in many places.

Most Important: If you decide to use this code, be sure to change the key and vector text to something only you know. You might even want to use a hardware security module.

I like AES (formerly known as Rijndael, pronounced “rain-doll”) but you can pick your own algorithm. The code below will work with most of the .NET symmetric encryption algorithms.

using System;
using System.Security.Cryptography;
using System.Text;

namespace MyCrypt
{
  public static class Tokenizer
  {
    //create your own unique key and vector strings
    //maybe even lock them up and require a cert to get them out
    private const string keyText = @"The quick brown fox jumps";
    private const string vectorText = @"over the lazy dog.";
    private static byte[] key = null;
    private static byte[] vector = null;

    static Tokenizer()
    {
      key = GetMD5Hash(keyText);
      vector = GetMD5Hash(vectorText);
    }

    public static string Encrypt(string val)
    {
      if (string.IsNullOrWhiteSpace(val)) return null;
      RijndaelManaged rjm = new RijndaelManaged();
      rjm.KeySize = 128;
      rjm.BlockSize = 128;
      rjm.Key = key;
      rjm.IV = vector;
      byte[] input = Encoding.UTF8.GetBytes(val);
      byte[] output = rjm.CreateEncryptor()
        .TransformFinalBlock(input, 0, input.Length);
      string data = Convert.ToBase64String(output);
      return data;
    }

    public static string Decrypt(string val)
    {
      if (string.IsNullOrWhiteSpace(val)) return null;
      try
      {
        RijndaelManaged rjm = new RijndaelManaged();
        rjm.KeySize = 128;
        rjm.BlockSize = 128;
        rjm.Key = key;
        rjm.IV = vector;
        byte[] input = Convert.FromBase64String(val);
        byte[] output = rjm.CreateDecryptor()
          .TransformFinalBlock(input, 0, input.Length);
        string data = Encoding.UTF8.GetString(output);
        return data;
      }
      catch
      {
        return null;
      }
    }

    static byte[] GetMD5Hash(string data)
    {
      MD5 md5 = MD5CryptoServiceProvider.Create();
      return md5.ComputeHash(Encoding.UTF8.GetBytes(data));
    }
  }
}
posted on Thursday, September 22, 2011 9:01:42 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, September 19, 2011

In this fourth installment of C# Basics, let’s take a look at how you handle multiple choice questions in your code. When you need to decide on a course of action based on the multiple possible values a variable may have, you have three essential choices.

  1. if | else if … | else
  2. switch
  3. Dictionary<K,T>

The code below shows you an example of each:

public class DownloadViewModel
{
  public Byte[] Contents { get; set; }
  public string FileName { get; set; }

  public string ContentType1
  {
    get
    {
      string ext = Path.GetExtension(FileName).ToLower();
      if (ext == ".pdf")
        return "application/pdf";
      else if (ext == ".txt")
        return "application/txt";
      else  
        return "application/octet-stream";
    }
  }

  public string ContentType2
  {
    get
    {
      switch (Path.GetExtension(FileName).ToLower())
      {
        case ".pdf":
          return "application/pdf";
        case ".txt":
          return "application/txt";
        default:
          return "application/octet-stream";
      }
    }
  }

  public string ContentType3
  {
    get
    {
      if (map.Count == 0) LoadMap();
      string val = string.Empty;
      if (!map.TryGetValue(Path.GetExtension(FileName).ToLower(), out val))
      {
        val = "application/octet-stream";
      }
      return val;
    }
  }

  private void LoadMap()
  {
    map.Add(".pdf", "application/pdf");
    map.Add(".txt", "application/txt");
    map.Add("*.*", "application/octet-stream");
  }

  private Dictionary<string, string> map = new Dictionary<string, string>();
}

So how do you pick which one to use? For me, the choice is easy. If I have only a few possible values that are not likely to change, I’ll use the if|else if|else construct. If I have a fair number (more than 3 and less than 16) and these values are not likely to change, I’ll use the switch statement. But if the values are likely to change or be data driven or if the number of values is greater than 15, I prefer to use a Dictionary.

Another highly valuable use of the Dictionary is when the values will kick off some action that may be lengthy or complicated. In that case, I prefer a Dictionary<T, ActionForT>. I can then retrieve the ActionForT and call the Execute method. Like this:

public class DownloadModel
{
  public Byte[] Contents { get; set; }
  public string FileName { get; set; }

  public string ContentType
  {
    get
    {
      string ext = Path.GetExtension(FileName).ToLower();
      if (ext == ".pdf")
        return "application/pdf";
      else if (ext == ".txt")
        return "application/txt";
      else  
        return "application/octet-stream";
    }
  }

  public void Save()
  {
    if (map.Count == 0) LoadMap();
    Action action = null;
    if (map.TryGetValue(Path.GetExtension(FileName).ToLower(), out action))
    {
      action(); //execute the action stored in our map
    }
    else
    {
      map["*.*"](); //execute the default action
    }
  }

  private void SavePdf()
  {
    throw new NotImplementedException();
  }

  private void SaveTxt()
  {
    throw new NotImplementedException();
  }

  private void SaveOther()
  {
    throw new NotImplementedException();
  }

  private void LoadMap()
  {
    map.Add(".pdf", new Action(SavePdf));
    map.Add(".txt", new Action(SaveTxt));
    map.Add("*.*", new Action(SaveOther));
  }

  private Dictionary<string, Action> map = new Dictionary<string, Action>();
}
posted on Monday, September 19, 2011 6:12:46 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, September 17, 2011

In this third installment of C# Basics, let's take a look at exception handling. It is one the easiest things to do poorly in an application. In C# you can capture an error and do something with it as easily as this:

try
{
  //do something that may raise an exception
}
catch (Exception e)
{
  //do something with e--log it, modify a return value, etc.
  //if you want the caller of your code to have a crack at the same exception
  throw; //raise the exception again with throw; (almost NEVER throw e;)
}

But do try your best to NEVER catch the base Exception class. Be more specific, especially where you have to do something specific with a particular type of exception and allows others to rise up the call stack. Here’s just one example of being a bit more specific:

try
{
  //call a service that reads data from SQL Server
}
catch (SqlException se)
{
  if (se.Message.Contains("Timeout"))
  {
    //send a timeout log message to the DBA service
  }
  throw; //raise it up the stack to be handled by the caller
}

Of course, you can and ought to handle different exceptions differently where required. Here’s a brief example:

try
{
  //call a service that reads data from SQL Server
  //call another service that writes to a file
}
catch (SqlException se)
{
  if (se.Message.Contains("Timeout"))
  {
    //send a timeout log message to the DBA service
  }
  throw; //raise it up the stack to be handled by the caller
}
catch (IOException iox)
{
  //special handling or logging of IO exceptions
  Console.WriteLine(iox.Message);
}
catch (Exception e)
{
  //log a general exception and rethrow
  throw;
}

And don’t forget, you can create your own specialized exception classes. In fact, with Visual Studio you can use the code snippet for Exception. Just put your cursor in a C# file, outside of a class declaration, and start typing Exception and when you see the Intellisense prompt just hit TAB TAB. And you will have the following:

[Serializable]
public class MyException : Exception
{
	public MyException() { }
	public MyException(string message) : base(message) { }
	public MyException(string message, Exception inner) : base(message, inner) { }
	protected MyException(
	 System.Runtime.Serialization.SerializationInfo info,
	 System.Runtime.Serialization.StreamingContext context)
		: base(info, context) { }
}

Flesh out your own custom exception and raise and catch it just like a pro.

public void ShowExample(int count)
{
  if (count < 0) throw new MyException("Count cannot be less than zero.");
  // . . .
}

public void CallExample()
{
  try
  {
    ShowExample(-4);
  }
  catch (MyException me)
  {
    Console.WriteLine(me.Message);
  }
}

Of course, in the above example, you would more likely want to just throw a new ArgumentException. There is a very long list of commonly used exception classes in the .NET base class libraries. Spend some time on MSDN and get familiar with them. Here’s a brief but incomplete list of common exception classes you may want to catch or throw and then catch.

  • System.ArgumentException  
  • System.ArgumentNullException  
  • System.ArgumentOutOfRangeException  
  • System.ArithmeticException  
  • System.DivideByZeroException  
  • System.FormatException  
  • System.IndexOutOfRangeException  
  • System.InvalidOperationException  
  • System.IO.IOException  
  • System.IO.DirectoryNotFoundException  
  • System.IO.EndOfStreamException  
  • System.IO.FileLoadException  
  • System.IO.FileNotFoundException  
  • System.IO.PathTooLongException  
  • System.NotImplementedException  
  • System.NotSupportedException  
  • System.NullReferenceException  
  • System.OutOfMemoryException  
  • System.Security.SecurityException  
  • System.Security.VerificationException  
  • System.StackOverflowException  
  • System.Threading.SynchronizationLockException  
  • System.Threading.ThreadAbortException  
  • System.Threading.ThreadStateException  
  • System.TypeInitializationException  
  • System.UnauthorizedAccessException
posted on Saturday, September 17, 2011 8:01:06 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Wednesday, September 14, 2011

For the second installment of C# Basics, let’s take a look at the conditional operator, sometimes known as the ternary operator. How many times have you written code like this:

if (a == b)
{
  x = y;
}
else
{
  x = z;
}

Probably never, at least not quite this simplistic or with such ancient style variable names, or one would hope anyway. But the example serves its purpose. Now use the conditional operator and convert that code to this:

x = (a == b) ? y : z;

You can read more about the conditional operator on MSDN here.

posted on Wednesday, September 14, 2011 8:20:09 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, September 12, 2011

This is the first in what I hope will be a long series of quick posts covering the basics of programming in C#. For this first installment, I’ll review the proper use and improper use of a class or struct constructor.

What is a Constructor
In a C# class, a constructor is a special code block for a class or struct called when an instance of that class or struct is created. If a constructor is not defined in code, the compiler will create a default constructor without parameters. Constructors can be overridden and can call a base class constructor.

Proper Use of a Constructor
Use a constructor to set or initialize class or struct fields. If this initialization code is lengthy, such as in the construction of a Windows Form class, move the initialization code to a partial class file and call it something like InitializeComponents. Here are a few examples:

public partial class Apple : Fruit
{
  //same as a default constructor if not constructor defined
  public Apple()
  {
  }
  
  //initialize a local class member
  public Apple(string name)
  {
    _name = name;
  }
  
  //initialize and call base class constructor
  public Apple(string name, double weight) : base(weight)
  {
    _name = name;
  }

  //constructor with conditional param to control construction behavior
  public Apple(bool initializeAll)
  {
    if (initializeAll) InitializeComponents();
  }

  //shown here but often hidden away in another file of defining the partial class
  void InitializeComponents()
  {
    //do some lengthy but simple initialization of class members
  }  
  
  private string _name;
}

Improper Use of a Constructor
Do not use a constructor for error prone or complex code. Do not use a constructor to execute tasks, business logic. I’m not going to include code examples of bad constructors but here are a few anti-patterns I’ve seen in my travels:

  • The constructor makes a call to an external service or database – BAD
  • The constructor creates child objects and calls methods on those objects to perform some business function – BAD BAD
  • The constructor asks for user input or reads from a file – BAD BAD BAD

Alternatives to a Constructor
If you require lengthy, long running or potentially error prone code to produce an instance object of a class or struct, use either a factory class or a static create method. Here’s how:

public class BookService : IBookService
{
  //a private default construtor prevents use of it outside of the class itself
  private BookService()
  {
  }
  
  public static BookService Create()
  {
    BookService instance = new BookService(); //calls private constructor
	
	//put lenghty or error prone code here that sets up the service
	
	return instance;
  }  
}

//use a factory for even more complex object creation
public static class BookServiceFactory
{
  public static IBookService Create(BookOptions options)
  {
    IBookService instance;
	
	//based on the BookOptions provide create the proper
	//concrete instance of an IBookService interface
	
	return instance;
  } 
}

Of course this is not a comprehensive treatment. It’s a blog post. If you want more, buy a book. If you have topics you would like to see addressed in future installments, please let me know.

posted on Monday, September 12, 2011 9:35:17 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, September 10, 2011

In my last post, I covered getting the Berkeley DB SQL API running under the covers of the System.Data.SQLite library for .NET. Another weekend has come and I’ve had some time to run some tests. The whitepaper Oracle Berkeley DB SQL API vs. SQLite API indicates that the Berkeley engine will have relatively the same read speed as SQLite but better write speed due to it’s page locking vs. file locking.

Berkeley Read Bug
Originally, my code would write a certain number of rows in a given transaction on one or more threads and then read all rows on one or more threads, but I had to give up on my read code because the Berkeley implementation of System.Data.SQLite threw a "malloc() failed out of memory" exception whenever I ran the read test with more than one thread. You can read the code below and decide for yourself whether I made a mistake or not, but the test ran fine with the SQLite assembly from the sqlite.org site.

The Tests
There were four tests, each inserting similar but different data into a single table with a column representing each of the main data types that might be used in a typical application. Two single threaded tests, the first inserting 6,000 rows in a single transaction and the second 30,000 rows. The third and fourth tests were multithreaded: 6 threads inserting 1,000 rows each and then 10 threads inserting 500 rows each. 

Here’s the SQL for the table:

CREATE TABLE [TT] 
(
  [src] TEXT, 
  [td] DATETIME, 
  [tn] NUMERIC, 
  [ti] INTEGER, 
  [tr] REAL, 
  [tb] BLOB
);

The Results
The results do not show a vast difference in insert speed for Berkeley as I might have expected. The tests were run on an AMD 6 core machine with 8GB of RAM. I’m writing to an SSD drive which may or may not affect results as well.

sqlitevbdb

You may choose to interpret the results differently, but I don’t see enough difference to make me abandon the more stable SQLite 3 engine at this time.

The Code
I invite you to review the code. If I’ve missed something, please let me know. It’s pretty straightforward. With each test, I wipe out the database environment entirely, starting with a fresh database file. I use the System.Threading.Tasks library.

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("SQLite Tests");
    var tester = new Tester();
    tester.DoTest("1 thread with 6000 rows", 1, 6000);
    tester.DoTest("6 threads with 1000 rows each", 6, 1000);

    tester.DoTest("1 thread with 30000 rows", 1, 30000);
    tester.DoTest("10 threads with 500 rows each", 10, 500);

    Console.WriteLine("tests complete");
    Console.ReadLine();
  }
}

class Tester
{
  public void DoTest(string testName, int threadCount, int rowCount)
  {
    DataMan.Create();
    Console.WriteLine("");
    Console.WriteLine(testName + " started:");

    List<Task> insertTasks = new List<Task>();
    DateTime beginInsert = DateTime.Now;
    for (int i = 0; i < threadCount; i++)
    {
      insertTasks.Add(Task.Factory.StartNew(() => InsertTest(i, rowCount), TaskCreationOptions.None));
    }

    Task.WaitAll(insertTasks.ToArray());
    DateTime endInsert = DateTime.Now;
    TimeSpan tsInsert = endInsert - beginInsert;

    //List<Task> readTasks = new List<Task>();
    //DateTime beginRead = DateTime.Now;
    //for (int i = 0; i < threadCount; i++)
    //{
    //   readTasks.Add(Task.Factory.StartNew(() => ReadTest(i), TaskCreationOptions.None));
    //}

    //Task.WaitAll(readTasks.ToArray());
    //DateTime endRead = DateTime.Now;
    //TimeSpan tsRead = endRead - beginRead;

    double rowsPerSecondInsert = (threadCount * rowCount) / tsInsert.TotalSeconds;
    //double rowsPerSecondRead = (threadCount * rowCount) / tsRead.TotalSeconds;
    Console.WriteLine("{0} threads each insert {1} rows in {0} ms", threadCount, rowCount, tsInsert.TotalMilliseconds);
    //Console.WriteLine("{0} threads each read all rows in {1} ms", threadCount, tsRead.TotalMilliseconds);
    Console.WriteLine("{0} rows inserted per second", rowsPerSecondInsert);
    //Console.WriteLine("{0} rows read per second", rowsPerSecondRead);
  }

  void InsertTest(int threadId, int rowCount)
  {
    DateTime begin = DateTime.Now;
    DataMan.InsertRows(rowCount);
    DateTime end = DateTime.Now;
    TimeSpan ts = end - begin;
    //Console.WriteLine("{0} lines inserted in {1} ms on thread {2}", rowCount, ts.TotalMilliseconds, threadId);
  }

  void ReadTest(int threadId)
  {
    DateTime begin = DateTime.Now;
    int count = DataMan.ReadAllRows();
    DateTime end = DateTime.Now;
    TimeSpan ts = end - begin;
    //Console.WriteLine("{0} rows read in {1} ms on thread {2}", count, ts.TotalMilliseconds, threadId);
  }
}

internal static class DataMan
{
  private const string DbFileName = @"C:\temp\bdbvsqlite.db";
  private const string DbJournalDir = @"C:\temp\bdbvsqlite.db-journal";

  public static void Create()
  {
    if (File.Exists(DbFileName)) File.Delete(DbFileName);
    if (Directory.Exists(DbJournalDir)) Directory.Delete(DbJournalDir, true);

    //Console.WriteLine(SQLiteConnection.SQLiteVersion);
    using (SQLiteConnection conn = new SQLiteConnection())
    {
      conn.ConnectionString = "Data Source=" + DbFileName + ";";
      conn.Open();
      using (SQLiteCommand cmd = conn.CreateCommand())
      {
        cmd.CommandTimeout = 180;
        cmd.CommandText = "DROP TABLE IF EXISTS [TT]; CREATE TABLE [TT] ([src] TEXT, [td] DATETIME, [tn] NUMERIC, [ti] INTEGER, [tr] REAL, [tb] BLOB);";
        cmd.CommandType = System.Data.CommandType.Text;
        int result = cmd.ExecuteNonQuery();
      }
      conn.Close();
    }
  }

  public static void InsertRows(int rowCount)
  {
    SQLiteParameter srParam = new SQLiteParameter();
    SQLiteParameter tdParam = new SQLiteParameter();
    SQLiteParameter tnParam = new SQLiteParameter();
    SQLiteParameter tiParam = new SQLiteParameter();
    SQLiteParameter trParam = new SQLiteParameter();
    SQLiteParameter tbParam = new SQLiteParameter();
    Random rnd = new Random(DateTime.Now.Millisecond);

    using (SQLiteConnection conn = new SQLiteConnection())
    {
      conn.ConnectionString = "Data Source=" + DbFileName + ";";
      conn.Open();
      using (SQLiteTransaction trans = conn.BeginTransaction())
      using (SQLiteCommand cmd = conn.CreateCommand())
      {
        cmd.CommandTimeout = 180;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "INSERT INTO [TT] ([src],[td],[tn],[ti],[tr],[tb]) VALUES (?,?,?,?,?,?);";
        cmd.Parameters.Add(srParam);
        cmd.Parameters.Add(tdParam);
        cmd.Parameters.Add(tnParam);
        cmd.Parameters.Add(tiParam);
        cmd.Parameters.Add(trParam);
        cmd.Parameters.Add(tbParam);

        int count = 0;
        while (count < rowCount)
        {
          var data = MakeRow(rnd);
          srParam.Value = data.src;
          tdParam.Value = data.td;
          tnParam.Value = data.tn;
          tiParam.Value = data.ti;
          trParam.Value = data.tr;
          tbParam.Value = data.tb;
          int result = cmd.ExecuteNonQuery();
          count++;
        }
        trans.Commit();
      }
      conn.Close();
    }
  }

  public static int ReadAllRows()
  {
    List<DRow> list = new List<DRow>();
    using (SQLiteConnection conn = new SQLiteConnection())
    {
      conn.ConnectionString = "Data Source=" + DbFileName + ";";
      conn.Open();
      using (SQLiteCommand cmd = conn.CreateCommand())
      {
        cmd.CommandTimeout = 180;
        cmd.CommandText = "SELECT [rowid],[src],[td],[tn],[ti],[tr],[tb] FROM [TT];";
        using (SQLiteDataReader reader = cmd.ExecuteReader())
        {
          while (reader.Read())
          {
            var row = new DRow
            {
              rowid = reader.GetInt64(0),
              src = reader.GetString(1),
              td = reader.GetDateTime(2),
              tn = reader.GetDecimal(3),
              ti = reader.GetInt64(4),
              tr = reader.GetDouble(5)
              //tb = (byte[])reader.GetValue(6)
            };
            list.Add(row);
          }
          reader.Close();
        }
      }
      conn.Close();
    }
    return list.Count;
  }

  private static DRow MakeRow(Random rnd)
  {
    int start = rnd.Next(0, 250);
    byte[] b = new byte[512];
    rnd.NextBytes(b);
    return new DRow
    {
      src = spear.Substring(start, 250),
      td = DateTime.Now,
      tn = rnd.Next(2999499,987654321),
      ti = rnd.Next(3939329,982537553),
      tr = rnd.NextDouble(),
      tb = b
    };
  }

  private const string spear = @"FROM fairest creatures we desire increase,That thereby beauty's rose might never die,But as the riper should by time decease,His tender heir might bear his memory:But thou, contracted to thine own bright eyes,Feed'st thy light'st flame with self-substantial fuel,Making a famine where abundance lies,Thyself thy foe, to thy sweet self too cruel.Thou that art now the world's fresh ornamentAnd only herald to the gaudy spring,Within thine own bud buriest thy contentAnd, tender churl, makest waste in niggarding.Pity the world, or else this glutton be,To eat the world's due, by the grave and thee.";
}

internal class DRow
{
  public long rowid { get; set; }
  public string src { get; set; }
  public DateTime td { get; set; }
  public decimal tn { get; set; }
  public long ti { get; set; }
  public double tr { get; set; }
  public byte[] tb { get; set; }
}
posted on Saturday, September 10, 2011 10:51:47 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, August 21, 2011

I wrote about getting SQLite up and working in Visual Studio 2010 and your .NET 4.0 projects in June. Then I got distracted with work and didn’t have a chance to come back to my exploration of SQLite until today. So I decided to look to see if we have a new version. Yes, the new System.Data.SQLite install for 1.0.74.0 (SQLite version 3.7.7.1 which includes a few bug fixes) is ready to download and install.

Unfortunately, the designers are still not available, so if you want any designer, however buggy, in Visual Studio, you’re still stuck with my original path in my previous post. (See the readme once you finish the 1.0.74.0 install.)

After a variety of experiments with the new installer, I ended up taking the following steps that led to successfully running my budding test/prototype application. Follow these steps and you won’t go too wrong:

  1. Uninstall all SQLite related items from Control Panel | Program and Features
  2. Download and install my favorite free SQLite admin tool from http://osenxpsuite.net/?xp=3.
  3. Download the latest from http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki. In my case, it was the sqlite-netFx40-setup-bundle-x64-2010-1.0.74.0.exe.
  4. This will have removed some GAC items and NOT put 1.0.74.0 into GAC. At least on my machine. I could not get the assemblies into the GAC to save my life.
  5. Make sure your project references are pointed to the correct version and that you have Copy Local set to true.
  6. Change your config settings to remove useLegacyV2RuntimeActivationPolicy=true from the startup node like this:
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
      </startup>
  7. Change your config settings in DbProviderFactories to remove strong name reference like this:
      <system.data>
        <DbProviderFactories>
          <remove invariant="System.Data.SQLite" />
          <add name="SQLite Data Provider"
              invariant="System.Data.SQLite"
              description=".Net Framework Data Provider for SQLite"
              type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
        </DbProviderFactories>
      </system.data>
  8. Test to taste.
posted on Sunday, August 21, 2011 11:30:56 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Saturday, June 04, 2011

Be sure to read upgrade instructions I've just posted as a follow-up to this post.

I’m just starting to play with SQLite and the System.Data.SQLite library created by Robert Simpson and taken over by the SQLite.org folks. In attempting to get things working in Visual Studio 2010, I ran into a few issues, so this post is as much a reminder for myself as it is a help for other .NET developers who wish to use SQLite from within Visual Studio 2010.

The current binary installers from sqllite.org for the System.Data.SQLite .NET assembly do not include the Visual Studio designers or the ADO.NET driver required for use of SQLite in the Server Explorer. So here’s the winning combination I’ve found for getting my environment set up properly.

  1. Download and install version 1.0.66.0 from sourceforge.net because current binary installs on SQLite.org at system.data.sqlite.org do not include the Visual Studio designer or ADO.NET driver install.
     
  2. Download and install the latest versions (x86 and x64) from system.data.sqlite.org (currently 1.0.73.0 which contains the SQLite 3.7.6.3 engine).
    Important Note: If you have Visual Studio 2008 and 2010, be sure to choose both when prompted as I found reports from others who had problems otherwise.
     
  3. Copy the x86 binaries into and overwriting file at C:\Program Files (x86)\SQLite.NET\bin (assuming you used the default install location for version 1.0.66.0 and you're running x64 Windows). And if you are on an x64 box, copy the x64 binaries to the C:\Program Files (x86)\SQLite.NET\bin\x64 directory, overwriting existing files.

Now you can open Visual Studio 2010 and navigate to the Server Explorer, right-click the Data Connections node, choose Add Connection and click the Change button for Data source. You can then select the SQLite Database file source like this:

dsource

Click the new button and navigate to your desired directory and supply a file name and you’ll end up with something like this:

dconn

With a new data connection, you can use the table designer, but it has limitations and it’s probably not the best approach with an embedded database engine from a development perspective anyway, since generally you’re going to want your app to be able to create the database from script embedded in code.

So now all that’s left to get started writing code against your database is to add your references like this:

dref

And since Entity Framework supports SQLite, you can add your ADO.NET Entity Data Model to your project and it will produce a nice connection string like this for you (VB-like line _ breaks added):

<connectionStrings>
  <add name="testEntities"
    connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl| _
    res://*/Model1.msl;provider=System.Data.SQLite; _
    provider connection string=&quot;data source=C:\Code\Projects\test.db&quot;"
    providerName="System.Data.EntityClient" />
</connectionStrings>

or a non EF 4 connection string of

<connectionStrings>
  <add name="mytest"
    connectionString="data source=C:\Code\Projects\test.db;"
    providerName="System.Data.SQLite" />
</connectionStrings>

Now remember, model first is not currently supported, so you need to create your data and then update your model from data. You also need to make sure that you add the following to your config file or you’ll get a nasty runtime error:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" />
</startup>

UPDATE (30 minutes later) Just a bit more testing reveals that I missed one step. Very important to know and use.

First, I reinstalled the x86 and then x64 latest installs and checked the checkboxes to install to the GAC and modify the path. Then I ran “test” from the command line and after modifying the connection string by giving the file a path like C:\temp\test.db, the tests ran fine. Looking at the chm help file and the test.exe.config revealed the trick I needed.

The 1.0.66.0 install adds a factory reference to your .NET machine.config file like this:

</DbProviderFactories>
  ...
  <add name="SQLite Data Provider"
    invariant="System.Data.SQLite"
    description=".Net Framework Data Provider for SQLite"
    type="System.Data.SQLite.SQLiteFactory,
      System.Data.SQLite,
      Version=1.0.66.0,
      Culture=neutral,
      PublicKeyToken=db937bc2d44ff139" />
</DbProviderFactories>

While this entry makes the Data Connection and designer possible, it will cause you problems when trying to run using the latest 1.0.73.0 referenced assemblies until you add this to your own config file:

<system.data>
  <DbProviderFactories>
    <remove invariant="System.Data.SQLite" />
    <add name="SQLite Data Provider"
      invariant="System.Data.SQLite"
      description=".Net Framework Data Provider for SQLite"
      type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
  </DbProviderFactories>
</system.data>

Next step: experiment with updating my machine.config in its many incarnations to point to the latest and greatest x64 version 1.0.73.0 with token db937bc2d44ff139 like this:

</DbProviderFactories>
  ...
  <add name="SQLite Data Provider"
    invariant="System.Data.SQLite"
    description=".Net Framework Data Provider for SQLite"
    type="System.Data.SQLite.SQLiteFactory,
    System.Data.SQLite,
    Version=1.0.73.0,
    Culture=neutral,
    PublicKeyToken=db937bc2d44ff139" />
</DbProviderFactories>

Note that this will move the machine.config reference to the MSIL (Any CPU) version rather than the x86 version. For my machine, this means making changes in (and remember to open as Administrator so you can save the file):

C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\machine.config
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config

Rebooting, just to be paranoid.

And now, run the same test after commenting out the local app.config’s <system.data><DbProviderFactories> node and everything works as expected. No more bad image exception. And the Data Connection designer continues to operate as expected. Now on to some real coding.

posted on Saturday, June 04, 2011 1:01:21 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Friday, May 27, 2011

How similar are these two strings? Does string X sound like string Y? Could they be duplicates? Is the difference between string N and string M just a typo? There are many scenarios in enterprise software development where the answers to these questions can be highly significant.

In my search to answer such questions with code, the most helpful resource I’ve ever found was presented by George M. Brown on www.codeguru.com who implemented four well known and powerful fuzzy string matching algorithms in VBA for Access a few years ago. In an effort to convert these algorithms to C#, I found two alternatives that saved me some time (see below).

The four algorithms, with requisite Wikipedia links, are:

Each of the algorithms have been implemented here as extensions to the string and string array. Before we get to the code, let’s take a look at some results. Here are two very simplistic tests. The algorithms are not combined in any way. You can experiment with them and create your own secret sauce.

Name Matching for (mispelled deliberately): "Jensn"
The first test result set presents the raw output of the algorithms on a mispelled surname (mine) against a list of other surnames. I’ve highlighted the best score.

Dice Coefficient for Jensn:
    .00000 against Adams
    .46154 against Benson
    .00000 against Geralds
    .37500 against Johannson
    .42857 against Johnson
    .76923 against Jensen
    .30769 against Jordon
    .30769 against Madsen
    .00000 against Stratford
    .14286 against Wilkins

Levenshtein Edit Distance for Jensn:
    4 against Adams
    2 against Benson
    5 against Geralds
    5 against Johannson
    3 against Johnson
    1 against Jensen
    4 against Jordon
    4 against Madsen
    8 against Stratford
    6 against Wilkins

Longest Common Subsequence for Jensn:
    .04000, s against Adams
    .33333, ensn against Benson
    .05714, es against Geralds
    .08889, jnsn against Johannson
    .17143, jnsn against Johnson
    .56667, jensn against Jensen
    .06667, jn against Jordon
    .13333, en against Madsen
    .02222, s against Stratford
    .11429, ns against Wilkins

Double Metaphone for Jensn: ANSN
    ATMS metaphone for Adams
    PNSN metaphone for Benson
    JRLT metaphone for Geralds
    AHNS metaphone for Johannson
    ANSN metaphone for Johnson
    ANSN metaphone for Jensen
    ARTN metaphone for Jordon
    MTSN metaphone for Madsen
    STTR metaphone for Stratford
    FLKN metaphone for Wilkins

Address Matching for "2130 South Fort Union Blvd."
The second test is the same code run against multiple addresses trying to match a given address. Let’s see how it turned out.

Dice Coefficient for 2130 South Fort Union Blvd.:
    .16000 against 2689 East Milkin Ave.
    .10000 against 85 Morrison
    .27273 against 2350 North Main
    .07843 against 567 West Center Street
    .66667 against 2130 Fort Union Boulevard
    .61538 against 2310 S. Ft. Union Blvd.
    .42553 against 98 West Fort Union
    .12245 against Rural Route 2 Box 29
    .05000 against PO Box 3487
    .04444 against 3 Harvard Square

Levenshtein Edit Distance for 2130 South Fort Union Blvd.:
    18 against 2689 East Milkin Ave.
    22 against 85 Morrison
    18 against 2350 North Main
    22 against 567 West Center Street
    11 against 2130 Fort Union Boulevard
    8 against 2310 S. Ft. Union Blvd.
    14 against 98 West Fort Union
    19 against Rural Route 2 Box 29
    22 against PO Box 3487
    22 against 3 Harvard Square

Longest Common Subsequence for 2130 South Fort Union Blvd.:
    .02116, 2 st in v. against 2689 East Milkin Ave.
    .02020,  son against 85 Morrison
    .04444, 230 oth in against 2350 North Main
    .01010,  st t  against 567 West Center Street
    .25481, 2130 fort union blvd against 2130 Fort Union Boulevard
   .25765, 230 s ft union blvd. against 2310 S. Ft. Union Blvd.
    .25514,  st fort union against 98 West Fort Union
    .02593,  out  o  against Rural Route 2 Box 29
    .01347, o o  against PO Box 3487
    .01389, 3 hrvd against 3 Harvard Square

Double Metaphone for 2130 South Fort Union Blvd.: STFR
    STML metaphone for 2689 East Milkin Ave.
    MRSN metaphone for 85 Morrison
    NRTM metaphone for 2350 North Main
    SSNT metaphone for 567 West Center Street
    FRTN metaphone for 2130 Fort Union Boulevard
    SFTN metaphone for 2310 S. Ft. Union Blvd.
    STFR metaphone for 98 West Fort Union
    RRLR metaphone for Rural Route 2 Box 29
    PPKS metaphone for PO Box 3487
    RFRT metaphone for 3 Harvard Square

As you can see, the double metaphone algorithm may not be as useful on its own as the other algorithms. But when you put them together in creative ways, you’ll get a very powerful result.

Here’s how easy the algorithms, as extension methods, are to use.

private static void NameMatching()
{
	//name matching
	string input = "Jensn";
	string[] surnames = new string[] { 
		"Adams",
		"Benson",
		"Geralds",
		"Johannson",
		"Johnson",
		"Jensen",
		"Jordon",
		"Madsen",
		"Stratford",
		"Wilkins"
		};

	Console.WriteLine("Dice Coefficient for Jensn:");
	foreach (var name in surnames)
	{
		double dice = input.DiceCoefficient(name);
		Console.WriteLine("\t{0} against {1}", 
			dice.ToString("###,###.00000"), name);
	}

	Console.WriteLine();
	Console.WriteLine("Levenshtein Edit Distance for Jensn:");
	foreach (var name in surnames)
	{
		int leven = input.LevenshteinDistance(name);
		Console.WriteLine("\t{0} against {1}", leven, name);
	}

	Console.WriteLine();
	Console.WriteLine("Longest Common Subsequence for Jensn:");
	foreach (var name in surnames)
	{
		var lcs = input.LongestCommonSubsequence(name);
		Console.WriteLine("\t{0}, {1} against {2}", 
			lcs.Item2.ToString("###,###.00000"), lcs.Item1, name);
	}

	Console.WriteLine();
	string mp = input.ToDoubleMetaphone();
	Console.WriteLine("Double Metaphone for Jensn: {0}", mp);
	foreach (var name in surnames)
	{
		string nameMp = name.ToDoubleMetaphone();
		Console.WriteLine("\t{0} metaphone for {1}", nameMp, name);
	}
}

Source References
In researching and finding these algorithms, I poured over what seemed like hundreds of articles, blogs and open source resources. In the end, I settled on three primary sources and made certain modifications to suite my own needs. Here they are.

Additional references:

I recommend you spend time with these sources and doing your own research. Undoubtedly you will come up with even better algorithms. When you do, please share them with us here.

Download the complete code here: FuzzyStrings.zip (15.27 KB)

posted on Friday, May 27, 2011 3:31:33 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, May 05, 2011

Tracking down a problem in a commercial .NET library today, I found this little gem (identifying code in the try removed):

try
{
   //any code that could fail in any way here
}
catch (Exception)
{
}

Not only should this construct not compile, any attempt to do so should cause your computer to explode.

posted on Thursday, May 05, 2011 7:50:09 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Thursday, April 28, 2011

A few days ago, a fellow programmer asked me a common question. How do you print odd numbers between one integer value and another. It's a common question and the quickest solution that came to mind is the common for loop with a simple if and the mod operator.

Later I began toying with the question and in combination wanted to experiment with an alternative to the limited ForEach extension method on IList<T>. What you see below is the result of a little tinkering and tweaking along with some fluent goodness.

I considered naming my custom extesion method ForEach but decided to use something different to remind myself that it is not your grandfather's ForEach extension method. So I named it ForEvery and in the middle of playing with that, I ended up creating the Once extension method on IEnumerable<T>.

class Program
{
   static void Main(string[] args)
   {
      PrintOdds(1, 100);
      Console.ReadLine();
   }

   static void PrintOdds(int x, int y)
   {
      Console.WriteLine("Odds with traditional for and if");
      for (int i = x; i <= y; i++)
      {
         if (i % 2 != 0) Console.Write("{0}, ", i);
      }

      Console.WriteLine();
      Console.WriteLine();
      Console.WriteLine("Odds with ToList and ForEach with if");
      Enumerable.Range(x, y - x + 1)
         .ToList()
         .ForEach(i =>
         {
            if (i % 2 != 0) Console.Write("{0}, ", i);
         });

      Console.WriteLine();
      Console.WriteLine();
      Console.WriteLine("Odds with Where then ToList and ForEach");

      Enumerable.Range(x, y - x + 1).Where(n => n % 2 != 0)
         .ToList().ForEach(i =>
         {
            Console.Write("{0}, ", i);
         });

      Console.WriteLine();
      Console.WriteLine();
      Console.WriteLine("Odds with Where and custom ForEach");

      Enumerable.Range(x, y - x + 1)
         .Where(n => n % 2 != 0)
         .ForEach(i =>
         {
            Console.Write("{0}, ", i);
         });

      Console.WriteLine();
      Console.WriteLine();
      Console.WriteLine("Odds with custom ForEvery fluent");

      Enumerable.Range(x, y - x + 1)
         .ForEvery(n => n % 2 != 0, i => 
         { 
            Console.Write("{0}, ", i);
         })
         .Once(n => n.Count() > 99, i =>
         {
            Console.WriteLine();
            Console.WriteLine("Once fluent");
            Console.WriteLine();
            Console.WriteLine("Evens with ForEvery fluent from {0} to {1}", i.Min(), i.Max());
         })
         .ForEvery(n => n % 2 == 0, i =>
         {
            Console.Write("{0}, ", i);
         });
   }
}

public static class EnumerableExtensions
{
   public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
   {
      foreach (var item in collection)
      {
         action(item);
      }
   }

   public static IEnumerable<T> Once<T>(this IEnumerable<T> collection, 
      Func<IEnumerable<T>, bool> predicate, Action<IEnumerable<T>> action)
   {
      if (predicate(collection)) action(collection);
      return collection;
   }

   public static IEnumerable<T> ForEvery<T>(this IEnumerable<T> collection, 
      Func<T, bool> predicate, Action<T> action)
   {
      foreach (var item in collection)
      {
         if (predicate(item)) action(item);
      }
      return collection;
   }
}

Drop the code into a console app and run it. If you like these little extensions, I'd love to hear from you.

posted on Thursday, April 28, 2011 9:41:15 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, January 10, 2011

The other day, a friend and I were reviewing some code like this and decided we deeply disliked it.

// var line1 = person.Address.Lines.Line1 ?? string.Empty;
// throws NullReferenceException: 
//    {"Object reference not set to an instance of an object."}

// The ugly alternative

var line1 = person.Address == null
        ? "n/a"
        : person.Address.Lines == null
        ? "n/a"
        : person.Address.Lines.Line1;

If you have ever written code like that or even worse, with the if (obj != null) statements, then you can certainly relate to our lack of love for the constructs required to avoid the dratted NullReferenceException.

So we experimented with a solution and nearly got there. Tonight I finished that up and the new Dis class is born with the OrDat<T> method so you can now write this instead.

var line2 = Dis.OrDat<string>(() => person.Address.Lines.Line2, "n/a");

Here’s the full example and if you’re patient enough to scroll down, you’ll also find the full implementation of the Dis.OrDat class and method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeepNullCoalescence
{
  class Program
  {
    static void Main(string[] args)
    {
      var person = new Person();

      // var line1 = person.Address.Lines.Line1 ?? string.Empty;
      // throws NullReferenceException: 
      //    {"Object reference not set to an instance of an object."}
      
      // The ugly alternative
      var line1 = person.Address == null
              ? "n/a"
              : person.Address.Lines == null
              ? "n/a"
              : person.Address.Lines.Line1;

      // A cooler alternative
      var line2 = Dis.OrDat<string>(() => person.Address.Lines.Line2, "n/a");

      Console.WriteLine(line1);
      Console.WriteLine(line2);
      Console.ReadLine();
    }
  }

  internal class Person
  {
    public Address Address { get; set; }
  }

  internal class Address
  {
    public AddressLines Lines { get; set; }
    public string State { get; set; }
  }

  internal class AddressLines
  {
    public string Line1 { get; set; }
    public string Line2 { get; set; }
  }
}

And for the patient reader, here is the actual magic.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace DeepNullCoalescence
{
  public static class Dis
  {
    public static T OrDat<T>(Expression<Func<T>> expr, T dat)
    {
      try
      {
        var func = expr.Compile();
        var result = func.Invoke();
        return result ?? dat; //now we can coalesce
      }
      catch (NullReferenceException)
      {
        return dat;
      }
    }
  }
}
posted on Monday, January 10, 2011 7:43:27 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Saturday, October 30, 2010

I had a simple small array of objects. I wanted to send each of them into a method that would fire off and manage a long running process on each of them in a new thread pool thread.

So I remebered the coolness of the new .NET 4.0 Task and it's attendant Factory. Seemed simple enough but I quickly learned a lesson I should have already known.

I've illustrated in code my first two failures and the loop that finally got it right. Let me know what you think. Undoubtedly there is even a better way.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TaskFactoryExample
{
  public class ServerManager
  {
    IServerLib[] serverLibs;
    List<Task> taskList = new List<Task>();
    List<CancellationTokenSource> cancelTokens = new List<CancellationTokenSource>();

    public ServerManager(IServerLib[] servers)
    {
      serverLibs = servers;
    }

    // FIRST FAIL: only the last lib in the iteration gets sent to all ManageStart calls
    internal void Start_FirstFailed(string[] args)
    {
      foreach (var lib in serverLibs)
      {
        var tokenSource = new CancellationTokenSource();
        taskList.Add(Task.Factory.StartNew(() => { ManageStart(lib, args); }, tokenSource.Token));
        cancelTokens.Add(tokenSource);
      }
    }

    // SECOND FAIL: i is incremented finally to serverLibs.Length before ManageStart is called
	// resulting in an index out of range exception
    internal void Start_SecondFailed(string[] args)
    {
      for (int i = 0; i < serverLibs.Length; i++)
      {
        var tokenSource = new CancellationTokenSource();
        taskList.Add(Task.Factory.StartNew(() => { ManageStart(serverLibs[i], args); }, tokenSource.Token));
        cancelTokens.Add(tokenSource);
      }
    }

    // finally got it right - get a local reference to the item in the array so ManageStart 
    // is fed the correct serverLib object
    internal void Start(string[] args)
    {
      for (int i = 0; i < serverLibs.Length; i++ )
      {
        var serverLib = serverLibs[i];
        var tokenSource = new CancellationTokenSource();
        taskList.Add(Task.Factory.StartNew(() => { ManageStart(serverLib, args); }, tokenSource.Token));
        cancelTokens.Add(tokenSource);
      }
    }

    private void ManageStart(IServerLib lib, string[] args)
    {
      try
      {
        //code redacted for brevity
        //start long running or ongoing process with lib on threadpool thread
        lib.Start();
      }
      catch (Exception e)
      {
        //TODO: log general exception catcher
        throw; //leave in for testing
      }
    }

    internal void Stop()
    {
      try
      {
        foreach (var lib in serverLibs) lib.Stop();
        foreach (var tokenSource in cancelTokens) tokenSource.Cancel();
        foreach (var t in taskList) if (t.IsCompleted) t.Dispose();
      }
      catch (Exception e)
      {
        //TODO: log general exception catcher
        throw; //leave in for testing
      }
    }
  }
}
posted on Saturday, October 30, 2010 7:58:35 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, October 24, 2010

The DomainAspects library introduced here may be the birth of an open source project that could add real value to the .NET stack. On the other hand, it could be just a small exploration of Castle Windsor's aspect oriented programming construct called the Interceptor. Time will tell but I felt it would be worth sharing the bits at this early stage to gauge interest and get some preliminary feedback.

DomainAspects is an aspect oriented infrastructure library for domain driven .NET projects. It uses Castle Windsor's Interceptor to provide configurable aspect oriented audit logging, authorization and exception handling to domain operations. Service classes in the domain can take advantage of DomainAspects using a custom attribute, avoiding the clutter of infrastructure code in the business logic.

There are many variations for the definitions of aspect oriented programming and domain driven design. I'll let Wikipedia contributors sort out the "pure" definitions. I'm not a purist or self-declared expert on either of these topics. But for the record, I'll share my definitions of these two as succinctly as I can.

Aspect Oriented Programming - The separation of cross cutting concerns, such as logging, authorization, and exception handling, from the business logic core of the application. AOP can allow the business application developer to focus on implementing business requirements without worrying about consistently applying and debugging repetitive infrastructure code throughout the application.

Domain Driven Design - An approach to writing applications where the domain is the core of the application. The domain defines the data, data persistence and business operations available to a user interface or service host of which it has no knowledge. DDD seeks to separate the mechanical concerns of the application host from the core business operations and data in order to maximize the potential for application developer specialization and code re-use. Common constructs seen in the domain are entities, services and repositories with a dependency on a persistence framework or data access layer.

DomainAspects brings AOP to DDD to make it easier to write the domain layer. Now I can write my acceptance criteria driven tests for a business operation and then implement that business operation with pure business logic while one or two simple attributes assure the consistent execution of infrastructure code every time that method is called. Here's a simplistic example:

[InterceptOperation, Authorize(RolesRule = "!Guest")]
public string GetUserPhoneNumber(int userId)
{
  var userRepository = new UserRepository();
  return userRepository.GetUser(userId).PhoneNumber;
}

And using that operation is just as easy. Here's the code to call that operation using the DomainProxy (normal UI exception handling not shown):

private void ShowPhoneButton_Clicked(object sender, EventArgs e)
{
  using (var proxy = new DomainProxy<IUserService>())
  {
    var phone = proxy.Service.GetUserPhoneNumber(userId);
    this.txtPhone.Text = phone;
  }
}

The client or host code uses the DomainProxy wrapper to get an IDisposable instance of a Castle Windsor container instance of the service class which is in turn wrapped by the Interceptor proxy. Here’s a look at these three important classes:

da_class_1

Under the covers, three specific DomainAspects infrastructure things are happening via the auditor and authorizer objects injected into the interceptor along with the principal provider object injected into the authorizer object. Here’s a look at the classes in question.

da_class_2

The first two things that happen occur before the proxy proceeds with calling the business operation. The third only happens if the business operation code throws an exception.

  1. The OperationAuditor's LogOperationInvoked method is called allowing the invokation to be logged by your implementation of IOperationAuditor.
  2. The OperationAuthorizer's Authorize method is called where the authorize attribute's rule is enforced. In this case, the logged in user cannot be in the role "Guest" or an exception will be thrown. Note that the IPrincipal used to determine this is provided by the injected PrincipalProvider implementation.
  3. The OperationAuditor's LogOperationException method is called if the business operation throws an exception.

In future posts, I'll write about each of these parts and how they work, but for now, download the code and let me know what you think. You will need to download the Castle Windsor library and correct the references in the solution depending on where you have installed the Castle project library.

Download the code here: DomainAspects.zip (29.39 KB)

posted on Sunday, October 24, 2010 2:51:25 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, October 21, 2010

It builds and runs fine on your local machine but when you deploy it to the server, all kinds of problems arise. Before you spent countless hours chasing ghosts, make sure you have your .NET projects on the same page, namely building for the right .NET Framework and targeting the right platform.

Open your project properties bag and try these first and then narrow it down. First, make sure your target frameworks for all your projects are in synch.

targetframework

Then make sure you give yourself as much latitude as you can by setting your platform target to Any CPU:

anycpu

Once you know your project and its dependencies are all on the same page and you still have problems on your deployment target, then go ahead and spend countless hours chasing ghosts.

posted on Thursday, October 21, 2010 9:40:47 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, October 16, 2010

Do you ever get frustrated with the limited nature of the ASP.NET MVC AuthorizeAttribute class’s limited Roles property which provides only a simple comma delimited list and creates a simple OR list? Would you like to be able to exclude specific roles or have a more complex expression such as:

!Guest & ((Admin | Supervisor) | (Lead & Weekend Supervisor))

Well, now you can. All thanks to the random convergence of great minds! (Or perhaps the obsessions of two code monkeys who have no life. You decide.)

While working on a project for a future blog post, I discussed the code with Nick Muhonen of Useable Concepts and MSDN author who offered to write a parser for an authorization strategy in the project that uses attributes similar to the ASP.NET MVC AuthorizeAttribute class.

Nick showed me the parser yesterday and after I agreed to say that I liked the code, he sent it to me with his blessing to use in my blog post project I’ve been working on. As I began to work the code into my project, I realized that this code deserved its own post as a descendant of the real ASP.NET MVC AuthorizeAttribute class for general use in the ASP.NET MVC world. I’m still planning to use the same parser for my future post, but here it is for your general use in your ASP.NET MVC projects.

The power starts in the return value of the RoleParser’s Parse method, the IRule:

public interface IRule
{
  bool Evaluate(Func<string, bool> matcher);
  string ShowRule(int pad);
}

Here’s the simple, but powerful SuperAuthorizeAttribute class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using SuperMvc.RoleRules;

namespace SuperMvc
{
  public class SuperAuthorizeAttribute : AuthorizeAttribute
  {
    private string _superRoles;
    private IRule _superRule;

    public string SuperRoles
    {
      get
      {
        return _superRoles ?? String.Empty;
      }
      set
      {
        _superRoles = value;
        if (!string.IsNullOrWhiteSpace(_superRoles))
        {
          RoleParser parser = new RoleParser();
          _superRule = parser.Parse(_superRoles);
        }
      }
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
      base.OnAuthorization(filterContext);
      if (_superRule != null)
      {
        var result = _superRule.Evaluate(role => filterContext.HttpContext.User.IsInRole(role));
        if (!result)
        {
          filterContext.Result = new HttpUnauthorizedResult();
        }
      }
    }
  }
}

You’ll note that the setter on SuperRoles creates a parser instance and generates an IRule for later use in the OnAuthorization override. This allows us to parse once and run many times, making the evaluation even faster.

I’m not going to dive into how the parser works. I’ll let Nick blog about that. The great thing is that it does work and it’s very fast. Here’s how it’s put to use. First a look at the controller code on which we test it and a peek at one or two of the test methods. The HomeController has been modified with some test actions:

//partial listing

public class HomeController : Controller
{
  [SuperAuthorize(SuperRoles = "!Guest")]
  public ActionResult AboutTestOne()
  {
    return RedirectToAction("About");
  }

  [SuperAuthorize(SuperRoles = "Admin & Local Office | Local Office Admin")]
  public ActionResult AboutTestFive()
  {
    return RedirectToAction("About");
  }

  [SuperAuthorize(SuperRoles = "!Guest & !(SuperUser | DaemonUser) & ((Admin & Local Office | Local Office Admin) & !User)")]
  public ActionResult AboutCrazyTwo()
  {
    return RedirectToAction("About");
  }

  public ActionResult About()
  {
    return View();
  }
}

And here’s the tests, including some crucial initialization logic, that allows us to verify the attribute works.

[TestClass]
public class HomeControllerTest
{
  [TestInitialize]
  public void Initialize()
  {
    string[] roles =
      {
         "Admin",
         "User",
         "Local Office"
      };
    HttpContextHelper.SetCurrentContext(new FakePrincipal("Fake", "testuser", true, roles));
  }

  //[SuperAuthorize(SuperRoles = "!Guest")]
  //public ActionResult AboutTestOne()
  [TestMethod]
  public void AboutTestOne()
  {
    // Arrange
    ControllerContext context;
    var invoker = GetInvoker<RedirectToRouteResult>(out context);

    // Act
    var invokeResult = invoker.InvokeAction(context, "AboutTestOne");

    // Assert
    Assert.IsTrue(invokeResult);
  }

  //[SuperAuthorize(SuperRoles = "Admin & Local Office | Local Office Admin")]
  //public ActionResult AboutTestFive()
  [TestMethod]
  public void AboutTestFive()
  {
    // Arrange
    ControllerContext context;
    var invoker = GetInvoker<RedirectToRouteResult>(out context);

    // Act
    var invokeResult = invoker.InvokeAction(context, "AboutTestFive");

    // Assert
    Assert.IsTrue(invokeResult);
  }

  //[SuperAuthorize(SuperRoles = "!Guest & !(SuperUser | DaemonUser) & ((Admin & Local Office | Local Office Admin) & !User)")]
  //public ActionResult AboutCrazyTwo()
  [TestMethod]
  public void AboutCrazyTwo()
  {
    // Arrange
    ControllerContext context;
    var invoker = GetInvoker<HttpUnauthorizedResult>(out context);

    // Act
    var invokeResult = invoker.InvokeAction(context, "AboutCrazyTwo");

    // Assert
    Assert.IsTrue(invokeResult);
  }

  private FakeControllerActionInvoker<TExpectedResult> GetInvoker<TExpectedResult>(out ControllerContext context) where TExpectedResult : ActionResult
  {
    HomeController controller = new HomeController();
    var httpContext = new HttpContextWrapper(HttpContext.Current);
    context = new ControllerContext(httpContext, new RouteData(), controller);
    controller.ControllerContext = context;
    var invoker = new FakeControllerActionInvoker<TExpectedResult>();
    return invoker;
  }
}

All you have to do is download the code and plug in the SuperMvc project into your ASP.NET MVC web project and you too can have the power of parsed roles at your authorization attribute finger tips. Let me know if you like it or find an even better way to accomplish the same things.

SuperMvc.zip (281.93 KB)

posted on Saturday, October 16, 2010 4:22:31 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, May 13, 2010

Recently I extended a previous blog post and published it on Code Project under the title Generic WCF Service Host and Client. An astute reader asked about calling a service method asynchronously, something I had not given much thought.

I decided that I wanted a way to support asynchronous calls on the generic WCF client without having to modify my service contract (interface) or implementation class libraries. I also wanted a way to do asynchronous calls with as little client code as possible, which meant support for a simple event based solution.

So I went to work experimenting. If you want the WCF version of the solution, visit the Code Project article and you can get the updated code there just as soon as I get an update published.

In this post, I'll present a more generalized version of the solution I created. The GenericAsyncWrapper<T> class is the heart of the solution. Take any instance of T (any class) and GenericAsyncWrapper<T> puts an event based asynchronous wrapper that allows you to call any method on the instance asynchronously.

I'm not going to explain how standard delegates are used to make asynchronous calls. If you want to brush up on the basics, check out Microsoft's How to call a Visual C# method asynchronously along with thousands of other online resources. I will show some examples of using standard generic delegates to do the asynchronous calls to compare with the use of the generic wrapper's event model.

Here's my test class. It does nothing, as you can see, but it does allow me to test my wrapper.

internal class MyTestClass
{
  public void DoNothingNoParams()
  {
    Console.WriteLine("MyTestClass.DoNothingNoParams called on thread: {0}", 
      Thread.CurrentThread.ManagedThreadId);
  }

  public string DoSomething(string input)
  {
    Console.WriteLine("MyTestClass.DoSomething called on thread: {0}", 
      Thread.CurrentThread.ManagedThreadId);
    return "Output of DoSomething with " + input + " as input.";
  }
}

And here's the test code. Just a simple console app that first shows the test class being called directly, then using standard generic delegates and finally using the wrapper. One advantage you may note is that with the wrapper, you also get all your original input params back.

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Main called on thread: {0}", Thread.CurrentThread.ManagedThreadId);
    Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++");
    Console.WriteLine("synchronous calls");
    var mytest = new MyTestClass();
    mytest.DoNothingNoParams();
    string output = mytest.DoSomething("my name is Tyler");
    Console.WriteLine(output);

    Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++");
    Console.WriteLine("Action<> and Func<> delgate calls");
    Action action = new Action(mytest.DoNothingNoParams);
    action.BeginInvoke(new AsyncCallback(ActionCallback), "test1");

    Func<string, string> func = new Func<string, string>(mytest.DoSomething);
    func.BeginInvoke("my name is Arnold", new AsyncCallback(FuncTTCallback), "test2");

    Thread.Sleep(1000);

    Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++");
    Console.WriteLine("asynchronous wrapper calls");
    var wrapper = new GenericAsyncWrapper<MyTestClass>(mytest);
    wrapper.AsyncCompleted += new EventHandler<GenericAsyncWrapperCompletedEventArgs>(wrapper_AsyncCompleted);
    wrapper.AsyncInvoke("DoSomething", "test2", "my name is Bob");
    wrapper.AsyncInvoke("DoNothingNoParams", "test1", null);

    Console.ReadLine();
  }

  static void FuncTTCallback(IAsyncResult result)
  {
    Console.WriteLine("FuncTTCallback called on thread: {0}", Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(250);
    Func<object, object> deleg = ((AsyncResult)result).AsyncDelegate as Func<object, object>;
    if (deleg != null)
    {
      object returnValue = deleg.EndInvoke(result);
      Console.WriteLine("FuncTTCallback return value: {0}", returnValue);
    }
  }

  static void ActionCallback(IAsyncResult result)
  {
    Console.WriteLine("ActionCallback called on thread: {0}", Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(250);
    Action deleg = ((AsyncResult)result).AsyncDelegate as Action;
    if (deleg != null)
    {
      deleg.EndInvoke(result);
    }
  }

  static void wrapper_AsyncCompleted(object sender, GenericAsyncWrapperCompletedEventArgs e)
  {
    Console.WriteLine("wrapper_AsyncCompleted called on thread: {0}", Thread.CurrentThread.ManagedThreadId);
    if (e.Error == null)
    {
      Console.WriteLine("methodName: {0}, userState: {1}, result: {2}", 
        e.MethodName, e.UserState, e.Result);
      if (e.InValues != null)
      {
        for (int i = 0; i < e.InValues.Length; i++)
        {
          Console.WriteLine("   value[{0}] = {1}", i, e.InValues[i]);
        }
      }
    }
    else
    {
      Console.WriteLine(e.Error.ToString());
    }
  }
}

Now here's the real magic. The GenericAsyncWrapper<T> class and its attendant event args class.

public class GenericAsyncWrapper<T> where T : class
{
  private T _instance;

  public GenericAsyncWrapper(T instance)
  {
    if (instance == null) throw new NullReferenceException("instance cannot be null");
    _instance = instance;
  }

  public T Instance { get { return _instance; } }

  public event EventHandler<GenericAsyncWrapperCompletedEventArgs> AsyncCompleted;

  public void AsyncInvoke(string methodName, object userState, params object[] inValues)
  {
    if (string.IsNullOrEmpty(methodName)) throw new NullReferenceException("methodName cannot be null");
    MethodInfo mi = this.Instance.GetType().GetMethod(methodName);
    if (null != mi)
    {
      Func<MethodInfo, object[], object> func = new Func<MethodInfo, object[], object>(this.ExecuteAsyncMethod);
      func.BeginInvoke(mi, inValues, new AsyncCallback(this.FuncCallback), 
        new GenericAsyncState() { UserState = userState, MethodName = methodName, InValues = inValues });
    }
    else
      throw new TargetException(string.Format("methodName {0} not found on instance", methodName));
  }

  private object ExecuteAsyncMethod(MethodInfo mi, object[] inValues)
  {
    return mi.Invoke(this.Instance, inValues);
  }

  private void FuncCallback(IAsyncResult result)
  {
    var deleg = (Func<MethodInfo, object[], object>)((AsyncResult)result).AsyncDelegate;
    var state = result.AsyncState as GenericAsyncState;
    if (null != deleg)
    {
      Exception error = null;
      object retval = null;
      try
      {
        retval = deleg.EndInvoke(result);
      }
      catch (Exception e)
      {
        error = e;
      }
      object userState = state == null ? null : state.UserState;
      string methodName = state == null ? (string)null : state.MethodName;
      object[] inValues = state == null ? null : state.InValues;
      GenericAsyncWrapperCompletedEventArgs args = new GenericAsyncWrapperCompletedEventArgs(retval, error, methodName, userState, inValues);
      if (this.AsyncCompleted != null)
        this.AsyncCompleted(this, args);
    }
  }

  private class GenericAsyncState
  {
    public object UserState { get; set; }
    public string MethodName { get; set; }
    public object[] InValues { get; set; }
  }
}

public class GenericAsyncWrapperCompletedEventArgs : EventArgs
{
  public GenericAsyncWrapperCompletedEventArgs(object result, Exception error, string methodName, object userState, object[] inValues)
  {
    this.Result = result;
    this.Error = error;
    this.MethodName = methodName;
    this.UserState = userState;
    this.InValues = inValues;
  }
  public object Result { get; private set; }
  public Exception Error { get; private set; }
  public string MethodName { get; private set; }
  public object UserState { get; private set; }
  public object[] InValues { get; private set; }
}

You can download the code here GenericUtils.zip (7.33 KB). If you find it useful, I'd love to hear from you. If you think this was a total waste of time, turn the TV back on.

posted on Thursday, May 13, 2010 2:39:41 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Tuesday, April 20, 2010

Over the weekend, I began to think about how to better protect proprietary algorithms and other sensitive code in a Silverlight application, keeping the assembly away from prying, snooping eyes. I decided the best way would be to keep the code in memory and never have it committed to the hard drive. A little research and a little coding and badda bing (er, badda google?).

The solution turns out to be rather simple. You need four projects: the Silverlight app, the web app, the contract (interface) and the implementation Silverlight class libraries. The Silverlight app references the contract library which pulls it into the XAP. The implementation library references the contract library to implement the interface, of course. And the web app does its thing, supplying the XAP file to the browser and most importantly supplying the protected bits via a stream that presumably is protected by SSL, authentication and authorization mechanisms, items I've conveniently left out of this post and the sample code for brevity.

Start with the AppManifest.xaml (in Dinorythm.xap)
Note that the manifest contains only the Silverlight app and the contract class library along with the other assemblies required for the Silverlight Navigation Application (find what you need at Scott Guthrie's informative Silverlight 4 Released blog post).

<Deployment 
    xmlns="http://schemas.microsoft.com/client/2007/deployment" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    EntryPointAssembly="Dinorythm" 
    EntryPointType="Dinorythm.App" 
    RuntimeVersion="4.0.50401.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="Dinorythm" Source="Dinorythm.dll" />
    <AssemblyPart x:Name="DinoContracts" Source="DinoContracts.dll" />
    <AssemblyPart x:Name="System.ComponentModel.DataAnnotations" Source="System.ComponentModel.DataAnnotations.dll" />
    <AssemblyPart x:Name="System.ServiceModel.DomainServices.Client" Source="System.ServiceModel.DomainServices.Client.dll" />
    <AssemblyPart x:Name="System.ServiceModel.DomainServices.Client.Web" Source="System.ServiceModel.DomainServices.Client.Web.dll" />
    <AssemblyPart x:Name="System.ServiceModel.Web.Extensions" Source="System.ServiceModel.Web.Extensions.dll" />
    <AssemblyPart x:Name="System.Windows.Controls" Source="System.Windows.Controls.dll" />
    <AssemblyPart x:Name="System.Windows.Controls.Navigation" Source="System.Windows.Controls.Navigation.dll" />
  </Deployment.Parts>
</Deployment>

 

DinoContracts a Silverlight 4 Class Library (in Dinorythm.xap).
To any nosy disassembler looking for the secret sauce code, all they will get is the interface and perhaps a few domain classes if you need them.

namespace DinoContracts
{
  public interface IMySecretCode
  {
    string DoSecretWork(string input);
  }
}

 

SecretAlgorithms a Silverlight 4 Class Library (NOT in Dinorythm.xap)
This library has a project reference to DinoContracts and copies it's output to the Dynorythm.Web/App_Data folder.

namespace SecretAlgorithms
{
  public class MySecretCode : IMySecretCode
  {
    public string DoSecretWork(string input)
    {
      return "results of my secret code";
    }
  }
}

 

Dinorythm.Web an ASP.NET MVC 2 project
Obviously this code is not production ready. You need some security here, but what you see here will get you the result you seek. Securing this action method might be a good topic for another blog post.

namespace Dinorythm.Web.Controllers
{
  [HandleError]
  public class HomeController : Controller
  {
    //...other code removed for brevity

    public FileContentResult Secret()
    {
      string ctype = "application/octet-stream";
      string fileName = "SecretAlgorithms.dll";
      byte[] dll = GetFile(fileName);
      return File(dll, ctype, fileName);
    }

    byte[] GetFile(string fileName)
    {
      string path = HostingEnvironment.MapPath(@"~/App_Data/" + fileName);
      byte[] bytes = System.IO.File.ReadAllBytes(path);
      return bytes;
    }
  }
}

 

Dinorythm a Silverlight 4 Navigation Application
This app has a project reference to DinoContracts but knows nothing about the SecretAlgorithms project. The secret code in this demo won't win any awards but it might help you conceive (and me to remember) of how to get the job done with your real intellectual property.

namespace Dinorythm
{
  public partial class About : Page
  {
    public About()
    {
      InitializeComponent();
    }

    // Executes when the user navigates to this page.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
      WebClient down = new WebClient();
      down.OpenReadCompleted += new OpenReadCompletedEventHandler(down_OpenReadCompleted);
      Uri location = new Uri(System.Windows.Application.Current.Host.Source, @"../Home/Secret");
      down.OpenReadAsync(location);
    }

    void down_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
      AssemblyPart part = new AssemblyPart();
      Assembly asm = part.Load(e.Result);
      IMySecretCode secret = (IMySecretCode)asm.CreateInstance("SecretAlgorithms.MySecretCode");

      if (secret != null)
        this.ContentText.Text = secret.DoSecretWork("help me");
      else
        this.ContentText.Text = "was null";
    }
  }
}

Help credits go to Tim Heuer for some comparison with cached assemblies and to the practical help from a Silverlight Tip of the Day.

A Note About Security: I am not a self-proclaimed security expert. I'm sure there are ways to defeat this approach, but I suspect that doing so would be more trouble than it would be worth. But certainly this would be more efficient than simple or even complex obfuscation. Then again one could obfuscate and then dynamically download and instantiate in memory. That ought to really throw a would be intellectual property thief for a real loop. (Also note, I've never tried obfuscation in a Silverlight class library, so perhaps it's not even possible. Hmm... Another research and blog topic.)

If you find this code useful, I'd love to hear from you. Download Dinorythm.zip (313.34 KB) here.

posted on Tuesday, April 20, 2010 9:17:49 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, March 28, 2010

I've been wanting a simplified WCF plugin architecture for .NET Windows service with easy debug console mode to make my life easier. Building services with Windows Communication Foundation (WCF) is simple and hard. The service and data contract code is simple, like this:

namespace Test2Common	
{
  [ServiceContract]
  public interface IMyOtherService
  {
    [OperationContract, FaultContract(typeof(WcfServiceFault))]
    string GetName(string seed);

    [OperationContract, FaultContract(typeof(WcfServiceFault))]
    Person GetPerson(int id);
  }

  [DataContract]
  public class Person
  {
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Title { get; set; }
  }
}

But that is where simple ends. The hosting and client proxy code and the configuration XML (or code) is not simple. Even when I use tools to generate these artifacts, I find myself having to tweak and fix and delve deeper than time permits. And since I prefer simple, I decided to create a reusable framework for hosting my limited scope services. Here's what I wanted (download PluggableWcfServiceHost.zip (38.05 KB)):

  • Fast net.tcp binding
  • Windows credentials and authentication
  • Encrypted and signed transport (no packet sniffing allowed)
  • Simplified configuration (hide everything I don't want to see)
  • Windows Service host that behaves like a Console app when I'm debugging
  • Dynamic loading of the service (no changes to the host code to add a new service)
  • Generic client so I don't have to write or generate proxy code
  • Client that is truly IDisposable (hide Abort vs Close for me)
  • Long timeout in DEBUG mode so I can really take my time while debugging
  • Inclusion of exception details in DEBUG mode only
  • Base service class with a simple Authorize method to support multiple Windows groups
  • Support for multiple Windows group authorization
  • Identical configuration for server and client
  • Cached resolution of service plugin service and contract types
  • Minimal number of assemblies (projects) in the solution
  • Keep the implementation of the service hidden from the client
  • (Probably some I've forgotten to mention)

Here's the simplified config with two services configured:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="wcfServices" 
          type="WcfServiceCommon.WcfServiceConfigurationSection, WcfServiceCommon" />
  </configSections>
  <appSettings/>
  <connectionStrings/>
  <wcfServices consoleMode="On">
    <services>
      <add key="test1"
          serviceAddressPort="localhost:2981"
          endpointName="Test1EndPoint"
          authorizedGroups="WcfServiceClients,someOtherGoup"
          hostType="Test1Service.ThatOneService, Test1Service"
          contractType="Test1Common.IThatOneService, Test1Common" />
      <add key="test2"
          serviceAddressPort="localhost:2981"
          endpointName="Test2EndPoint"
          authorizedGroups="WcfServiceClients,someOtherGoup"
          hostType="Test2Service.MyOtherService, Test2Service"
          contractType="Test2Common.IMyOtherService, Test2Common" />
    </services>
  </wcfServices>
</configuration>

And here's the implementation of the service (It really is simple):

namespace Test2Service
{
  public class MyOtherService : WcfServiceBase, IMyOtherService
  {
    public string GetName(string seed)
    {
      base.Authorize();
      return "This is my name: " + seed.ToUpper();
    }

    public Person GetPerson(int id)
    {
      base.Authorize();
      return new Person { Name = "Donald Trumpet", Title = "King of the Hill" };
    }
  }
}

Now for the really fun part. The client. Hey, where's the proxy? Hidden away just like it ought to be.

namespace WcfSvcTest
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var client1 = WcfServiceClient<IThatOneService>.Create("test1"))
      {
        Console.WriteLine(client1.Instance.GetName("seed"));
        var add = client1.Instance.GetAddress(8);
        Console.WriteLine("{0}", add.City);
      }

      using (var client2 = WcfServiceClient<IMyOtherService>.Create("test2"))
      {
        try
        {
          Console.WriteLine(client2.Instance.GetName("newseed"));
          var per = client2.Instance.GetPerson(7);
          Console.WriteLine("{0}, {1}", per.Name, per.Title);
        }
        catch (FaultException<WcfServiceFault> fault)
        {
          Console.WriteLine(fault.ToString());
        }
        catch (Exception e) //handles exceptions not in wcf communication
        {
          Console.WriteLine(e.ToString());
        }
      }

      Console.ReadLine();
    }
  }
}

To save space, I only wrapped the use of the client in try catch on the second test service.

Note: You have to remember that the WcfServiceHost requires the "common" and the "service" assemblies of your dynamically loaded services in it's bin folder. The client (see WcfSvcTest project in the solution) will also need a copy of the "common" assemblies in it's bin folder. You'll find I'm doing that for the test using post-build commands (copy $(TargetPath) $(SolutionDir)WcfServiceHost\bin\debug\). And of course, both need to have identical config sections as shown in the code.

I hope you find this WCF plugin architecture and the accompanying code useful. I will certainly be using it. If you do use it, please let me know how it goes.

Download PluggableWcfServiceHost.zip (38.05 KB)

posted on Sunday, March 28, 2010 8:58:40 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, March 14, 2010

A few years ago I worked on a project called Atrax which among other things included an implementation of the work of Yutaka Matsuo of the National Institute of Advanced Industrial Science and Technology in Tokyo and by Mitsuru Ishizuka of the University of Tokyo.

I decided to revisit the keyword extraction algorithm and update it a bit and isolate it from the overall Atrax code to make it easier for anyone to use. You can download the code Keyword.zip (17.87 KB).

Here are the top ten keywords the code returns from the Gettysburg Address and from Scot Gu’s most recent blog post:

gettys
   dedicated
   nation
   great
   gave
   dead
   rather
   people
   devotion
   people people
   lives

gu
   ASP.NET MVC
   VS 2010 and Visual Web Developer
   ASP.NET 3.5
   ASP.NET
   MVC
   Web Developer 2008 Express
   VS 2010
   VS 2008
   release
   Improved Visual Studio

Let me know if you end up using the implementation of the algorithm and if you happen to make improvements to it.

posted on Sunday, March 14, 2010 4:56:37 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, March 11, 2010

I love ASP.NET MVC 2 validations for client and server via annotations. Steve Sanderson's xVal is great too, but in this post I want to focus on a custom validation for MVC 2 which is frustratingly missing from the out-of-the-box validations. There is a very nice StringLengthAttribute which allows you to specify a maximum length but does not provide for a minimum length.

At first I attacked this deficiency with a regex like this:

[RegularExpression("[\\S]{6,}", ErrorMessage = "Must be at least 6 characters.")]
public string Password { get; set; }

This approach just seems clunky. Happily, while reading Scott Allen's piece on MVC 2 validation in MSDN magazine, I came across a critical reference to one of Phil Haack's blog posts which I must have overlooked.

Thanks go to Phil's easy to follow instructions on writing a custom validator for MVC 2 that will work on both client and server sides.

So here's my custom MinStringLengthAttribute and supporting code which let's me do something easier and cleaner like this:

[StringLength(128, ErrorMessage = "Must be under 128 characters.")]
[MinStringLength(3, ErrorMessage = "Must be at least 3 characters.")]
public string PasswordAnswer { get; set; }

If you really wanted to get creative, you could produce a combination of the two, but I'll leave that for another day.

Here's the code for the attribute and the required validator:

public class MinStringLengthAttribute : ValidationAttribute
{
  public int MinLength { get; set; }

  public MinStringLengthAttribute(int minLength)
  {
    MinLength = minLength;
  }

  public override bool IsValid(object value)
  {
    if (null == value) return true;     //not a required validator
    var len = value.ToString().Length;
    if (len < MinLength)
      return false;
    else
      return true;
  }
}

public class MinStringLengthValidator : DataAnnotationsModelValidator<MinStringLengthAttribute>
{
  int minLength;
  string message;

  public MinStringLengthValidator(ModelMetadata metadata, ControllerContext context, MinStringLengthAttribute attribute)
    : base(metadata, context, attribute)
  {
    minLength = attribute.MinLength;
    message = attribute.ErrorMessage;
  }

  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
  {
    var rule = new ModelClientValidationRule
    {
      ErrorMessage = message,
      ValidationType = "minlen"
    };
    rule.ValidationParameters.Add("min", minLength);
    return new[] { rule };
  }
}

Here's the code in the Global.asax.cs that registers the validator:

protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);
  DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MinStringLengthAttribute), typeof(MinStringLengthValidator));
}

Here's the javascript to hook up the client side:

Sys.Mvc.ValidatorRegistry.validators["minlen"] = function(rule) {
  //initialization
  var minLen = rule.ValidationParameters["min"];

  //return validator function
  return function(value, context) {
    if (value.length < minLen) 
      return rule.ErrorMessage;
    else
      return true;  /* success */
  };
};

Now, in your view, add <% Html.EnableClientValidation(); %> and that's all there is to it.

posted on Thursday, March 11, 2010 1:21:29 PM (Mountain Standard Time, UTC-07:00)  #    Comments [2]
# Wednesday, January 06, 2010

This log helper class seems to get used over and over again in projects I've worked on. Generally I use it as a fallback, calling it from an exception block in a application logging code. Let me know if you find it helpful.

public static class LogHelper
{
  public static bool WriteEventLogEntry(string source, EventLogEntryType entryType, int eventId, string message)
  {
    bool passFail = true;
    try
    {
      if (!EventLog.SourceExists(source))
      {
        EventLog.CreateEventSource(source, "Application");
      }
      EventLog elog = new System.Diagnostics.EventLog();
      elog.Source = source;
      elog.WriteEntry(message, entryType, eventId);
    }
    catch
    {
      passFail = false; //this method is usually called as a last resort, so there can be no real exception handling
    }
    return passFail;
  }
}
posted on Wednesday, January 06, 2010 3:01:07 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Sunday, November 29, 2009

It turns out that using table storage in Windows Azure 1.0 is quite easily done with a minimal amount of configuration. In the new Azure cloud service Visual Studio project template, configuration is significantly simpler than what I ended up with in a previous blog post where I was able to get the new WCF RIA Services working with the new Windows Azure 1.0 November 2009 release and the AspProvider code from the updated demo.

And while the project runs as expected on my own machine, I can’t seem to get it to run in the cloud for some reason. I have not solved that problem. Since I can’t seem to get much of a real reason for the failure via the Azure control panel, I’ve decided to start at the beginning, taking each step to the cloud rather than building entirely on the local simulation environment before taking it to the cloud for test.

I started with a clean solution. No changes except to the web role’s Default.aspx page with some static text. Publish to the cloud and twenty to thirty minutes later (too long in my opinion) the page will come up, deployment is complete and the equivalent of a “hello world” app is running in the Azure cloud.

The next step I want to experiment with is the simplest use possible of Azure table storage. In the previous project, there was a lot of configuration. In this new project, there was very little. I wondered how much of the configuration from the previous project, largely an import from the updated AspProviders demo project, was a partially unnecessary legacy of CTP bits. It turns out, nearly all of it.

Here’s the only configuration you need for accessing Azure storage:

<?xml version="1.0"?>
<ServiceConfiguration serviceName="MyFilesCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="MyFiles">
    <Instances count="1" />
    <ConfigurationSettings>
      <!-- Add your storage account information and uncomment this to target Windows Azure storage. 
      <Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" />
      <Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" />
      -->

      <!-- local settings -->
      <Setting name="DataConnectionString" value="UseDevelopmentStorage=true" />
      <Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

The thumbnails sample does provide one important piece of code that does not come with the standard Visual Studio template. It goes in the WebRole.cs file and makes the use of the CloudStorageAccount class’s static FromConfigurationSetting method which returns the needed CloudStorageAccount instance. To use that method, the SetConfigurationSettingPublisher method must have already been called. Hence this code placed in the WebRole class like this:

public class WebRole : RoleEntryPoint
{
  public override bool OnStart()
  {
    DiagnosticMonitor.Start("DiagnosticsConnectionString");

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    #region Setup CloudStorageAccount Configuration Setting Publisher

    // This code sets up a handler to update CloudStorageAccount instances when their corresponding
    // configuration settings change in the service configuration file.
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
    {
      // Provide the configSetter with the initial value
      configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

      RoleEnvironment.Changed += (sender, arg) =>
      {
        if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
           .Any((change) => (change.ConfigurationSettingName == configName)))
        {
          // The corresponding configuration setting has changed, propagate the value
          if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
          {
            // In this case, the change to the storage account credentials in the
            // service configuration is significant enough that the role needs to be
            // recycled in order to use the latest settings. (for example, the 
            // endpoint has changed)
            RoleEnvironment.RequestRecycle();
          }
        }
      };
    });
    #endregion

    return base.OnStart();
  }

  private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
  {
    // If a configuration setting is changing
    if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
    {
      // Set e.Cancel to true to restart this role instance
      e.Cancel = true;
    }
  }
}

Once you have the set the configuration setting publisher, you can use the FromConfigurationSetting method in the creation of your CloudTableClient and then check for the existence of a table, creating it if it does not already exist in your repository code. Here’s a minimal example that I used and published successfully to my Azure account.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.Data.Services.Client;

namespace MyDemo
{
  public class AdventureRow : TableServiceEntity
  {
    public string IpAddress { get; set; }
    public DateTime When { get; set; }
  }

  public class AdventureRepository
  {
    private const string _tableName = "Adventures";
    private CloudStorageAccount _account;
    private CloudTableClient _client;

    public AdventureRepository()
    {
      _account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
      _client = new CloudTableClient(_account.TableEndpoint.ToString(), _account.Credentials);
      _client.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
      _client.CreateTableIfNotExist(_tableName);
    }

    public AdventureRow InsertAdventure(AdventureRow row)
    {
      row.PartitionKey = "AdventurePartitionKey";
      row.RowKey = Guid.NewGuid().ToString();
      var svc = _client.GetDataServiceContext();
      svc.AddObject(_tableName, row);
      svc.SaveChanges();
      return row;
    }

    public List<AdventureRow> GetAdventureList()
    {
      var svc = _client.GetDataServiceContext();
      DataServiceQuery<AdventureRow> queryService = svc.CreateQuery<AdventureRow>(_tableName);
      var query = (from adv in queryService select adv).AsTableServiceQuery();
      IEnumerable<AdventureRow> rows = query.Execute();
      List<AdventureRow> list = new List<AdventureRow>(rows);
      return list;
    }
  }
}

Just as the StorageClient has moved from “sample” to first class library in the Azure SDK, I suspect that the AspProviders sample may already be on that same path to glory. In it’s current form, it represents something new and something old, the old having not been entirely cleaned up, lacking the elegance it deserves and will likely get either by Microsoft or some other enterprising Azure dev team.

As for me, I will continue trying to learn, one step at a time, why the Adventure code I blogged about previously will run locally but not on the cloud as expected. Who knows, it could be as simple as a single configuration gotcha, but figuring it out one step at a time will be a great learning opportunity and as I get the time, I’ll share what I learn here.

posted on Sunday, November 29, 2009 7:13:26 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Monday, November 23, 2009

A month ago I posted the results of some experimentation with the preview bits of what was then called .NET RIA Services, Silverlight 3 and the Windows Azure with AspProvider sample code from the Azure July 2009 CTP. That was then and much has changed.

Windows Azure 1.0 and what is now called WCF RIA Services Beta have since been released. Lot’s of great changes make using these together with the new AspProvider sample in the “Additional C# Samples” download that some friendly readers shared with me. With Visual Studio 2008 SP1 and SQL Server 2008 (Express if you want) and these you’re set up to play.

WARNING: They were not lying about the WCF part when they renamed it. The default Domain Service channel is binary and they’re using Windows Activation Service (WAS). So make sure you’re Windows Features look something like this or you’re in for several hours of maddening error chasing.

advnew3

After some review of the previous effort using the July 2009 CTP and RIA preview bits, I decided starting over was the best course of action. Here’s the steps to nirvana:

  1. Create a new Silverlight Business Application called Adventure which produces Adventure.Web application as well.
  2. Add new CloudService project with WebRole called AdventureCloudService and WebRole1.
  3. Copy WebRole.cs to Adventure.Web and rename namespace.
  4. Add 3 azure refs to Adventure.Web.
  5. In the cloud service project file, replace WebRole1 with Adventure.Web and project guid with that from Adventure.Web. (There is probably a better way to do this.)
  6. The node under Roles in the cloud service project shows an error. Right click it and choose “associate” and pick Adventure.Web.
  7. Copy system.diagnostics section from WebRole1 web.config to that of Adventure.Web.
  8. Remove WebRole1 from solution and set service project as startup.
  9. Copy and new AspProviders project and sections from demo web.config into Adventure.Web, changing DefaultProviderApplicationName and applicationName="Adventure".
  10. Do the same previous steps to create/copy UserProfile class and IUserProfile with FriendlyName property too. Added to the Models directory this time. NOTE: Be sure to get the magic strings right in the UserProfile class or you will get unexpected results.
  11. Add Global.asax and AppInitializer class to it from previous project without the CreateTableFromModel calls which are no longer needed as I understand it.
  12. Drop in the code to create the admin user if it does not already exist.
  13. When I go to modify the LoginStatus.xaml which was previously LoginControl.xaml, but find the needed modification is already there. Skip this step.
  14. Just hit F5 and error is thrown.

After some lengthy research, I discovered a bug in the AspProvider's TableStorageRoleProvider.cs. When the RoleExists method is called and no roles have yet been created an exception is thrown.

AspProvider Fix Found
Replace e.InnerException in line 484 in TableStorageRoleProvider.cs with e.InnerException.InnerException. The first inner exception is another InvalidOperationException. The second inner exception is the DataServiceClientException we're looking for.

Login with admin/admin and we see Administrator displayed in the newly renamed LoginStatus area.

And we’re back to par. Download the code here (566KB).

posted on Monday, November 23, 2009 8:48:05 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Sunday, November 15, 2009

The 1.0 release of Windows Azure SDK is now available. Download and read about what’s new here. Sadly, the AspProviders sample project was not included. I spent a few hours trying to bandage it up, but it was a hopeless cause. If a new AspProviders sample is not soon forthcoming, it will be easier to write one from scratch using the new SDK and the new project templates.

Update (11/22/09) - AspProviders in Additional C# Examples: One comment and an additional private email from readers have pointed out Azure Code Samples on MSDN where you can download the "Additional C# Samples" which contatin the new AspProviders. I'll be checking out this and other samples with the new Azure SDK. Thanks to both Jason and Gerold for the links.

When I tried to run my old project, after modifying some references to match those of a fresh project created with the new Visual Studio templates, the first thing that popped was a new local storage database script dialog result:

az-nov09-01 

I’ve not explored them in detail but there are several new tables, some stored procedures and a few user defined functions in the new dev storage database.

I clicked okay and before I got my next error, I noticed the new baloon dialog name for the dev fabric, Windows Azure Simulation Environment:

az-nov09-02

I also compared the csCFG and and csDEF config files for the Azure cloud service project. The XML namespace is the same and as near as I can tell there are no changes there.

The next thing I noticed was a new class in the web role of the new project template. Seems we now have a “Windows Service”-like OnStart and RoleEnironmentChanging set of startup and status change event handlers. This will be highly useful for web role applications that may have resource cleanup needs.

public class WebRole : RoleEntryPoint
{
	public override bool OnStart()
	{
		DiagnosticMonitor.Start("DiagnosticsConnectionString");

		// For information on handling configuration changes
		// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
		RoleEnvironment.Changing += RoleEnvironmentChanging;

		return base.OnStart();
	}

	private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
	{
		// If a configuration setting is changing
		if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
		{
			// Set e.Cancel to true to restart this role instance
			e.Cancel = true;
		}
	}
}

Another bit of great news is that the StorageClient goes from “sample” project to part of the release libraries. There were ample changes there which appear to have broken the AspProviders sample project severely. While that explains the missing AspProviders project disappointment, I do hope that it means the changes in the StorageClient namespace will make using Azure storage easier.

Much more to learn and blog about with the new release, but it looks as though I’ll need to start over on my “Aventure” sample. I’m glad that I don’t have loads of code to refactor to the new release. It makes starting over less painful. For those who have written large projects relying on the beta, all I can say is, “beta = subject to change.”

posted on Sunday, November 15, 2009 3:42:06 PM (Mountain Standard Time, UTC-07:00)  #    Comments [1]
# Wednesday, October 21, 2009

A very long time ago, I wrote a little helper class clone of SqlHelper for Oracle which I called OraHelper. I haven’t looked at or touched the code in years, but I regularly get email asking where it’s gone to. It appears that the www.asp.net community gallery still refers to it but their link is broken. Rather than attempt to get them to fix the link, I’m posting it here.

Download OraHelper (12KB) here.

I don’t know how well this code works anymore. I’ve no Oracle database against which I can test it. I recall that one inquirer indicated that he wanted the code because he was limited to the .NET Framework 1.1. I found that rather sad to think about given how comfortable I’ve become with generics and lambdas of late.

For those of you who are doing .NET database access to Oracle, you may be helped even more by looking at Oracle’s .NET Developer Center. I can’t speak for the state of their current support. Perhaps there are readers that could post more informed comments on the subject here.

posted on Wednesday, October 21, 2009 9:05:51 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, October 18, 2009

After spending last weekend working on and blogging about Silverlight 3 and .NET RIA services, I decided I’d look to build out a membership, profile and role provider that would use Windows Azure storage. Much to my delight, I stumbled into the AspProvidersDemo code that comes with the Windows Azure SDK or perhaps the Visual Studio 2008 Tools for Azure.

No matter, you need them both to follow along with this post. If you have not already, you should look at my previous post and make sure you prepare your environment for Silverlight 3 in addition to signing up for your Azure account and installed the tools mentioned

You can download the entire solution file (434KB) and skip to the momentous striking of your F5 key if you like. Or you can follow along here and blunder through this adventure as I did. (I recommend cheating now and downloading the code.)

Here’s the step-by-step details. I’ll try to spare the you excruciating minutiae and keep it as exciting as possible.    

I started by creating a standard Cloud Service application called MyFilesCloudService with a web role called WebFilesRole. I then added a Silverlight Business Application called Adventure. Unfortunately, this template does not allow you to select the web role application to host the Silverlight app.

I removed the Adventure.Web application and in the web role’s project properties added the Silverlight app in the Silverlight Application tab. (ERROR: This turned out to be a problem which I solved by added a throwaway standard Silverlight app to the solution, selecting the WebFilesRole app as the host. I am still not certain why, but I’ll spare you the grisly details of experimentation with the web.config. If you haven’t already, this is a good place to stop and download the code.)

I copied the AspProviders and StorageClient projects from the Azure SDK demos folder into the solution directory and added them to the solution. I also copied the relevant sections from the web.config for the web role and the ServiceConfiguration.cscfg and ServiceDefinition.csdef files in cloud service project.

I hit F5 for kicks and get (via Event Viewer) an event 3007, “A compilation error has occurred.” Upon further digging I realize that the profile provider is configured to inherit it’s ProfileBase from UserProfile. The class is in the demo’s web role. Steal that too. Here it is as added to the web role in my project:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;

namespace WebFilesRole
{
   public class UserProfile : ProfileBase
   {
      public static UserProfile GetUserProfile(string username)
      {
         return Create(username) as UserProfile;
      }

      public static UserProfile GetUserProfile()
      {
         return Create(Membership.GetUser().UserName) as UserProfile;
      }


      [SettingsAllowAnonymous(false)]
      public string Country
      {
         get { return base["Country"] as string; }
         set { base["Country"] = value; }
      }

      [SettingsAllowAnonymous(false)]
      public string Gender
      {
         get { return base["Gender"] as string; }
         set { base["Gender"] = value; }
      }

      [SettingsAllowAnonymous(false)]
      public int Age
      {
         get { return (int)(base["Age"]); }
         set { base["Age"] = value; }
      }
   }
}

I boldly hit F5 again and get this gem:

Configuration Error
Initialization of data service structures (tables and/or blobs) failed!
The most probable reason for this is that the storage endpoints are not configured correctly.
Line 133: type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"

A little searching and googling and I learn that I need to right-click on my cloud service application and select “Create Test Storage Tables.” I do it and bada-bing, I get this nice dialog and Output window text:

advent3

DevTableGen : Generating database 'MyFilesCloudService'
DevTableGen : Generating table 'Roles' for type 'Microsoft.Samples.ServiceHosting.AspProviders.RoleRow'
DevTableGen : Generating table 'Sessions' for type 'Microsoft.Samples.ServiceHosting.AspProviders.SessionRow'
DevTableGen : Generating table 'Membership' for type 'Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow'
===== Create test storage tables succeeded =====

Aha! I go examine my local SQL Server instance and sure enough, there’s a new DB called MyFilesCloudService with some interesting tables. You can take at look at your own when you’ve read far enough along here to learn to click that “Create Test Storage Tables” magic context menu item too.

So I experiment a little and create a couple of test tables like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Samples.ServiceHosting.StorageClient;

namespace WebFilesRole
{
   public class MyTestDataServiceContext : TableStorageDataServiceContext
   {
      public IQueryable Roles
      {
         get
         {
            return this.CreateQuery("MyTest");
         }
      }
   }

   public class MyTestRow : TableStorageEntity
   {
      public string MyTestName { get; set; }
   }
}

Note the nice and easy TableStorageEntity and it’s TableStorageDataServiceContext. Just don’t make the mistake I did and forget to name the property something unique. I tried Roles (yeah, a copy/past error) and got a nasty message like this:

No table generated for property 'Roles' of class 'WebFilesRole.MyTestDataServiceContext' because the name matches (or differs only in case) from the name of a previously generated table

I add an AppInitializer class to make sure these tables get created in the cloud when run there. First, I add a bit of code to the Application_BeginRequest method in the Global.asax.cs (the one I just added but didn’t tell you about).

protected void Application_BeginRequest(object sender, EventArgs e)	
{	
   HttpApplication app = sender as HttpApplication;   
   if (app != null)   
   {   
      HttpContext context = app.Context;   
      AppInitializer.Initialize(context);   
   }   
}

I then add the initializer class at the bottom of that same code file.

internal static class AppInitializer
{
   static object lob = new object();
   static bool alreadyInitialized = false;
   public static void Initialize(HttpContext context)
   {
      if (alreadyInitialized) return;
      lock (lob)
      {
         if (alreadyInitialized) return;
         InitializeAppStartFirstRequest(context);
         alreadyInitialized = true;
      }
   }

   private static void InitializeAppStartFirstRequest(HttpContext context)
   {
      StorageAccountInfo account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration();
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow));
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.RoleRow));
      TableStorage.CreateTablesFromModel(typeof(Microsoft.Samples.ServiceHosting.AspProviders.SessionRow));
      TableStorage.CreateTablesFromModel(typeof(Room));
   }
}

I then add some test code into the Default.aspx.cs which I won’t bore you with here. You can look at it in the downloaded solution. I got a weird error with the session test, but after a reboot, it went away, so I’ll chalk that up to the development fabric being a CTP.

Now I want to get back to working Silverlight into the picture. I need to create an admin user for my test login, so I add some code to the AppInitializer class in the Global.asax.cs file like this:

MembershipUser user = Membership.GetUser("admin");
if (null == user)
{
   //create admin user
   MembershipCreateStatus status = MembershipCreateStatus.Success;
   Membership.CreateUser("admin", "admin", "admin@admin.com", "admin-admin", "admin", 
      true, Guid.NewGuid(), out status);

   //add admin user to admin role
   if (status == MembershipCreateStatus.Success)
   {
      if (!Roles.RoleExists("admin"))
      {
         Roles.CreateRole("admin");
      }
      Roles.AddUserToRole("admin", "admin");
   }

   //add profile data to admin user
   UserProfile profile = UserProfile.Create("admin") as UserProfile;
   profile.Age = 40;    //not my true age
   profile.Country = "US";
   profile.Gender = "M";
   profile.Save();
}

I look at the UserProfile class and know that the DomainService’s User class needs the same properties in order for the Silverlight RiaContext to know about them. I discovered in the metadata code the following comments in the UpdateUser method of the  System.Web.Ria.ApplicationServices.AuthenticationBase<T> base class used for the AuthenticationService domain service class:

// Remarks:
//     By default, the user is persisted to the System.Web.Profile.ProfileBase.
//     In writing the user to the profile, the provider copies each property in
//     T into the corresponding value in the profile. This behavior can be tailored
//     by marking specified properties with the System.Web.Ria.ApplicationServices.ProfileUsageAttribute.

I know now that I want the UserProfile and the User classes to have the same profile properties, so I add an interface above the UserProfile class like this:

public interface IUserProfile	
{	
   string Country { get; set; }   
   string Gender { get; set; }   
   int Age { get; set; }   
}

And then add the same properties found in UserProfile to the User class in the AuthenticationService.cs file as follows:

public class User : UserBase, IUserProfile   
{   
   // NOTE: Profile properties can be added for use in Silverlight application.   
   // To enable profiles, edit the appropriate section of web.config file.   
   
   // public string MyProfileProperty { get; set; }   
   
   public string Country { get; set; }   
   
   public string Gender { get; set; }   
   
   public int Age { get; set; }   
}

I try to run it and get the following error on the Silverlight app when I try to login using admin/admin: "The specified resource was not found." A little digging reveals that I need two things: first, some additions to the web.config file that I was missing, and second, the ServiceDefinition.csdef had to have it’s enableNativeCodeExecution set to true. Here’s the pieces:

<!-- handlers and httpHandlers sections require the following additions -->
<handlers>
   <add name="DataService" verb="GET,POST" path="DataService.axd" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>		
</handlers>

<httpHandlers>
   <add path="DataService.axd" verb="GET,POST" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>		
</httpHandlers>

<!-- the ServiceDefinition.csdef gets the enableNativeCodeExecution set to true -->
<WebRole name="WebFilesRole" enableNativeCodeExecution="true">

Once those changes were made, I was able to run the Silverlight application, login using admin/admin and logout. Now one more item on the agenda for this post. I want to see the profile information we added in the AppInitializer code. So I modify the LoginControl.xaml and LoginControl.xaml.cs as follows.

<StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}">
   <TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/>
   <TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/>
      <TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/>
      <TextBlock Text="" x:Name="ProfileText" Style="{StaticResource WelcomeTextStyle}"/>
      <TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/>
   <Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" />
</StackPanel>

With the code behind changed like this:

private void UpdateLoginState()	
{	
   if (RiaContext.Current.User.AuthenticationType == "Windows")   
   {   
      VisualStateManager.GoToState(this, "windowsAuth", true);   
   }   
   else //User.AuthenticationType == "Forms"   
   {   
      VisualStateManager.GoToState(this,    
         RiaContext.Current.User.IsAuthenticated ? "loggedIn" : "loggedOut", true);   
   
      if (RiaContext.Current.User.IsAuthenticated)   
      {   
         this.ProfileText.Text = string.Format("age:{0}, country:{1}, gender:{2}",    
            RiaContext.Current.User.Age,    
            RiaContext.Current.User.Country,    
            RiaContext.Current.User.Gender);   
      }   
   }
}

Now when I login, I get to look at something like this:

advent8

Cool. In Part 2, I’ll modify the UserProfile to capture the data I want to keep in my Adventure application and complete the user registration changes to the Silverlight application as well as clean up and prepare the app for some real application development in follow-on posts.

If you have any questions or ways to do this better, I’d love to hear from you.

posted on Sunday, October 18, 2009 7:58:29 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, October 12, 2009

I finally carved out some time to experiment with Silverlight 3 and .NET RIA Services over the weekend. Specifically I wanted to experiment with Forms security and how one might secure a Silverlight "page" as well as the services on the server side along with a custom membership, role and profile providers. Here's the result.

Tools
Before you follow along on your own machine, be sure that you have these:

1. Visual Studio 2008 Pro (Visual Studio 2008 Professional Edition (90-day Trial))

2. Visual Studio 2008 SP1 (Microsoft Visual Studio 2008 Service Pack 1 (Installer))

3. Silverlight SDK (Microsoft® Silverlight™ 3 Tools for Visual Studio 2008 SP1)

4. RIA Services July 2009 Preview (Microsoft .NET RIA Services July 2009 Preview)

5. Download code for this post (download DemoAgRia.zip 427KB).

Once you have the tools installed, you can start a new Visual Studio project from the Silverlight projects types called Silverlight Business Application. Name yours whatever you like. I've chosen DemoAgRia.

s1

The project template creates a Silverlight and ASP.NET Web Application project and populates them with a number of helpful artifacts to get us started. There are two DomainService classes, one for authentication and one for user registration. These services use the standard ASP.NET Membership, Role and Profile provider model.

s2

You also get several "views" or Page and ChildWindow XAML controls with code-behind. These files are a familiar construct to any classic ASP.NET developer. Of course XAML is a whole new ballgame compared to the hodge podge of HTML. But rather than focus on these page and child window objects, I will focus this post on the security aspects of the app.

While the project template sets authentication to "Forms" based authentication there are no membership, role, or profile providers configured in the web.config. Since I'm going to create some custom providers in order to just experiment with the mechanics of security within the Silverlight and the web app, I'll just spin up some stub providers. Here's the web.config sections (including the "Forms" authentication node) for them:

<authentication mode="Forms"/>

<roleManager enabled="true" defaultProvider="AgRoleProvider">
  <providers>
    <clear />
    <add name="AgRoleProvider" type="DemoAgRia.Web.AgRoleProvider" />
  </providers>
</roleManager>
<membership defaultProvider="AgMembershipProvider">
  <providers>
    <clear />
    <add name="AgMembershipProvider" type="DemoAgRia.Web.AgMembershipProvider" />
  </providers>
</membership>
<profile enabled="true" defaultProvider="AgProfileProvider">
  <providers>
    <clear />
    <add name="AgProfileProvider" type="DemoAgRia.Web.AgProfileProvider" />
  </providers>
  <properties>
    <clear />
    <add name="PhoneNumber" />
    <add name="FullName" />
  </properties>
</profile>

Now I stub out the provider classes in the Providers folder of the web application. I won't post the code here because the implementation provides dumb data or place holders. Of course, a real set of providers, whether you use the AspSqlMembership provider or role your own, will do real authentication and provide real role and profile access. The stub membership class will authenticate any username and password to allow us to just play with the happy path for now.

Note the custom properties I've added to the profile provider above. These require some custom code in two places. First, in the profile provider class and then in the User class found in the AuthenticationService.cs file. Here's the code for both:

in AgProfileProvider.cs:

public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, 
  SettingsPropertyCollection collection)
{
  string userName = context["UserName"].ToString(); //use this to look up real values for user

  SettingsPropertyValueCollection s = new SettingsPropertyValueCollection();
  foreach (SettingsProperty p in collection)
  {
    if (p.Name == "PhoneNumber") s.Add(new SettingsPropertyValue(p) { PropertyValue = "508.555.1212" });
    if (p.Name == "FullName") s.Add(new SettingsPropertyValue(p) { PropertyValue = "Tyler Jensen" });
    //NOTE: replace with real lookups
  }
  return s;
}
in AuthenticationService.cs:

public class User : UserBase
{
  // NOTE: Profile properties can be added for use in Silverlight application.
  // To enable profiles, edit the appropriate section of web.config file.

  // public string MyProfileProperty { get; set; }
  public string FullName { get; set; }
  public string PhoneNumber { get; set; }
}

Now to use these new profile provider properties, let's modify some XAML in the LoginControl.xaml file so that rather than seeing the username of the logged in user, we'll see the FullName and the PhoneNumber.

Here's the existing XAML which we will modify:

<StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}">
  <TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/>
  <TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/>
  <TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/>
  <Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" />  
</StackPanel>

We now modify this XAML snippet to this:

 
<StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}">
  <TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/>
  <TextBlock Text="{Binding Path=User.FullName}" Style="{StaticResource WelcomeTextStyle}"/>
  <TextBlock Text="  |  phone: " Style="{StaticResource SpacerStyle}"/>
  <TextBlock Text="{Binding Path=User.PhoneNumber}" Style="{StaticResource WelcomeTextStyle}"/>
  <TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/>
  <Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" />
</StackPanel>

Now lets add a DomainService for fecthing some data. Right click on the web application's Services folder and select Add | New Item.

s3

Of course, we don't have a data or object context class, so we don't have any to choose from in the dialog.

s4

Leave "Enable client access" checked. We want a proxy class to automatically be generated from our service class on the server side. Just click OK and let's create our own custom DomainService.

Now you'll see something like this:

 
namespace DemoAgRia.Web.Services
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.ComponentModel.DataAnnotations;
  using System.Linq;
  using System.Web.Ria;
  using System.Web.Ria.Data;
  using System.Web.DomainServices;


  // TODO: Create methods containing your application logic.
  [EnableClientAccess()]
  public class DemoDataService : DomainService
  {
  }
}

I'll put it into the root of the namespace by lopping off the ".Services" in the namespace declaration. This is just a convenience to me. You can do with it what you like.

Now let's add a couple of simplistic methods. Be sure to decorate them with the ServiceOperation attribute or the build process will not autogenerate the DemoDataContext class and proxy class in the Silverlight client app.

 
[EnableClientAccess()]
public class DemoDataService : DomainService
{
  [ServiceOperation]
  public string GetApplicationName()
  {
    return "Demo Ag Ria";
  }

  [ServiceOperation]
  public string GetApplicationAddress()
  {
    return "http://www.demoagria.com";
  }
}

To use the DemoDataService on the client, let's try the following code in the Home.xaml.cs file. Note the two additional using statements and take special note that all calls to the server are asynchronous:

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.IO;
using DemoAgRia.Web;
using System.Windows.Ria.Data;

namespace DemoAgRia
{
  public partial class Home : Page
  {
    public Home()
    {
      InitializeComponent();
    }

    // Executes when the user navigates to this page.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
      DemoDataContext ddc = new DemoDataContext();
      InvokeOperation<string> invAddress = ddc.GetApplicationAddress();
      invAddress.Completed += new EventHandler(invAddress_Completed);
      
      InvokeOperation<string> invAppName = ddc.GetApplicationName();
      invAppName.Completed += new EventHandler(invAppName_Completed);
    }

    void invAppName_Completed(object sender, EventArgs e)
    {
      InvokeOperation<string> op = sender as InvokeOperation<string>;
      string appName = op.Value;
      this.ContentText.Text += string.Format("{0}app name: {1}", Environment.NewLine, appName);
    }

    void invAddress_Completed(object sender, EventArgs e)
    {
      InvokeOperation<string> op = sender as InvokeOperation<string>;
      string address = op.Value;
      this.ContentText.Text += string.Format("{0}address: {1}", Environment.NewLine, address);
    }

  }
}

If you F5 and run a debug test, you'll note that the text in the Home page gets modified as expected.

s5

Now let's add a RequiresAuthentication to the GetApplicationName method:

[ServiceOperation, RequiresAuthentication]
public string GetApplicationName()
{
  return "Demo Ag Ria";
}

Run the app again and you will notice that the GetApplicationName's InvokeOperation<string> object's Value property is null. Now login and click the About page link and then go back to the Home page link. Note that the text has maintained it's state. We're not clearing it, but this time we've added text which includes the app name.

s6

Now try modifying the GetApplicationAddress method like this:

[ServiceOperation, RequiresRoles("Supervisor")]
public string GetApplicationAddress()
{
  return "http://www.demoagria.com";
}

Since the stubbed role provider gives your logged in user the Admin and Analyst role, you can run this and see that you are getting a null value for the operation. Now change the role to "Admin" and try the same thing. This time when you login and come back to the Home page you'll see what we'd expect.

Getting this far was almost enough fun, but then I wondered how I would prevent a user from navigating to a specific Silverlight page if they were not authenticated. There are probably better ways, but here's the solution I arrived at after a little fiddling.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace DemoAgRia
{
  public class PageSecurity
  {
    private Page page;
    private string url;

    public PageSecurity(Page page)
    {
      this.page = page;
    }

    public void Authenticate()
    {
      Authenticate(null);
    }

    public void Authenticate(string url)
    {
      this.url = url;
      if (!RiaContext.Current.User.IsAuthenticated)
      {
        ErrorWindow ew = new ErrorWindow("You must be logged in to view this page.", 
          "Using this page is not allowed unless you are logged in.");
        ew.Title = "Authentication Required";
        ew.IntroductoryText.Text = "Not Authenticated";
        ew.LabelText.Text = "Message";
        ew.Closed += new EventHandler(ew_Closed);
        ew.Show();
      }
    }

    void ew_Closed(object sender, EventArgs e)
    {
      if (null == url)
        this.page.NavigationService.GoBack();
      else
      {
        if (!url.StartsWith("/")) url = "/" + url;
        try
        {
          this.page.NavigationService.Navigate(new Uri(url, UriKind.Relative));
        }
        catch
        {
          this.page.NavigationService.GoBack(); 
        }
      }
    }
  }
}

To test this code, I've added the following code to the About.xaml.cs code to see how it plays.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  PageSecurity ps = new PageSecurity(this);
  ps.Authenticate("Home");
}

Now all you have to do is download the code and you've got a headstart on Silverlight and .NET RIA Services security. Let me know if you find any exciting improvements or alternatives.

posted on Monday, October 12, 2009 3:01:52 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, August 27, 2009

A week ago in a misguided attempt to make things easier, I created something like the following code. My mistake was not in creating the code necessarily, but in applying it to data driven auto generated enums. If you have those, don’t use this.

If you have nice, well behaved static enums wandering around your code and you wish you had a nice way to convert that enum to a usable Dictionary<int, string>, then you’ve come to the right place. So dress up that drab enum with a Description attribute like you see below and call EnumConverter.ConvertToDictionary<DrabEnum>();

And let me know how it works out.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.Reflection;
using System.Collections;

namespace FunStuff
{
  public enum FunEnum
  {
    [Description("Happy Enum")]
    Happy = 1,

    [Description("Sad Enum")]
    Sad = 2
  }


  public static class EnumConverter
  {
    private static object lo = new object(); //used for locking access to the Cache
    private static Dictionary<Type, Dictionary<int, string>> enumStore = 
      new Dictionary<Type, Dictionary<int, string>>();

    /// <summary>
    /// Returns thread safe copy of enum value and name dictionary. Where Description <br />
    /// attribute exists, returns the description value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static Dictionary<int, string> ConvertToDictionary<T>() where T : IComparable
    {
      lock (lo)
      {
        Type t = typeof(T);
        if (!t.IsEnum) throw new ArgumentException("T must be an enum.");
        if (!enumStore.ContainsKey(t)) enumStore.Add(t, Load(t));
        return new Dictionary<int, string>(enumStore[t]);
      }
    }

    private static Dictionary<int, string> Load(Type t)
    {
      Dictionary<int, string> list = new Dictionary<int, string>();
      foreach (MemberInfo m in t.GetMembers())
      {
        if (m.MemberType == MemberTypes.Field && m.Name != "value__")
        {
          string label = m.Name;
          foreach (var att in m.GetCustomAttributes(false))
          {
            DescriptionAttribute da = att as DescriptionAttribute;
            if (null != da)
            {
              if (da.Description.Length > 0)
              {
                label = da.Description;
              }
            }
          }
          int id = Convert.ToInt32(System.Enum.Parse(t, m.Name));
          list.Add(id, label);
        }
      }
      return list;
    }
  }
}
posted on Thursday, August 27, 2009 9:15:44 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, April 27, 2009

A few weeks ago I made a major course correction in our choice of ORM data layer. We had planned to use LLBLGen Pro but several issues with the code that it generates continued to bother me. First, it's support for stored procedures lacked the ability to strongly type the resultset. Second, the data entity classes do not easily support serialization over WCF with the option to dress them up with the appropriate attributes.

So I took a second look at PLINQO with CodeSmith 5.0, something I had considered some time ago but had decided against because I felt it was not sufficiently mature for our team's use. I wanted to see if the dev team had improved the product to the point that I believed it would work for us. I'm very happy I gave it another try. They have done a great job and restored my confidence in LINQ to SQL.

With PLINQO, I found that I could return to standard LINQ to SQL queries and enjoy many of the benefits I had looked forward to using in LLBLGen Pro such as "disconnected" entities. And much to my satisfaction, PLINQO resolves the two major issues I had with the LLBLGen Pro. The improvements over standard LINQ to SQL may seem small at first but when dealing with a very large, enterprise class database, the enhancements that PLINQO offers are critical, including the separation of entities into individual class files.

There are many more features and benefits with PLINQO than I have time to review here. If you're looking for a better LINQ to SQL than LINQ to SQL, look very carefully at PLINQO. I mean, who couldn't fall in love with code like this all buttoned up for you automatically:

private long _userId;

//// <summary>
/// Gets the USER_ID column value.
/// </summary>
[System.Data.Linq.Mapping.Column(Name = "USER_ID", Storage = "_userId", 
     DbType = "bigint NOT NULL IDENTITY", IsPrimaryKey = true, 
	 IsDbGenerated = true, CanBeNull = false)]
[System.Runtime.Serialization.DataMember(Order = 1)]
public long UserId
{
    get { return _userId; }
    set
    {
        if (_userId != value)
        {
            OnUserIdChanging(value);
            SendPropertyChanging("UserId");
            _userId = value;
            SendPropertyChanged("UserId");
            OnUserIdChanged();
        }
    }
}
posted on Monday, April 27, 2009 9:31:03 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [8]
# Sunday, March 15, 2009

In a recent project I wanted to simplify the creation and configuration of a WCF proxy client and enforce programmatic configuration so that the client could only be used in a specific configuration. Here’s the result of that effort. Note that there is a static Create method and the standard ClientBase constructors have been marked as internal to prevent creation of the client in any other way.

public class ControlServiceClient : ClientBase<IControlService>, IControlService
{
    public static ControlServiceClient Create()
    {
        string controlServiceAddress = ConfigurationManager.AppSettings["controlServiceAddress"];
        NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
        tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
        tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

        //set other binding attributes
        tcpBinding.CloseTimeout = new TimeSpan(0, 1, 30);     //default is 1 minute.
        tcpBinding.MaxBufferPoolSize = 1048576;               //1MB default is 65,536 bytes

        //not allowed by partially trusted 
        //tcpBinding.MaxBufferSize = 262144;                  //256KB default is 65,536 bytes

        tcpBinding.MaxConnections = 10;                       //default is 10:
        tcpBinding.MaxReceivedMessageSize = 4194304;          //4MB The default is 65,536 bytes
        tcpBinding.OpenTimeout = new TimeSpan(0, 1, 30);      //The default value is 1 minute
        tcpBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);   //The default value is 10 minute
        tcpBinding.SendTimeout = new TimeSpan(0, 1, 30);      //The default value is 1 minute

        EndpointAddress endpointAddress = 
            new EndpointAddress(string.Format("net.tcp://{0}", controlServiceAddress));
        ControlServiceClient client = new ControlServiceClient(tcpBinding, endpointAddress);
        return client;
    }

    internal ControlServiceClient() { }

    internal ControlServiceClient(string endpointConfigurationName) :
        base(endpointConfigurationName)
    { }

    internal ControlServiceClient(Binding binding, EndpointAddress remoteAddress) :
        base(binding, remoteAddress)
    { }

    internal ControlServiceClient(InstanceContext callbackInstance) :
        base(callbackInstance)
    { }

    public string GetData(int value)
    {
        return base.Channel.GetData(value);
    }

    public CompositeType GetDataUsingDataContract(CompositeType composite)
    {
        return base.Channel.GetDataUsingDataContract(composite);
    }
}
posted on Sunday, March 15, 2009 9:29:31 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, November 24, 2008

I'm experimenting with using the Guid type in databases and applications but I don't like the string format of the Guid. It's not easily read or formatted on a report. I wanted to find a way to represent very large integers such as the Guid (a 128 bit integer under the covers), so I looked around and found a Base 36 type sample on Code Project article by Steve Barker that gave me a great start.

The problem with Base 36 is that several characters are similar to other characters or numbers, so took the code and modified it to use a limited set of 20 characters that are distinctive from numbers and other characters sufficiently to make it easy for humans to read them back or hand enter them in a user interface.

I downloaded the code and went to work making the modifications. Here's the core of the Base 30 struct:

//removed are chars similar to numbers or another char when printed: I, J, O, Q, V, Z
private static List<char> alphaDigits = new List<char>(new char[]{ 'A','B','C','D','E','F','G','H','K','L','M','N','P','R','S','T','U','W','X','Y' });

private static byte Base30DigitToNumber(char Base30Digit)
{
    if(char.IsDigit(Base30Digit))
    {
        //Handles 0 - 9
        return byte.Parse(Base30Digit.ToString());
    }
    else
    {
        //Converts one base-30 digit to it's base-10 value
        if (alphaDigits.IndexOf(Base30Digit) > -1)
        {
            //Handles ABCDEFGHKLMNPRSTUWXY  (these are letters that cannot be confused for numbers)
            int index = alphaDigits.IndexOf(Base30Digit) + 10;
            return (byte)(index);
        }
        else
        {
            throw new InvalidBase30DigitException(Base30Digit);
        }
    }
}

private static char NumberToBase30Digit(byte NumericValue)
{
    //Converts a number to it's base-30 value.
    //Only works for numbers <= 29.
    if(NumericValue > 29)
    {
        throw new InvalidBase30DigitValueException(NumericValue);
    }

    //Numbers:
    if(NumericValue < 10)
    {
        return NumericValue.ToString()[0];
    }
    else
    {
        //Note that A is code 65, and in this
        //scheme, A = 10, Y = 29 ABCDEFGHKLMNPRSTUWXY  use alphaDigits for List<char>
        int index = NumericValue - 10;
        return alphaDigits[index]; //(char)(NumericValue + 55);
    }
}

Now, I have added a couple of static methods to give me a shiny Base 30 guid string and convert that string back to a Guid here:

/// <summary>
/// Convert a Guid to a set of four Base30 string values connected by a dash character.
/// </summary>
/// <param name="g"></param>
/// <returns></returns>
public static string GuidToBase30Set(Guid g)
{
    byte[] b = g.ToByteArray();
    Base30 b1 = BitConverter.ToUInt32(b, 0);
    Base30 b2 = BitConverter.ToUInt32(b, 4);
    Base30 b3 = BitConverter.ToUInt32(b, 8);
    Base30 b4 = BitConverter.ToUInt32(b, 12);
    return string.Format("{0}-{1}-{2}-{3}", b1, b2, b3, b4);
}

/// <summary>
/// Convert the Base30 set string produced by GuidToBase30Set back to a Guid.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static Guid Base30SetToGuid(string s)
{
    string[] p = s.Split('-');
    if (p.Length != 4) throw new ArgumentException("Invalid Base30Set format.");
    try
    {
        Base30 b1 = p[0];
        Base30 b2 = p[1];
        Base30 b3 = p[2];
        Base30 b4 = p[3];

        uint x1 = (uint)b1.NumericValue;
        uint x2 = (uint)b2.NumericValue;
        uint x3 = (uint)b3.NumericValue;
        uint x4 = (uint)b4.NumericValue;

        byte[] a1 = BitConverter.GetBytes(x1);
        byte[] a2 = BitConverter.GetBytes(x2);
        byte[] a3 = BitConverter.GetBytes(x3);
        byte[] a4 = BitConverter.GetBytes(x4);

        byte[] gb = new byte[16];

        a1.CopyTo(gb, 0);
        a2.CopyTo(gb, 4);
        a3.CopyTo(gb, 8);
        a4.CopyTo(gb, 12);

        return new Guid(gb);
    }
    catch
    {
        throw new ArgumentOutOfRangeException("Invalid Base30Set string.");
    }
}

The code above gets you something like this:

Common Guid string: b908d243-c1ac-4ea4-a954-121e4ab5c334
Base30Set from same: 47PGC95-1S8WCHP-MPTTA1-16CUN8P

You can download the code here (Base30.zip 3.6 KB).

posted on Monday, November 24, 2008 5:27:19 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Wednesday, September 17, 2008

In my first attempt at creating a real applicaiton using the new ASP.NET MVC project template (Codeplex Preview 5), I found that when I clicked a new tab I'd created linked to a specific controller and an action I'd decorated with the [Authorize(Roles = "user")] attribute, the "out of the box" Login action did not redirect me to the that controller/action combo once I had successfully logged in.

Here's my solution to the problem. First, I added a hidden value in the Login.aspx form. Second, I added a parameter to the Login action in the Acount controller (AccountController.cs). Let me know if you've found a better way.

Here's the code for the form:

<form method="post" action="<%= Html.AttributeEncode(Url.Action("Login")) %>">
    <div>
        <table>
            <tr>
                <td>
                    Username:
                </td>
                <td>
                    <%= Html.TextBox("username") %>
                </td>
            </tr>
            <tr>
                <td>
                    Password:
                </td>
                <td>
                    <%= Html.Password("password") %>
                </td>
            </tr>
            <tr>
                <td>
                </td>
                <td>
                    <input type="checkbox" name="rememberMe" value="true" />
                    Remember me?
                </td>
            </tr>
            <tr> <!-- Added to handle the returnUrl -->
                <td>
                    <%= Html.Hidden("returnUrl", ViewData["ReturnUrl"].ToString()) %>
                </td>
                <td>
                    <input type="submit" value="Login" />
                </td>
            </tr>
        </table>
    </div>
</form>

Here's the code for the Login action:

public ActionResult Login(string username, string password, bool? rememberMe, string returnUrl)
{
    ViewData["Title"] = "Login";
    string url = (string.IsNullOrEmpty(returnUrl) 
        ? Request.QueryString["ReturnUrl"] ?? string.Empty 
        : returnUrl)
        .Trim('/');
    ViewData["ReturnUrl"] = url;

    // Non-POST requests should just display the Login form 
    if (Request.HttpMethod != "POST")
    {
        return View();
    }

    // Basic parameter validation
    List<string> errors = new List<string>();

    if (String.IsNullOrEmpty(username))
    {
        errors.Add("You must specify a username.");
    }

    if (errors.Count == 0)
    {

        // Attempt to login
        bool loginSuccessful = Provider.ValidateUser(username, password);

        if (loginSuccessful)
        {
            FormsAuth.SetAuthCookie(username, rememberMe ?? false);
            if (url != null && url.Length > 0)
                return RedirectToAction("Index", url);
            else
                return RedirectToAction("Index", "Home");
        }
        else
        {
            errors.Add("The username or password provided is incorrect.");
        }
    }

    // If we got this far, something failed, redisplay form
    ViewData["errors"] = errors;
    ViewData["username"] = username;
    return View();
}
posted on Wednesday, September 17, 2008 8:20:31 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Tuesday, September 09, 2008

I've just installed the plugin blogged about by Mike Ormond and here's an example of it's output taken from code in the Atrax project I've just published to Codeplex.

namespace Atrax.Library
{
   [DataContract, Serializable]
   public class QueryResult
   {
      /// <summary>
      /// The original query sent by the client.
      /// </summary>
      [DataMember]
      public Query Query { get; set; }

      /// <summary>
      /// Status code sent back to query client's callback url.
      /// </summary>
      [DataMember]
      public string StatusCode { get; set; }
      
      /// <summary>
      /// Status description sent back to query client's callback url.
      /// </summary>
      [DataMember]
      public string StatusDescription { get; set; }
      
      /// <summary>
      /// The XML schema for the result XML.
      /// </summary>
      [DataMember]
      public string ResultSchema { get; set; }

      /// <summary>
      /// The result produced by the query processor, usually XML.
      /// </summary>
      [DataMember]
      public string Result { get; set; }
   }
}
posted on Tuesday, September 09, 2008 12:22:07 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, September 07, 2008

Two and a half years ago I wrote an implementation in C# of an algorithm published in 2003 in a short academic paper by Yutaka Matsuo and Mitsuru Ishizuka in the International Journal of Artificial Intelligence Tools. Of course, the algorithm is not a perfect implementation of the algorithm published in the "Keyword Extraction from a Single Document using Word Co-occurrence Statistical Information" paper. I made a number of decisions to make the algorithm as effective as possible while keeping it as fast as I could.

The code was written for Provo Labs, my employer at the time. I've recently obtained written permission from Provo Labs to release this code as open source under the Apache 2.0 license. You can get the code in the Atrax.Html project, a part of the entire Atrax project which I've just released, at http://www.codeplex.com/atrax. Here's the core of the code.

string[] terms = new string[termsG.Count];
termsG.Values.CopyTo(terms, 0); //gives terms array where last term is the MAX g in G
foreach (string w in terms)
{
    decimal sumZ = 0;
    for (int i = 0; i < terms.Length - 1; i++) //do calcs for all but MAX
    {
        string g = terms[i];
        if (w != g) //skip where on the diagonal
        {
            int nw = termNw[w];
            decimal Pg = termPg[g];
            decimal D = nw * Pg;
            if (D != 0.0m)
            {
                decimal Fwg = termFwg[w][terms[i]];
                decimal T = Fwg - D;
                decimal Z = (T * T) / D;
                sumZ += Z;
            }
        }
    }
    termsX2[w] = sumZ;
}

SortedDictionary<decimal, string> sortedX2 = new SortedDictionary<decimal, string>();
foreach (KeyValuePair<string, decimal> pair in termsX2)
{
    decimal x2 = pair.Value;
    while (sortedX2.ContainsKey(x2))
    {
        x2 = x2 - 0.00001m;
    }
    sortedX2.Add(x2, pair.Key);
}

//now get simple array of values as lowest to highest X2 terms
string[] x2Terms = new string[sortedX2.Count];
sortedX2.Values.CopyTo(x2Terms, 0);

I have not spent much time on this algorithm in the past two years and would like to find others with similar interests to help me improve and perfect it. If you have an interest in this kind of research, please join me at the Atrax project page on Codeplex.

posted on Sunday, September 07, 2008 2:12:27 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, August 04, 2008

I want to thank Scott Guthrie and Scott Hanselman and the whole ASP.NET MVC team for making web development fun again.

The simplicity of Rails, the power of .NET, and so much more. I've been reading the posts and watching some of the screencasts but had not yet tried it for real. That all changed over the weekend while working my latest pet project which I hope to reveal sometime soon. I decided to put MVC Preview 4 to the test. I was not disappointed.

I mean, who could not fall in love with the elegant simplicity of this view?

<tr>
  <td>Current password:</td>
  <td><%= Html.Password("currentPassword") %></td>
</
tr>
<
tr>
  <td>New password:</td>
  <td><%= Html.Password("newPassword") %></td>
</
tr>
<
tr>
  <td>Confirm new password:</td>
  <td><%= Html.Password("confirmPassword") %></td>
</
tr>
<
tr>
  <td></td>
  <td><input type="submit" value="Change Password" /></td>
</
tr>

Handled by this controller:

[Authorize]
public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword)
{

    ViewData["Title"] = "Change Password";
    ViewData["PasswordLength"] = Provider.MinRequiredPasswordLength;

    // Non-POST requests should just display the ChangePassword form
    if (Request.HttpMethod != "POST")
    {
        return View();
    }

    // Basic parameter validation
    List<string> errors = new List<string>();

    if (String.IsNullOrEmpty(currentPassword))
    {
        errors.Add("You must specify a current password.");
    }
    if (newPassword == null || newPassword.Length < Provider.MinRequiredPasswordLength)
    {
        errors.Add(String.Format(CultureInfo.InvariantCulture,
                    "You must specify a new password of {0} or more characters.",
                    Provider.MinRequiredPasswordLength));
    }
    if (!String.Equals(newPassword, confirmPassword, StringComparison.Ordinal))
    {
        errors.Add("The new password and confirmation password do not match.");
    }

    if (errors.Count == 0)
    {

        // Attempt to change password
        MembershipUser currentUser = Provider.GetUser(User.Identity.Name, true /* userIsOnline */);
        bool changeSuccessful = false;
        try
        {
            changeSuccessful = currentUser.ChangePassword(currentPassword, newPassword);
        }
        catch
        {
            // An exception is thrown if the new password does not meet the provider's requirements
        }

        if (changeSuccessful)
        {
            return RedirectToAction("ChangePasswordSuccess");
        }
        else
        {
            errors.Add("The current password is incorrect or the new password is invalid.");
        }
    }

    // If we got this far, something failed, redisplay form
    ViewData["errors"] = errors;
    return View();
}

Yes, you say, but what about all my high powered controls from XYZ Controls Company? Do they really make your life that much easier? Is HTML so hard? Have you looked at your ViewState lately? Yikes! Certainly there are tradeoffs, but you can bet that controls are on their way. Where Microsoft stack developers go, the control vendors soon follow.

Give me clean HTML with CSS style and controllers that support TDD in the most straightforward manner I've ever seen, sprinkle in some convention over configuration jazz from Ruby on Rails, and I'm a happy web developer again after having spent the last four and a half years avoiding ASP.NET while writing back end data and content analysis systems.

ASP.NET never looked better!

 

posted on Monday, August 04, 2008 7:03:06 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, March 27, 2008

I am fascinated with Windows Communication Foundation (WCF) but the configuration files can be cumbersome. Until now I haven't had the time to investigate programmatic configuration of WCF, but I may be involved in a project soon in which WCF would be useful but where configuration files would present an unnecessary complication to the end user. So I've spent some time researching and experimenting. To my happy surprise, WCF is easily configured programmatically. A little research has resulted in a simple Windows Forms application talking to a Windows Service via WCF while both client and server use a common class library that defines the service contract and data transfer objects. I'll give you a brief overview and then you can download the solution here.

First let me give credit where credit is due. I could not have figured out all of this stuff without the great help of Juval Lowy and his book Programming WCF Services. I highly recommend the book. I also took advantage of some of the samples published on his http://www.idesign.net/ web site. If you need help with your WCF work, I urge you to contact them.

You download the entire solution at the bottom of this entry, so I'm not going to push all the code into the text here, but I'll try to cover the highlights.

Framework/Architecture
The architecture of this little test application is simple.

  • MyWcfService - (server) A Windows service application
  • MyWcfMon - (client) A Windows Forms application with a simplistic test
  • MyWcfLib - A class library defining the service contract used by client and server

MyWcfLib
Since I like the "contract first" approach, let's begin with the interface and data transfer objects shared by client and server. This is a very simple piece of code but sufficient to illustrate the principles involved (see IMyWcfServiceControl.cs).

[ServiceContract]
public interface IMyWcfServiceControl
{
    [OperationContract]
    MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command);
}

[DataContract]
public class MyWcfServiceCommand
{
    [DataMember]
    public string Command { get; set; }
}

[DataContract]
public class MyWcfServiceResponse
{
    [DataMember]
    public string Response { get; set; }
}

As you can see, we have a simple service contract with a single operation and a simple command object taken and response object returned.

You'll also notice an Extensions.cs file in the MyWcfLib project. These are a few of my favorite extensions I've written lately. I find them very useful but they are not terribly relevant to this project. You can take a look at them later in the source download.

MyWcfService
I won't bore you with the details of the Windows service code, though I do encourage you to download the code and give it a look. I've blogged about this before but it's worth metioning, if only for the keyword exposure. The service code allows you to debug the service as a console application and then compile in "Release" and deploy/install as a real Windows service. A handy little chunk of code.

The primary area of interest in the service is the declaration of the WCF ServiceHost and how it is configured in code. In the following lines of code found in the MyWcfService.cs file in the project, we create a WCF host listening on a port configured using the m_port value, requiring Windows authentication and using encryption and message signing on the transport layer. Fast but highly secure.

Uri tcpBaseAddress = new Uri(string.Format("net.tcp://localhost:{0}/", m_port));
serviceHost = new ServiceHost(typeof(MyWcfServer), tcpBaseAddress);

NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

serviceHost.AddServiceEndpoint(typeof(IMyWcfServiceControl), tcpBinding,
    string.Format("net.tcp://localhost:{0}/MyWcfServiceControl", m_port));

//this is the default but good to know
serviceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseWindowsGroups;

serviceHost.Open();

That's it. We're now configured. Not so hard. Not really any more difficult than raw .NET remoting configuration. In fact, probably easier.

Of course, the Stop method on the ServiceRunner class executes the Close method on the service host.

Now to the implementation of the IMyWcfServiceControl interface in the MyWcfServer.cs file:

internal class MyWcfServer : IMyWcfServiceControl
{
    [PrincipalPermission(SecurityAction.Demand, Role = @"nbdev2\allwcfgroup")]
    [PrincipalPermission(SecurityAction.Demand, Role = @"nbdev2\mywcfgroup")]
    public MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
    {
        MyWcfServiceResponse response = null;
        if (IsAuthorized())
        {
            response = new MyWcfServiceResponse()
            {
                Response = command.Command + " response " + DateTime.Now.ToLongTimeString()
            };
        }
        else
        {
            response = new MyWcfServiceResponse()
            {
                Response = "Error: user not authorized"
            };
        }
        return response;
    }

    bool IsAuthorized()
    {
        //The PrincipalPermission attributes are an OR proposition.
        //The following enforces the AND requirement.
        IPrincipal p = Thread.CurrentPrincipal;
        if (p.IsInRole(@"nbdev2\allwcfgroup") && p.IsInRole(@"nbdev2\mywcfgroup"))
            return true;
        else
            return false;
    }
}

Note that we have two layers of security authorization employed here. (Authentication has already been handled automatically for us.) First we have two PrincipalPermission attributes that demand that the user be in one of two groups. But in fact, our invented requirement here is that the user belong to both groups. Don't ask me why. It's a demo.

So the IsAuthorized method is called and there we examine the Thread.CurrentPrincipal to learn if the requirement is met. This was a revelation to me. I did not know that the thread handling the single call to the WCF service would be running under the calling user context. A very good thing to know. Note to self...

MyWcfMon
Now to the client. It's simple really, and you could probably find an even more clever way to write it, but this might help you get started. You will find in the source a file called MyWcfServiceProxy.cs where the following code lives in the MyWcfServiceProxy class:

internal MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
{
    NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport, false);
    tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
    tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

    EndpointAddress endpointAddress =
        new EndpointAddress(string.Format("net.tcp://{0}:{1}/MyWcfServiceControl", m_server, m_port));
    
    MyWcfServiceControlClient proxy = new MyWcfServiceControlClient(tcpBinding, endpointAddress);

    //Note: current user credentials are used unless we use runtime provided credentials like this
    NetworkCredential credentials = new NetworkCredential(m_userName, m_password);
    if (m_domain != null) credentials = new NetworkCredential(m_userName, m_password, m_domain);
    proxy.ClientCredentials.Windows.ClientCredential = credentials;
    
    MyWcfServiceResponse response = proxy.ExecuteCommand(command);
    
    //if proxy is in Faulted state, Close throws CommunicationObjectFaultedException
    if (proxy.State != CommunicationState.Faulted) proxy.Close();

    return response;
}

class MyWcfServiceControlClient : ClientBase<IMyWcfServiceControl>, IMyWcfServiceControl
{
    public MyWcfServiceControlClient(Binding binding, EndpointAddress address) : base(binding, address) { }
    public MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command)
    {
        MyWcfServiceResponse response = null;
        try
        {
            response = Channel.ExecuteCommand(command);
        }
        catch (SecurityNegotiationException ne)
        {
            response = new MyWcfServiceResponse() { Response = ne.Message };
        }
        catch (SecurityAccessDeniedException ae)
        {
            response = new MyWcfServiceResponse() { Response = ae.Message };
        }
        return response;
    }
}

The WCF client is easily configured programmatically as you can see. Create a Binding, an EndpointAddress, a NetworkCredential if you want to, and then call the service. The private MyWcfServiceControlClient class just makes it a little easier to isolate the configuration code in the code above it.

So now, we have a simple Form that does this:

string userName = txtUserName.Text;
string password = txtPassword.Text;
MyWcfServiceProxy sp = new MyWcfServiceProxy("localhost", 8239, userName, password, null);
MyWcfServiceCommand command = new MyWcfServiceCommand()
{
    Command = "Hello world."
};
MyWcfServiceResponse response = sp.ExecuteCommand(command);
lblTest.Text = response.Response;

With this little framework, you can extend the command and response classes and build pretty much anything you want between your Windows Forms application and your Windows service with the comfort of secure, encrypted and signed communication between the two on the port of your choice.

If you find this useful, I'd love to hear about it. The code can be found here MyWcfService.zip (31.55 KB) under the MIT license. Enjoy!

posted on Thursday, March 27, 2008 2:29:41 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Tuesday, March 18, 2008

I was playing around with some old code in which I had a custom ConfigurationSection (see code below). I had an attribute in the configuration section that I wanted to change from an Int32 to a Double. Seems a simple change. Just a little refactoring of the ConfigurationElement class changing the "int" declaration to "double" and it compiles. But kablam! It does not run but throws a nasty System.Configuration.ConfigurationErrorsException with this explanation:

The default value for the property 'size' has different type than the one of the property itself.

Huh? Turns out the type inference on the DefaultValue property in the ConfigurationProperty attribute is rather picky. Here's what I had originally:

[ConfigurationProperty("size", DefaultValue = 1, IsKey = false, IsRequired = true)]
public int Size
{
    get
    { return (int)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

And here's what I changed it to thinking it would run just fine:

[ConfigurationProperty("size", DefaultValue = 1, IsKey = false, IsRequired = true)]
public double Size
{
    get
    { return (double)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

Just because the above code compiled, does not mean it will work correctly. So here's what really worked:

[ConfigurationProperty("size", DefaultValue = 1.0, IsKey = false, IsRequired = true)]
public double Size
{
    get
    { return (double)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

Small but important lesson to learn. Here's the whole code and following it the snippet from the config file in case this is the first time you've written a custom config handler.

using System;
using System.Collections;
using System.Text;
using System.Configuration;
using System.Xml;

namespace MyConfigBox
{
    public class SizeLimitConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("hostSize")]
        public HostSizeConfigCollection HostSize
        {
            get
            {
                return ((HostSizeConfigCollection)(base["hostSize"]));
            }
        }
    }

    [ConfigurationCollectionAttribute(typeof(HostSizeConfigElement))]
    public class HostSizeConfigCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new HostSizeConfigElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((HostSizeConfigElement)(element)).Name;
        }

        public void Add(HostSizeConfigElement element)
        {
            this.BaseAdd(element);
        }

        public void Remove(string key)
        {
            this.BaseRemove(key);
        }

        public void Clear()
        {
            this.BaseClear();
        }

        public HostSizeConfigElement this[int idx]
        {
            get { return (HostSizeConfigElement)this[idx]; }
        }
    }

    public class HostSizeConfigElement : ConfigurationElement
    {
        public HostSizeConfigElement() { }
        public HostSizeConfigElement(string name, double size)
        {
            this.Name = name;
            this.Size = size;
        }

        [ConfigurationProperty("name", DefaultValue = "_", IsKey=true, IsRequired = true)]
        [StringValidator(InvalidCharacters = "~!@#$%^&()[]{}/;'\"|\\", MinLength = 1, MaxLength = 260)]
        public string Name
        {
            get
            { return (string)this["name"]; }
            set
            { this["name"] = value; }
        }

        [ConfigurationProperty("size", DefaultValue = 1.0, IsKey = false, IsRequired = true)]
        public double Size
        {
            get
            { return (double)this["size"]; }
            set
            { this["size"] = value.ToString(); }
        }
    }
}

And now here's the config file (some items removed to clean it up a bit and just show the relevant parts):

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="sizeLimits" type="MyConfigBox.SizeLimitConfigurationSection, MyConfigBox" />
    </configSections>
    <appSettings/>
    <connectionStrings/>

    <sizeLimits>
        <hostSize>
            <add name="netbrick.net" size="17.5" />
            <add name="duovia.com" size="42.4" />
        </hostSize>
    </sizeLimits>

</configuration>

And here's an example of how to use the custom config handler in code:

SizeLimitConfigurationSection config =
   (SizeLimitConfigurationSection)(System.Configuration.ConfigurationManager.GetSection("sizeLimits"));
//now use config to get at the items in the hostSize collection of HostSizeConfigElement objects

So watch those attribute values because sometimes the compiler won't.

posted on Tuesday, March 18, 2008 3:32:54 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [2]
# Wednesday, January 30, 2008

When something works well on its own with a high level of reliability, we tend to take it for granted and forget about the mechanics of how it works. We turn the key of our car and expect the engine to fire up. No thought is given to the inner workings of the internal combustion engine.

We write .NET code and expect the CLR and its garbage collector to manage memory for us without having to think much about value types, reference types, the stack and the heap. We just write code that works and thank our lucky stars that we've seen the last of malloc. Sure we have to dispose of some objects that reference system or outside resources manually but that's simple work.

But sometimes it's fun to look under the hood. And who knows, it might show up on a test.

So what is the heap and the stack and what is the difference between a reference type and a value type and what do they have to do with the stack and the heap and garbage collection?

You're right. I'm about to tell you. Now I'm not a compiler or CLR guru and this is not a graduate level CS class. This is a blog post, so we'll try to keep it real. There are far greater explainations that go into much more detail out there on the web and in texts. I hope this post will serve as a summary reminder of these concepts and help us understand the engine under the hood a bit better. And remember, this post is based on what I know, so if I'm wrong about something here, please feel free to correct me.

What is the Stack?
The Stack is essentially a LIFO (last in, first out) execution stream for a given thread (each thread gets its own Stack) with the most recently called method on the top containing parameters, stack allocated value types (more on that later), and references or pointers to data items in the Heap. The CLR using the JIT compiler manages what goes on the Stack. When a method returns or fires an unhandled exception, that top item on the Stack is removed and control is returned to the next item on the Stack. Sometimes you will see the Stack referred to as the "call stack."

What is the Heap?
The Heap's purpose is to hold information. The Heap is like a filing cabinet where data is stored. While the Stack is only accessed by the CLR in a LIFO fashion, the Heap can be accessed without constraint. The Heap contains the data you generally think of as variables or objects that are reference types. When we're done with things in the Heap, they have to be cleaned up to make room for other things. That's the job of the garbage collector.

What is a Value Type?
A value type is an object that is derived implicitly from the System.ValueType which overrides the System.Object virtual methods more appropriate to value types. Value types fall into to main categories:

Structs
Structs fall into these categories:
  • numeric types
    - integral types (byte, char, short, int, long, sbyte, ushort, uint, ulong)
    - floating-point types (double, float)
    - decimal
  • boolean
  • user defined structs
 
 Enumerations
 Enumerations are a set of named constants with an underlying type which can be any integral type except System.Char.

Value types are allocated on the Stack or allocated inline in a structure. This means that value types are almost always stored in the execution or call stack memory. When they're used like an object, they're wrapped up to look like a reference type and placed on the Heap. This is called boxing. Bringing the object back into use on the Stack as a value type is called unboxing.

The most important thing to remember about value types is that the assignment of one value type to another results in the data being copied. For example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackHeap
{
    class Program
    {
        static void Main(string[] args)
        {
            MyData me = new MyData();
            me.Age = 42;
            me.Name = "Sam";
            me.Relationship = "married";

            MyData her = me;
            her.Age = 44;
            her.Name = "Mary";

            Console.WriteLine("I am {0} years old. My name is {1}.", me.Age, me.Name);
            Console.WriteLine("She is {0} years old. Her name is {1}.", her.Age, her.Name);
            Console.WriteLine("I am {0} to her. She is {1} to me.", me.Relationship, her.Relationship);

            Console.ReadLine();
        }
    }

    public struct MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }
}

Output
 I am 42 years old. My name is Sam.
 She is 44 years old. Her name is Mary.
 I am married to her. She is married to me.

The assignment of the Age value applies only to the copy of the original. It is a value type.

Now consider the output if we make MyData a reference type by changing it to a class.

    public class MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }

Output
 I am 44 years old. My name is Mary.
 She is 44 years old. Her name is Mary.
 I am married to her. She is married to me.

The assignment of the Age and Name values apply to both objects now because the variable refers to or points to the object created with the "new MyData()" call.

The same behavior can be observed in using value types and reference types as parameters. Consider this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackHeap
{
    class Program
    {
        static void Main(string[] args)
        {
            MyData me = new MyData();
            me.Age = 42;
            me.Name = "Sam";
            me.Relationship = "married";

            MyData her = me;
            her.Age = 44;
            her.Name = "Mary";

            ModifySomeData(me, ref her);

            Console.WriteLine("I am {0} years old. My name is {1}.", me.Age, me.Name);
            Console.WriteLine("She is {0} years old. Her name is {1}.", her.Age, her.Name);
            Console.WriteLine("I am {0} to her. She is {1} to me.", me.Relationship, her.Relationship);

            Console.ReadLine();
        }

        private static void ModifySomeData(MyData me, ref MyData her)
        {
            me.Age = 50;
            her.Age = 50;
            Console.WriteLine("\nMy age changed to {0} as value type parameter.", me.Age);
            Console.WriteLine("Her age changed to {0} as value type parameter passed by ref.\n", me.Age);
        }
    }

    public struct MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }
}

Output
 My age changed to 50 as value type parameter.
 Her age changed to 50 as value type parameter passed by ref.
 
 I am 42 years old. My name is Sam.
 She is 50 years old. Her name is Mary.
 I am married to her. She is married to me.

Notice that her.Age changed permanently and me.Age changed only in the "copy" in the ModifySomeData method because it was not passed as a "by ref" parameter. Now what happens to the output if we change the MyData to a class rather than a struct? Here's the output if we make MyData a reference type by making it a class:

    public class MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }

Output
 My age changed to 50 as value type parameter.
 Her age changed to 50 as value type parameter passed by ref.
 
 I am 50 years old. My name is Mary.
 She is 50 years old. Her name is Mary.
 I am married to her. She is married to me.
 

So what happened when we passed a value type "by ref" in the example above? It was boxed into a reference type. And when we changed MyData into a class, the parameters are passed "by ref" regardless of whether the "ref" keyword is used. This is an important distinction to learn when dealing with parameter values.


What is a Reference Type?
Reference types can be a class, interface or delegate. All classes are ultimately derived from System.Object. Interfaces and delegates are special reference types. Exactly what they are and how they are used is a subject for another day. There are two built in reference types: object and string. These types are "native" to the CLR and do not require a "class definition" in code. All other reference types are defined in existing framework assemblies, third party assemblies or in your own code.

When you create an instance of a reference type or pass that instance as a parameter, a pointer is placed in the call Stack that references the object in the Heap. While value types live in the call Stack and are cleaned up with the removal of their associated execution call, the data on the Heap must be cleaned up by the garbage collector (GC).

What is the GC?
The garbage collector in the .NET CLR is the intelligent mechanism that deals with data on the Heap for which there is no reference or rather no existing pointer in the call Stack. It scans the Stack from time to time to determine if an object in the Heap is referenced. If the object is no longer referenced, it removes the object from the Heap returning that memory space to the runtime and eventually to the system.

The GC uses a "generations" approach to improve the speed with which garbage collection is done. The reason this is required is that while garbage collection is done (the traversing of the call Stack and iteration through the Heap), nothing else can be done. In other words, all processing threads are halted while garbage collection is performed.

The GC marks each object in the Heap with a generation value: 0, 1 or 2. The reason for this is that objects that make it through two garbage collection passes are likely to be objects that will live a long time, such as a Windows.Form object. On the other hand, short lived objects such as a local string literal will generally not survive one garbage collection pass. By marking objects with a generation value, the GC can prioritize its work. For example, if sufficient memory is recovered by examining objects with the generation value of zero, then further garbage collection is not required and processing may continue. This way you get a good balance between memory use and performance.

Summary
That's about all I have to say on this subject for now. I'm sure that virtual forests have been consumed in addressing these topics, but writing this up has been a good exercise for me. If you find mistakes, please let me know but go easy on me. :)

posted on Wednesday, January 30, 2008 6:21:40 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Saturday, October 20, 2007

Often in my line of work, I need to create parameterized queries in code. All those overloaded constructors. Yuck. So, like a lazy guy would, I built a factory. I use it everywhere. In my personal projects and even at work when no one is looking. Here it is:

static SqlParameter CreateParameter(string name, SqlDbType type,
    ParameterDirection direction, int? size, byte? precision, object value)
{
    SqlParameter param = new SqlParameter(name, type);
    param.Direction = direction;
    if (size.HasValue) param.Size = size.Value;
    if (precision.HasValue) param.Precision = precision.Value;
    if (value != null) param.Value = value; else param.Value = DBNull.Value;
    return param;
}

And then when I'm building a command, I just do this:

cmd.Parameters.Add(DataAccess.CreateParameter("@RETURN_VALUE",
    SqlDbType.Int, ParameterDirection.ReturnValue, null, null, null));
cmd.Parameters.Add(DataAccess.CreateParameter("@ID",
    SqlDbType.Int, ParameterDirection.Input, null, null, id));
cmd.Parameters.Add(DataAccess.CreateParameter("@NAME",
    SqlDbType.VarChar, ParameterDirection.Input, 50, null, name));

Of course, it won't work for everything, but it makes quick work out of most of my parameter creation. Hooray for the factory.

posted on Saturday, October 20, 2007 8:46:44 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, September 09, 2007

Sometimes your logger throws an exception while logging an exception. At least it does if you have luck swings like mine from time to time.

Here's how I deal with it.

using System.Diagnostics;

try
{
    //some logging code that can throw an exception
    //but the exception has to be handled and logged
    //somehow
}
catch (Exception e)
{
    try
    {
        //write exception to OS event log
        if (!EventLog.SourceExists("MyAppName"))
            EventLog.CreateEventSource("MyAppName", "Application");
        EventLog.WriteEntry("MyAppName", "Log Exception: " + e.Message);
    }
    catch
    {
        //sorry charlie
    }
}

It's not perfect, but it seems to work in most cases.

This code comes in handy especially in Windows Services where in the .NET Framework 2.0 and up (as near as I can tell), an unhandled exception will result in your service being stopped with little or no evidence as to why.

posted on Sunday, September 09, 2007 8:54:37 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, September 01, 2007

I've recently begun to explore MySQL a bit more, mostly out of curiosity. Primarily I work with SQL Server 2005 in my day job but it seems prudent to know a bit more about some of the other databases servers and it's been a while since I dusted off MySQL.

Happily I found that MySQL AB has released a really great ADO.NET provider for MySQL.

If you have used the SQL Server specific ADO.NET provider, you'll easily make the transition to using this one.

But I digress. The reason for this posting was to permanently remind myself and anyone else making a transition between these two database engines that TOP = LIMIT but not in the same place. That is to say, the TOP keyword is used in SQL Server to limit the number of returned rows just prior to the column specifiers. The LIMIT keyword however is used at the end of the select statement. Thus:

SELECT TOP 1 * FROM MYTABLE WHERE FKID = 3

And for MySQL use:

SELECT * FROM MYTABLE WHERE FKID = 3 LIMIT 1;

Yes, I know. It ought to be obvious, but having a quick reminder here will help to seal this minor difference into my brain.

posted on Saturday, September 01, 2007 10:30:13 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, August 19, 2007

If you've written an ASP.NET application, you've already taken advantage of schema driven XML configuration perhaps without even realizing it. You may have even ignored the web.config file if you're just starting out with ASP.NET. Or you may have used it extensively without considering the usefulness of using such a construct in your own applications.

My day job involves writing a complex application that implements a myriad of business rules, nearly all of which non-coders need to be able to modify from time to time without bothering the development team. That means using XML. But not just any old XML. I'm talking about well formed, validated XML using a nice XSD schema file controlled by the development team.

I recommend the reader purchase O'Reilly's book XML Schema by Eric van der Vlist. It's been a most trustworthy companion. And then to make the use of this XML configuration dreamscape even easier, I recommend Christian Weyer's contract first tool. I use this extremely useful tool to generate the XAL (XML access layer) so I don't have to write it by hand.

With these two tools in hand, you can create something like this in Visual Studio:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="watchconfig" targetNamespace="http://example.com/v1001/watchconfig.xsd"
    elementFormDefault="qualified"
    xmlns="http://example.com/v1001/watchconfig.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="watchconfig">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="watchgroup" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="watchgroup">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="watcher" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:attribute name="id" type="xs:string" use="required" />
            <xs:attribute name="literalsconfigpath" type="xs:string" />
        </xs:complexType>
    </xs:element>
    <xs:element name="watcher">
        <xs:complexType>
            <xs:attribute name="sourcepath" type="xs:string" use="required" />
            <xs:attribute name="wippath" type="xs:string" use="required" />
            <xs:attribute name="outpath" type="xs:string" use="required" />
            <xs:attribute name="ssispath" type="xs:string" use="required" />
            <xs:attribute name="intakemap" type="xs:string" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>

And an XML file like this:

<?xml version="1.0" encoding="utf-8" ?>
<watchconfig xmlns="http://example.com/v1001/watchconfig.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <watchgroup id="clientname" literalsconfigpath="H:\temp\literals_client">
        <watcher sourcepath="H:\temp\client\watch"
                    wippath="H:\temp\client\wip"
                    outpath="H:\temp\client\out"
                    ssispath="H:\temp\client\ssis"
                    intakemap="D:\Contracts\Code\map.xml" />
    </watchgroup>
</watchconfig>

And the nicely generated code like this:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, TypeName="watchconfig")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.com/v1001/watchconfig.xsd", IsNullable=false, ElementName="watchconfig")]
[System.ComponentModel.TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
public partial class Watchconfig
{

/// <remarks/>
private System.Collections.Generic.List<Watchgroup> watchgroup;

public Watchconfig()
{
}

public Watchconfig(System.Collections.Generic.List<Watchgroup> watchgroup)
{
this.watchgroup = watchgroup;
}

[System.Xml.Serialization.XmlElementAttribute("watchgroup", Order=0)]
public System.Collections.Generic.List<Watchgroup> Watchgroup
{
get
{
return this.watchgroup;
}
set
{
if ((this.watchgroup != value))
{
this.watchgroup = value;
}
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, TypeName="watchgroup")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.com/v1001/watchconfig.xsd", IsNullable=false, ElementName="watchgroup")]
[System.ComponentModel.TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
public partial class Watchgroup
{

/// <remarks/>
private System.Collections.Generic.List<Watcher> watcher;

/// <remarks/>
private string id;

/// <remarks/>
private string literalsconfigpath;

public Watchgroup()
{
}

public Watchgroup(System.Collections.Generic.List<Watcher> watcher, string id, string literalsconfigpath)
{
this.watcher = watcher;
this.id = id;
this.literalsconfigpath = literalsconfigpath;
}

[System.Xml.Serialization.XmlElementAttribute("watcher", Order=0)]
public System.Collections.Generic.List<Watcher> Watcher
{
get
{
return this.watcher;
}
set
{
if ((this.watcher != value))
{
this.watcher = value;
}
}
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="id")]
public string Id
{
get
{
return this.id;
}
set
{
if ((this.id != value))
{
this.id = value;
}
}
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="literalsconfigpath")]
public string Literalsconfigpath
{
get
{
return this.literalsconfigpath;
}
set
{
if ((this.literalsconfigpath != value))
{
this.literalsconfigpath = value;
}
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, TypeName="watcher")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.com/v1001/watchconfig.xsd", IsNullable=false, ElementName="watcher")]
[System.ComponentModel.TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
public partial class Watcher
{

/// <remarks/>
private string sourcepath;

/// <remarks/>
private string wippath;

/// <remarks/>
private string outpath;

/// <remarks/>
private string ssispath;

/// <remarks/>
private string intakemap;

public Watcher()
{
}

public Watcher(string sourcepath, string wippath, string outpath, string ssispath, string intakemap)
{
this.sourcepath = sourcepath;
this.wippath = wippath;
this.outpath = outpath;
this.ssispath = ssispath;
this.intakemap = intakemap;
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="sourcepath")]
public string Sourcepath
{
get
{
return this.sourcepath;
}
set
{
if ((this.sourcepath != value))
{
this.sourcepath = value;
}
}
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="wippath")]
public string Wippath
{
get
{
return this.wippath;
}
set
{
if ((this.wippath != value))
{
this.wippath = value;
}
}
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="outpath")]
public string Outpath
{
get
{
return this.outpath;
}
set
{
if ((this.outpath != value))
{
this.outpath = value;
}
}
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="ssispath")]
public string Ssispath
{
get
{
return this.ssispath;
}
set
{
if ((this.ssispath != value))
{
this.ssispath = value;
}
}
}

[System.Xml.Serialization.XmlAttributeAttribute(AttributeName="intakemap")]
public string Intakemap
{
get
{
return this.intakemap;
}
set
{
if ((this.intakemap != value))
{
this.intakemap = value;
}
}
}
}

(Sorry, indentation got hosed, but you won't need it since you'll be generating this code with one click.)

 

 

 

 

posted on Sunday, August 19, 2007 9:58:51 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Wednesday, July 18, 2007

I subscribe to CodeProject's newsletter and "product information" emails. Today I received an interesting missive with the headline: "Introducing the new DB2 Express-C". And I noted the "no charge edition" limits you 2 (dual core) processors, 4GB ram limit but with unlimited database size and number and unlimited users.

SQL Server 2005 Express is limited to one CPU and 1GB of ram with a max database size of 4GB. Hmm... I'll bite. I want to know more.

A little exploration reveals a nice article on the wiki about leveraging your MySQL skills. And there seems to be ample information on using DB2 with .NET.

Having never used DB2, I'm completely unaware of what I'm getting myself into, but I'm seriously considering diving into this latest addition to the free, and increasingly capable, database engines.

So I'm downloading now and I'll give it a whirl and report what I find back here. No promises on when.


 Followup - Who am I kidding. The install is HUGE and I have had no time to eval this thing. Toss another distraction overboard.

posted on Wednesday, July 18, 2007 7:14:21 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Friday, June 08, 2007

You learn something new every day. I just don't have time to blog about it every time. This one seemed significant enough.

I'm writing a little ASP.NET app to keep up my web skills since my day job keeps me busy cranking out back-end code. For the first time, I've tried playing with themes. I wanted to assign a theme based on a user configuration, so I unwittingly assigned it in the Page_Load event.

Bo no... Nasty little error message telling me I can't do that, so a bit of digging revealed it has to be done earlier in the life of the page.

protected void Page_PreInit(object sender, EventArgs e)
{
    this.Theme = GetTheme();
}

That did the trick.

posted on Friday, June 08, 2007 9:36:51 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, March 11, 2007

I'm having fun. In the last couple of months, I've carved out about 20 hours of fun playing with some code and tools I found on www.devincook.com. If you're interested in the creation of programming languages, I want to encourage you to to check out that site and the code (link below) that I've derived and organized from code found on that site.

I even tried to share my enthusiasm with the .NET Users Group I like to attend, though as most attendees will confirm, my presentation was ill prepared, disorganized and rambled. Hopefully the 20 or so new attendees at the users group meeting will realize that my presentation is not representative of the excellent presentations the group is use to and will come back.

In the code you can download below, you'll find my first attempt at a language: TROLL — Tyler's Really Obtuse Little Language. It's based on the concepts in the sample SIMPLE interpreter I downloaded from Devin Cook's site under the C# Engines (I recommend Morozov's engine).

Why would anyone want to write their own programming language, you ask. Especially when we have C#, VB.NET, Boo and yes, even Java. Yeah, yeah, there's C++ and D as well, and a hundred others.

So why one more programming language? Because now you can.

It's a great learning experience. You'll learn about BNF, LALR and other fun acronymns. What's more, you may find it an empowering experience to write your own programming language and see your own made-up code executed. You might even find a real use for creating a 4th+ generation language for a specific, vertical solution.

Well, whatever your reason, download the code, download Devin Cook's GOLD Builder and have some fun.

Download code (659KB)

posted on Sunday, March 11, 2007 10:14:24 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [2]
# Wednesday, November 01, 2006

Where's the response?
I couldn't figure out why I was not getting an immediate response. I ran through my code several times before I realized I was missing a key test at a crucial decision making point. I was failing to check whether or not the ManagedThreadPool in my application could get to my request now or whether the request would be pooled.

ManagedThreadPool.ActiveThreads < ManagedThreadPool.MaxThreads - 2

Simple as that. A simple test in a more complex if statement. Why the - 2? Well, I needed a margin to allow for the fact that other threads would be jamming their own jobs in. So I figured a margin of 2 unused threads would give me that. We'll see how it does in the real world.

Lesson Learned
If you plan to use a thread pool, be sure to pay attention to how many babies are in the water at the moment you decide to jump in. Otherwise, you may not get what you expect when you expect, especially in a system like I have been working on where hundreds or even thousands of items might be queued up.

(Note: This is being reposted because I inadvertently allowed trackbacks and the previous post got hammered with spam trackbacks and dasBlog would log me out when I tried to go to the post to delete them. Go figure...)

posted on Wednesday, November 01, 2006 1:46:49 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Monday, September 18, 2006

A little puzzle came up today. Fetch an image out of a database and stream it down to the browser. The trick: we don't know what type of image is stored in the database. So I borrowed a little from our Python friends and this is what I ended up with.

internal static class ImageTypeFinder
{
    internal static string GetMimeType(byte[] image)
    {
        string retval = "image/jpeg";
        string imgtype = GetImageType(image);
        switch (imgtype)
        {
            case "bmp":
                retval = "image/bmp";
                break;
            case "gif":
                retval = "image/gif";
                break;
            case "tif":
                retval = "image/tiff";
                break;
            case "png":
                retval = "image/png";
                break;
        }
        return retval;
    }

    internal static string GetImageType(byte[] image)
    {
        int len = image.Length;
        if (len > 32) len = 32;
        string first32 = ASCIIEncoding.ASCII.GetString(image, 0, len);
        return GetImageType(first32);
    }

    internal static string GetImageType(string first32)
    {
        string retval = string.Empty;
        if (first32.StartsWith("GIF87a") || first32.StartsWith("GIF89a"))
            retval = "gif";
        else if (first32.StartsWith("MM") || first32.StartsWith("II"))
            retval = "tif";
        else if (first32.Substring(6, 4) == "JFIF" || first32.Substring(6, 4) == "Exif")
            retval = "jpg";
        else if (first32.StartsWith("BM"))
            retval = "bmp";
        else if (first32.Substring(1, 3) == "PNG")
            retval = "png";
        return retval;
    }

}

It's a bit of an esoteric puzzle, but if you're trying to solve this one, the above code should help.

posted on Monday, September 18, 2006 9:00:41 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [2]
# Friday, September 01, 2006

Some time ago and again today, I had occasion to write an ASP.NET page that had no form in the .ASPX page but would accept and handle POST 'ed data. This was in an effort to support a REST-like interface for non-ASP.NET developers. Here's the way it turned out.

The .ASPX page looks something like this:

<%@ Page Language="C#"
 
AutoEventWireup="true"
  CodeBehind="extract.aspx.cs"
  Inherits="KeyExtractWeb.extract" %>

There is nothing else in the file. Now the code behind looks like this:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace KeyExtractWeb
{
    public partial class extract : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string alldata = string.Empty;
            using (StreamReader sr = new StreamReader(this.Request.InputStream))
            {
                alldata = sr.ReadToEnd();
            }

            //convert to strings - assumes URL encoded data
            string[] pairs = alldata.Split('&');
            NameValueCollection form = new NameValueCollection(pairs.Length);
            foreach (string pair in pairs)
            {
                string[] keyvalue = pair.Split('=');
                if (keyvalue.Length == 2)
                {
                    form.Add(keyvalue[0], HttpUtility.UrlDecode(keyvalue[1]));
                }
            }

            if (alldata.Length > 0 && this.Request.HttpMethod.ToUpper() == "POST")
            {
                if (form["text"] != null)
                {
                    //TODO - do something with the data here
                }
                else
                    Response.Write("*** 501 Invalid data ***");
            }
            else
                Response.Write("*** 599 GET method not supported. ***");

            Response.End();
        }
    }
}

Well, there you have it. There are probably better ways to do this, but I didn't find one.

posted on Friday, September 01, 2006 3:52:53 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Sunday, July 30, 2006

Thread Abortion
Why is my app working in my Windows XP Pro machine and not on the Windows Server 2003 production machine? I have two ASP.NET apps that run on the same server and interact between one another. Why? Because eventually they will go their separate ways behind a load balancer onto many machines. And I was logging unexplained ThreadAbort exceptions.

Clue: IIS 6 and Application Pools
After working on fine tuning my code nearly all day and still getting the same result, it dawned on me that the two unique Application Pools that I had created on which the two ASP.NET apps would run had properties. Doh! Check out the properties.

Application Pool Properties
I made the following changes on the assumption that because each request to the application would launch work on a ManagedThreadPool and return something immediately. Because of that, the settings of the application pool would allow the process to be killed and/or cycled while executing on those working threads and generate the unexpected ThreadAbort exception.

  • Recycling tab - disable the check boxes
  • Performance tab - diable the check boxes
  • Health tab - uncheck "Enable rapid-fail protection"

Positive Result
Ran the test again and alakazam! No ThreadAbort exceptions.

Threading on ASP.NET
There have been several issues I've run into over the past few months in dealing with handling work after the request has long since been sent back to the client. Using the ThreadPool vs the ManagedThreadPool from Stephen Toub and this Application Pool thing have been among the trickiest.

What are the dangers?
I'm sure there are dangers in disabling the safety net around the Application Pool. So I'm making sure that these two apps run on their own. I may experiment with re-enabling them one at a time and observing the result. If you have any advice for me on the matter, I'd love to hear from you.

posted on Sunday, July 30, 2006 7:31:17 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]

A month or two ago, I started looking for an RSS client again. I had tried some a year or two ago but never really liked them. I now have greater reason to keep track of a few blogs and other RSS sources. There seem to be quite few now.

All the Readers a Local Client
Okay. Not all, but nearly all of the RSS readers are local clients which means installing another piece of software on a machine already full of it. What I wanted was a daily or thrice daily email with updates on all my favorite feeds. Simple. But none of the online sites I browsed provided what I wanted.

Rolling My Own
So I had a free weekend on my hands. I could have spent it fishing but I don't fish. I could have spent it golfing but I don't golf anymore. So I registered RSSJAM.COM and wrote a little file based ASP.NET app that would do what I wanted.

Daily Emails
Now I get three emails a day with a nice HTML formatted message that shows me my feeds with the stories that have been posted in the last 24 hours listed at the top.

Explosive Growth
After a month or two of telling a few people about it, only 16 people have signed up to use RssJam for free, so I don't expect it to be a huge hit or make me a ton of money. But it's a fun and useful tool. And for those of you who spent the time to read this post, if you want, just shoot me an email and ask for the code. I'll be happy to zip it up and send it to you. Who knows, you might set up your own site inside your team to keep track of all your teams blogs. Or whatever.

The link to email me is at the bottom of the left column here.

posted on Sunday, July 30, 2006 10:01:47 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, July 29, 2006

The Bug - Submitted June 5, 2006
On June 5, 2006, I submitted a bug to Microsoft their Connect site and expected that it was an exercise in futility. Who would listen to me? Here's what I submitted to them.

Title: Long pattern string results in race condition on x64 system but not x86 system
A long pattern string in a Regex constructor works fine on my x86 Windows XP development machine but results in a race condition that eats RAM very fast until an "out of memory" condition occurs an the process is killed on the x64 Windows Server 2003 machine. In steps below, I will cut and paste the code which resulted in the condition--the input exceeds 2000 characters so I will remove some of the lines that concatenate the pattern string but one can easily add additional lines to achieve the result that I experienced. To resolve it or work around it, I simply split the Regex into 19 Regex objects and that resolved the problem.

This happened after developing a pattern to remove unwanted words from text before I run the keyword extraction algorithm I wrote based on this whitepaper by a brilliant young researcher named Yutaka Matsuo and the honorable professor Mitsuru Ishizuka at the University of Tokyo.

Fixed - July 7, 2006
I received an email from the Connect system to let me know the bug had been fixed. Of course, it was a nice, poorly formatted plain text email spit out by the system. Where's the love? Still, I was impressed that the system (hence somebody who programmed the system) bothered to send a note to let me know that the bug was confirmed and fixed.

I'm sure a million or more of my readers have already enjoyed this experience, but for those small few that have not, I thought I'd share. So don't hold back. When you find a bug in the framework or just want to complain, visit the Connect site and see what happens.

 

posted on Saturday, July 29, 2006 9:22:42 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]

I've spent months fighting with 3rd party components and my own hand rolled code that would allow me to achieve essentially the same thing you can with the HttpWebRequest class with one additional feature: binding a specific end point (IP address) to the object so that a remote server would recognize the call as coming from that specific IP address.

I looked through the description of each of the HttpWebRequest's members in the MSDN documentation. I searched the internet high and low. I banged my head against buggy third party components. And in desperation attempted to roll my own. All efforts resulted in a thorougly disappointing result.

Bring on the Delegates

Two days ago, I was chatting with a friend and I expressed my desperation. I told him I'd drive to his house and give him a fifty dollar bill if he could tell me how to use the HttpWebRequest object and assign or "bind" the local IP. He started digging. And I tried one last Google search using HttpWebRequest and IPEndPoint, I think it was, in the search. And I found this little gem about 5 seconds before my friend suggested taking a look at the HttpWebRequest's ServicePoint member and the ServicePoint's BindIPEndPointDelegate member.

Glory Hallelujah!

One of my new best friends is someone I don't know: Malar Chinnusamy. Thanks a million, Malar.

So to the point of the title of this little rant. It is the delegate stupid. The lesson learned is when you can't figure out how to do something with the .NET Framework, check out the delegates. And the delegates of the object's members. And so on...

public delegate IPEndPoint BindIPEndPoint(ServicePoint servicePoint,
  IPEndPoint remoteEndPoint, int retryCount);

That little gem is a beautiful thing. It lead to this:

private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint,
  IPEndPoint remoteEndPoint, int retryCount)
{
    if(retryCount < 3)
        return new IPEndPoint(IPAddress.Parse("192.168.10.60"), 0);
    else
        return new IPEndPoint(IPAddress.Any, 0);
}

and...

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.ServicePoint.BindIPEndPointDelegate =
  new BindIPEndPoint(BindIPEndPointCallback);

I told my friend that I wish I knew and understood everything in the framework. He said that he wished I knew it all too. So, when there's a shortage of helps and great blog posts out there, don't give up. Follow the delegates and you won't look as stupid as I felt once I found my new friend's post.

posted on Saturday, July 29, 2006 1:43:49 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Friday, July 07, 2006

I ran across the Consolas font from Microsoft today. I love it. I'd been using Courier New in 9pt and have now switched to Consolas 10pt. Much easier on the eyes. But not at first. It displayed quite poorly until I enabled ClearType in my display settings.

I've been using LCD monitors for a long time and why I've not switched to ClearType, I'll never know. It's like my glasses suddenly became more effective.

How many other cool things have I missed? One can never really know.

posted on Friday, July 07, 2006 2:04:53 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, June 15, 2006

I recently ordered something online. Let's hypothetically say it was a pair of glasses. I won't say which company because your experience will in all likelihood be better than mine. In point of fact, I have a crazy prescription that is hard to make and throws every optical lab for a loop the first time they see it.

Actually, I ordered two pairs. One pair was produced and arrived in a reasonable timeframe. The other has yet to arrive, hence my hesitance to name names. It's been weeks and weeks now. I would call and receive placating assurances that the matter would be looked into and that all would be resolved. I sent email nearly every other day inquirying. No answer. No status update. No way to look at the order status online--okay, yes that's partly my fault. Know before you press "confirm order."

So how did I solve this great quandry. Just a few lines of code which I will share below produced an emailed response within the hour. Have fun with it. Use it at your own risk. I take no responsibility for how you make yourself heard. And I've removed the identifying strings to avoid embarrassing the vendor and further endangering my order. BTW, their response was:

"We apologize for the inconvenience you experienced with us. We are remaking the glasses you ordered in our lab. You will receive them in about 10 days."

Here's the simple code:

using System;
using System.Collections.Generic;
using System.Text;

namespace
CrazyEmail
{
  class Program
  {
    static void Main(string[] args)
    {
       string n = Environment.NewLine;
       string nn = n + n;
       string body = "Hello," + nn
         + "I can think of no other way..." + nn
         + "Can you please respond..." + nn
         + "You can either..." + nn
         + "Thanks," + nn
         + "-Tyler";

       System.Net.Mail.MailMessage msg = 
         new System.Net.Mail.MailMessage("myemail@address.com", customer@service.com
         "order #xyz status inquiry"
, body);

       System.Net.Mail.SmtpClient client = 
         new System.Net.Mail.SmtpClient("mail.myserver.com"
);

       for (int i = 0; i < 100; i++)
       {
         client.Send(msg);
         Console.WriteLine(i.ToString());
       }

       Console.WriteLine("Done.");
       Console.ReadLine();
     }
  }
}

 

posted on Thursday, June 15, 2006 11:17:40 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Friday, May 12, 2006

In a recent project, I had a Windows Service that was receiving many thousands of requests which could only be processed at specific intervals. Soon I found that queuing so many requests in a simple Queue<T> class ran away with all my machine's memory.

So what to do?

I didn't really want to change my code. I like the Queue<T> class. So I wrote a class I call Hopper<T> which acts like Queue<T> but caches items to disk. It's constructor gives the class the information it needs to do all the work. Then you just use it like a Queue<T>.

public Hopper(
 
string cachePath,
 
string uniqueFileExtension,
 
int hopperCapacity,
 
int reorderLevel)

This class takes advantage of the System.Runtime.Serialization and the System.Runtime.Serialization.Formatters.Binary namespaces.

Download the code and give it a try. And be sure to let me know what you think.

Hopper.zip (2.74 KB)
posted on Friday, May 12, 2006 10:59:20 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, May 11, 2006

Recently I had to write an HTML parser for a project I've been working on for some time now. First I tried translating an open source C++ parser but it really wasn't what I wanted and it was also under the GPL. After contacting the author and realizing (or re-remembering) that I could not use a GPL derivative in a commercial library or application, I scrapped that and went back to the source: the official HTML DTD.

Re-remembering how to read a DTD after not having done so for so long was a chore, but the folks at Autistic Cuckoo helped. So I found a very helpful tutorial. I spent the next day or two writing the code in the file you linked below. I took some inspiration from a few files I found while browsing the FireFox code under the Mozilla license. The rest of it came from studying the DTD and trying to figure out a way to encapsulate that in a usable object model.

Here's an example of how to use it:

HtmlDocument doc = new HtmlDocument(url, html);
StringBuilder sb = new StringBuilder();
Collection<HtmlTag> pcdata = doc.GetList(DtdElement.A);
foreach (HtmlTag tag in pcdata)
{
  if (!tag.EndTag)
  {
    Dictionary<string, string> attributes = doc.GetAttributes(tag);
    sb.AppendLine("");
    sb.AppendLine("A: " + doc.ReadSlice(tag.Slice));

    foreach (KeyValuePair<string, string> pair in attributes)
    {
      sb.AppendLine(" " + pair.Key + "=" + pair.Value);
    }
  }
}

I'm releasing it under the BSD license, which I like much more than the GPL as I'm not really a "true" free software zealot. The only think I ask is that if you fix a bug or make an improvement, please share it with me and I'll put up a new version here.  

NetBrick.Net.OpenUtils1.zip (35.31 KB)
posted on Thursday, May 11, 2006 3:14:33 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Wednesday, March 08, 2006

I had to get an object serialized to a byte[] and then compress it using SharpZipLib and gzip and then decompress it and deserialize it to the original object. The serialization was easy but for some reason I was struggling with using the GZipOutputStream and GZipInputStream compression providers in the SharpZipLib library.

Then I found Scott Galloway's compression helper. I highly recommend it. Anyway, here's the code without the helper. Visit Scott's blog for that.

 public class ResultSerializer
 {
  public static byte[] Serialize(ResultData data)
  {
   //convert to byte[]
   IFormatter frm = new BinaryFormatter();
   MemoryStream ms = new MemoryStream(8096);
   frm.Serialize(ms, data);
   byte[] serial = ms.ToArray();
   ms.Close();
   byte[] retval = ZipUtil.Compress(serial);
   return retval;
  }
  public static ResultData Deserialize(byte[] zipData)
  {
   byte[] data = ZipUtil.DeCompress(zipData);
   //now deserialize
   IFormatter frm = new BinaryFormatter();
   MemoryStream datams = new MemoryStream(data, 0, data.Length);
   ResultData retval = (ResultData)frm.Deserialize(datams);
   return retval;
  }
 }

Note that I renamed Scott's helper "ZipUtil" for my own reasons.

posted on Wednesday, March 08, 2006 3:05:47 PM (Mountain Standard Time, UTC-07:00)  #    Comments [1]
# Wednesday, February 22, 2006

I'm creating a .NET 2.0 ASP.NET web service as a front end to several Windows Services (also built using .NET 2.0) and want to use IPC since the web service and the Windows Services will be running on the same machine.

I don't want to use XML configuration files. I want to do it in code. It works with a console app to the Windows Service, but the ASP.NET web service blows chunks.

Failed to connect to an IPC port:  Access Denied

Search. Search. Search. One clue about "authorizedGroup" = "Everyone" but no code. Tinker. Stumble. Search. Tinker. Finally. Here's the final result in the Windows Service server:

Dictionary<string, string> props = new Dictionary<string, string>();
props.Add("authorizedGroup", "Everyone");
props.Add("portName", "ServerPortName");
serverChannel = new IpcServerChannel(props, null);
ChannelServices.RegisterChannel(serverChannel, true);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalByRefObjectSubClass),
   "ServerAppName", WellKnownObjectMode.SingleCall);
serverChannel.StartListening(null);

With the client setup like this in the web service:

using System;
using System.Data;
using System.Configuration;
using System.Threading;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using MyRemotingInterfaces;

public class RemotingClientFactory
{
   private static Mutex mut = new Mutex();
   private static WellKnownClientTypeEntry remoteEntry;
   private static IpcClientChannel remoteChannel;
   private static string remoteUrl = "ipc://RemoteExampleRemoteServer/RemoteExampleRemote";

   static RemotingClientFactory() { }

   public static IMyRemoteObject CreateRemote()
   {
      if (remoteChannel == null || remoteEntry == null)
      {
         mut.WaitOne();
         try
         {
            if (remoteChannel == null)
            {
               remoteChannel = new IpcClientChannel();
               ChannelServices.RegisterChannel(remoteChannel, true);
            }
            if (remoteEntry == null)
            {
               remoteEntry =
                 new WellKnownClientTypeEntry(typeof(MyRemotingInterfaces.IMyRemoteObject),
                       remoteUrl);
               RemotingConfiguration.RegisterWellKnownClientType(remoteEntry);
            }
         }
         finally
         {
            mut.ReleaseMutex();
         }
      }
      try
      {
         IMyRemoteObject obj =
          
(IRemoteExampleRemote)Activator.GetObject(remoteEntry.ObjectType, remoteUrl);
         return obj;
      }
      catch(Exception e)
      {
         //TODO log then rethrow
         throw e;
      }
   }
}

And it works like a charm. It's not perfect, I'm sure. But it's a start. And it didn't seem like anyone had or wanted to post their solution to the newsgroups or anywhere else I could find.

Let me know if you find a better way or if this helps you. And good luck.

posted on Wednesday, February 22, 2006 10:02:44 AM (Mountain Standard Time, UTC-07:00)  #    Comments [9]
# Tuesday, February 14, 2006

I know this problem has been solved many times and written about many times, but every time I go to create a new Windows Service project, I end up re-researching how to debug and step through code in a Windows Service project in Visual Studio.

I've done it now, again, building my first real set of Windows Service projects in Visual Studio 2005 and this time I took the compiler directive approach. It's been done before, sure, and many have written about it, but for my own short term memory's sake, here's my solution.

Step One
Create the Windows Service project using the New Project wizard and the Windows Service template.

Step Two
Modify the nicely created program.cs file as follows:

using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
#if (DEBUG)
   class Program
#else
   static class Program
#endif
   {
      /// 
      /// The main entry point for the application.
      /// 
#if (DEBUG)
      static void Main(string[] args)
#else
      static void Main()
#endif
      {
#if (DEBUG)
         ServiceRunner sr = new ServiceRunner();
         sr.Start(args);
         Console.WriteLine("Started... Hit enter to stop...");
         Console.ReadLine();
         sr.Stop();
#else
         ServiceBase[] ServicesToRun;
         ServicesToRun = new ServiceBase[] { new Service1() };
         ServiceBase.Run(ServicesToRun);
#endif
      }
   }
}

Step Three
Modify the Service1.cs file as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
   public partial class Service1 : ServiceBase
   {
      private ServiceRunner serviceRunner = null;
      public Service1()
      {
         InitializeComponent();
         serviceRunner = new ServiceRunner();
      }

      protected override void OnStart(string[] args)
      {
         serviceRunner.Start(args);
      }

      protected override void OnStop()
      {
         serviceRunner.Stop();
      }
   }

   internal class ServiceRunner
   {
      public void Start(string[] args)
      {
         //TODO: Add code that will execute on start.
      }
      public void Stop()
      {
         //TODO: Add code that will execute on stop.
      }
   }
}

Step Four
Change the output type (in properties page of the project) to console application.

Now debug away!

posted on Tuesday, February 14, 2006 9:58:54 AM (Mountain Standard Time, UTC-07:00)  #    Comments [2]
# Friday, February 10, 2006

I recently ran into Richard Northedge's excellent article and C# rendition of the OpenNLP libraries as posted on Code Project. It's a fascinating toolset that presents common, ordinary coders like me with the opportunity to explore and build solutions previously the exclusive domain of guys with thick black plastic frames and lab coats.

I just wish I'd had this tool back in high school when the English teacher was having us waste our time diagramming sentences. But I doubt one could have stuffed this sort of code into a Commodore PET with 32K of RAM and a 4Khz 8 bit 6502 processor. Ah, those were the days. Life was simple. But not nearly so much fun as now.

I don't pretend to understand everything in the OpenNLP library, but I'm learning. Currently I'm exploring how this library might help me in search and content analysis for an ongoing project. As I learn more, I'll post more. For now, I'd love to hear from you if you've had any experience in building real-world applications using this library (even if it was the original java incantation).

posted on Friday, February 10, 2006 9:56:25 AM (Mountain Standard Time, UTC-07:00)  #    Comments [1]
# Tuesday, December 27, 2005

I wanted to play with the Amazon Alexa Web Search Platform (AWS) web service, so I fired up Visual Studio 2005 and created a new Windows Forms project. I then tried to add a web reference to the AWS url. The GUI interface to wsdl.exe threw up all over it, so I tried it manually after running the trusty sdkvars.bat to make sure my environment variables were set. Here's the result (not pretty):

------------------------------------------------------------------------------------------------------
c:\>wsdl /o:test.cs http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl
Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation. All rights reserved.
Error: There was an error processing 'http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl'.
- The document at the url http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl was not recognized as a known document type.

The error message from each known type may help you fix the problem:
- Report from 'DISCO Document' is 'Discovery document at the URL http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl could not be found.'.
- The document format is not recognized.
- Report from 'WSDL Document' is 'There is an error in XML document (140, 3).'.
- The element was not expected in this context: ... Expected elements: http://www.w3.org/2001/XMLSchema:include, http://www.w3.org/2001/XMLSchema:import, http://www.w3.org/2001/XMLSchema:redefine, http://www.w3.org/2001/XMLSchema:simpleType, http://www.w3.org/2001/XMLSchema:complexType, http://www.w3.org/2001/XMLSchema:annotation, http://www.w3.org/2001/XMLSchema:notation, http://www.w3.org/2001/XMLSchema:group, http://www.w3.org/2001/XMLSchema:element, http://www.w3.org/2001/XMLSchema:attribute, http://www.w3.org/2001/XMLSchema:attributeGroup.- Report from 'XML Schema' is 'The root element of a W3C XML Schema should be and its namespace should be 'http://www.w3.org/2001/XMLSchema'.'.

If you would like more help, please type "wsdl /?".
------------------------------------------------------------------------------------------------------

So I wondered how VS .NET 2003 would do with Amazon's WSDL. Changed directories to make sure I was running 1.1 of wsdl.exe and ran the same command line. It ran flawlessly. Here's the output:

------------------------------------------------------------------------------------------------------
c:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin>wsdl /o:test.cs http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl
Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 1.1.4322.573]
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Writing file 'test.cs'.
------------------------------------------------------------------------------------------------------

Opened VS .NET 2003 and created a little test project and it created the proxy just fine. I noticed that the WSDL file it created in the project was slightly different from the one downloaded directly from the Amazon URL. Specifically, the nodes with no namespace designation such as <definitions> and <types> now had a namespace prefix <wsdl:definitions> and <wsdl:types> along with the namespace declaration in the <definitions> node changed from xmlns="http://schemas.xmlsoap.org/wsdl/" to xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/".

I closed VS .NET 2003 and opened VS 2005. Now I used the "Add Web Reference" and referenced the local AlexaWebSearchPlatform.wsdl file that VS .NET 2003 had created. Now I have a proxy that at least compiles, but of course it does not reference the Amazon URL directly so update web reference will not work.

I'll start testing using the 2003 to 2005 proxy generated class and report back tomorrow on how well it worked. Meantime, if anyone can tell me how to get the wsdl.exe for .NET 2.0 to behave, I'd appreciate it.

posted on Tuesday, December 27, 2005 9:55:32 AM (Mountain Standard Time, UTC-07:00)  #    Comments [2]
# Saturday, December 10, 2005

I spent a few hours this week exploring DNN 4.0 and the team's effort to transform the successful 3.x version into the ASP.NET 2.0 mold. I congratulate the team. They had a lot of work to do and I found the installation and setup easy and the module template is a joy.

Of course, I wish they had chosen C# but that's my own bias. The beauty is that you can add a C# module using the module template right into the DNN web application. Everything seems to work as advertised, EXCEPT...

Open the C# module code generated by the template and right-click on an class name that's part of the DNN source code and select the "Go to Definition" menu option. Hey, where did the code go. I get a C# [meta data] file just like I would with a BCL class rather than the object browser. EXCEPT there is really code available but it's VB.NET.

So I have my first complaint about VS 2005. I'm hoping a reader can help me find the solution. In a mixed language solution, why doesn't the real code open up? Is this a bug or am I missing some configuration thing? First person to help me find the solution get's a $20 Amazon gift certificate, unless I post the solution here first.

One way or the other, I like DNN 4.0 a lot. Sure there's more comprehensive portal and content management systems available, but definitely not for the price. I'm sure I'll run into more trouble as I roll down the .NET 2.0 road, but so far, it's been a lot of fun. Here's to more of it.

posted on Saturday, December 10, 2005 9:53:54 AM (Mountain Standard Time, UTC-07:00)  #    Comments [2]
# Thursday, November 03, 2005

I've had VS.NET 2005 and SQL Server 2005 installed for a couple of days now. Thanks to the MSDN subscription site. So far, I'm very impressed. The question remains how and when do we make the move. I say, run with the scissors.

The cutting edge, if you can define this as cutting edge, is not quite as sharp as one might think given we've been through beta one and two and the community technology previews (CTP). But for those of you who did install the betas (and by what I've read and heard there are thousands of you), be warned! The SQL Server install is a pain if it detects any whiff of beta. I was finally successful after uninstalling even the previous .NET frameworks.

That said, I'm still recommending running with the scissors. Okay, well, walk quickly anyway. Plan to migrate as quickly as possible without totally disrupting your current development paths. Here's my list of reasons to do it. I'm sure there's many more, but it's a start.

ADO.NET

  • Bulk updates: 1,000,000 row insert for 1.1: 30 minutes; for 2.0: 45 seconds
  • Dataset binary serialization in remoting: faster DS over the wire (up to 6 times smaller)
  • DataTable now supports XML read, write, schema, merge, load
  • DataView.ToTable method allows creation of a new DataTable from a view

C# 2.0

  • Generics: generic class later cast to a specific type. Collections are the best example: a list of some type: List<someType>
  • Anonymous methods: allows code to be passed as a parameter rather than requiring a delegate
  • Partial classes: allows a class to be defined and worked on in two or more files

ASP.NET

  • AJAX: direct support for asynchronous javascript calls to the server with javascript generation automated and easy event handling in the code-behind code of the page.
  • Master pages: allows visual inheritance or a base class page
  • DataSource & ObjectDataSource allow easier binding to data aware controls

Visual Studio .NET 2005

  • Click-Once deployment of smart client
  • Editor: improved color coding and intellisense
  • Debugger will suggest potential problem areas
  • Warnings suggesting specific replacements for code that uses deprecated or obsolete framework objects
  • Debugger allows data visualization: view a dataset in a grid while debugging
  • Conversion of previous VS.NET projects easy, automated, informative reports

SQL Server 2005

  • PIVOT/UNPIVOT allows rows and column rotation
  • APPLY allows use of a UDF in a FROM clause to create a result set with calculated columns
  • TRY/CATCH allows more granular exception handling
  • CTE (Common Table Expressions) allow the creation of a recursive query to produce a hierarchical resultset
  • CLR integration allows stored procedures to be written in C#
posted on Thursday, November 03, 2005 10:51:53 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, October 27, 2005

I enjoy reading Fawcette publications online as one source of industry information, but sometimes for plain old amusement. A recent article with an author byline that begins "by by" did a relatively decent job of comparing J2EE and .NET with a fair bit of praise for ASP.NET, especially in the much anticipated 2.0 incarnation.

The amusement part began with the author's constant reference to ASP.NET as ASP. This is a clear and dead give away that the author has either never used both or has absolutely no pride. I will not pretend to make a comparison of ASP.NET and JSP because I really don't have any real experience with JSP. I have friends that do, and they like it well enough, and that's good enough for me to assume that you can get done what you need to get done in JSP, JSF, etc.

And there have been reams of paper and billions of bytes wasted on enumerating the differences between what is now generally referred to, by those who have been there, as "classic ASP" and ASP.NET. Let me just waste the following words for the author and my Java friends: ASP.NET IS NOT ASP. The only real thing shared between the two is the <% %> tag markers. And just for the record, ASP 2.0 was a long time ago.

ASP.NET is like the guy with Jr. following his name who just knows he turned out so much better than his dad and wonders to himself why the old man thought so much of himself that he had to go and give him the same name.

And the real ASP.NET 2.0 is just days away. I'm like a kid looking in at the candy store, just waiting for doors to open.

And no, I'm not going to give you a link to the story. Like the byline suggested, the story should go bye bye.

posted on Thursday, October 27, 2005 9:50:10 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, October 22, 2005

Things have been a bit crazy. Actually, more like 32 bits of crazy. At least. I registered for the VS.NET 2005 product launch with excitement. They were giving away a free copy of VS.NET 2005 Pro and SQL Server 2005 Standard. I told all my friends and they signed up with the same excitement. Then the "we made a mistake" bait-n-switch email arrived.

"...there may have been an inaccurate reference on our website when you registered..."

Come on... Who wants a Standard version when you profess to be a pro and really need the Pro version? Sorry, "edition." And yet, I'm still going.

But for those of you who would rather have all the cool stuff but can't afford the MSDN Universal subscription price, there's always Empower. If you are starting a little company (your "on the side project business") and you need tools, the best way to get them, honestly, is through the Microsoft Empower for ISVs program.

Why two links? Because it's really the best deal out there. You get media. You get download access. You get managed support newsgroups and 10 hours of advisory service. Not bad for only $375.

ONLY $375

No. I haven't bought mine yet. But I plan to. Just as soon as the chairperson of the budget committee releases the funds. My wife's a reasonable person, so I expect that to happen soon. Before the launch event in my area anyway.

It was an honest mistake I'm sure. But would it have really hurt so bad to just give out what was originally promised? It's really not a bad idea. Get all the geeks in the neighborhood to use the latest and greatest at home, and when they all go work, they'll be begging for a corporate copy so they don't have to take a step back. Let's face it, there is some way cool things in .NET 2.0. and a hundred blogs or more for each of them.

But really, Bill, don't you think the mistake would have been fortuitous? But now you just kind of look like a stingy dork--"an inaccurate reference," yeah, right. Why don't you surprise all of us still willing to come out for a standard copy and give us a pro copy as a reward for our loyalty. Now that would be cool.

posted on Saturday, October 22, 2005 9:44:17 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Thursday, June 23, 2005

Yesterday I received my copy of CODE magazine with an article by Christian Weyer covering contract first web service design and his free tool WSCF (web service contract first) for Visual Studio .NET. After a few bumpy stumbles because I was reading and following examples at 2am, I got a nice example up and running.

All I can say is: TOTALLY AWESOME!

This is the way web services, especially complex services that require complete platform independence, should be built. The common [WebMethod] asmx approach in VS .NET works for small projects and quick and dirty prototypes, but to build serious web services in a service oriented architecture (SOA), you should really consider taking Christian's advice and design by schema and contract first.

Anyone building web services owes it to themselves to try this free tool.

posted on Thursday, June 23, 2005 9:40:35 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Wednesday, June 15, 2005

Some time ago I was working on a web site where we wanted to have a good rollover button control for ASP.NET in our projects that would eliminate the need for client-side script. Google search turned up a post that I've since lost that discussed using CSS for rollover of a button image with all states of the button in one image.

Using CSS and custom ASP.NET controls, this little project gives you a highly useful fixed width label control and a button control with three states and automatic rollovers without having to write a single line of javascript and without having to manage multiple image files for one button.

The FixedWidth label uses a CSS button and a little GDI+ to measure the length of the label text and truncate the text if necessary to fit it within the specified width. It then adds an elipsis button (you control the button as well) to which a javascript alert with the full string is hooked.

Download the source code and use these controls as you will. In it you'll find the control project and a test/example project to show you how to use it. If you find it useful and/or make changes/improvements to it, I'd love to hear from you and see what you've done with it.

CssWebControls.zip (45.1 KB)
posted on Wednesday, June 15, 2005 9:38:07 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]