<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>tsJensen.com - Code</title>
    <link>http://www.tsjensen.com/blog/</link>
    <description />
    <language>en-us</language>
    <copyright>Tyler Jensen</copyright>
    <lastBuildDate>Thu, 13 May 2010 20:39:41 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8139.823</generator>
    <managingEditor>tyler@tsjensen.com</managingEditor>
    <webMaster>tyler@tsjensen.com</webMaster>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=9a413d75-82de-472e-b2d4-40f4d190b28a</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,9a413d75-82de-472e-b2d4-40f4d190b28a.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,9a413d75-82de-472e-b2d4-40f4d190b28a.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9a413d75-82de-472e-b2d4-40f4d190b28a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I extended a <a href="http://www.tsjensen.com/blog/2010/03/29/WCF+Plugin+Architecture+For+NET+Windows+Service+With+Easy+Debug+Console+Mode.aspx">previous
blog post</a> and published it on Code Project under the title <a href="http://www.codeproject.com/KB/WCF/GenericWcfServiceHostAndC.aspx">Generic
WCF Service Host and Client</a>. An astute reader asked about calling a service method
asynchronously, something I had not given much thought.
</p>
        <p>
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.
</p>
        <p>
So I went to work experimenting. If you want the WCF version of the solution, visit
the <a href="http://www.codeproject.com/KB/WCF/GenericWcfServiceHostAndC.aspx">Code
Project article</a> and you can get the updated code there just as soon as I get an
update published.
</p>
        <p>
In this post, I'll present a more generalized version of the solution I created. The
GenericAsyncWrapper&lt;T&gt; class is the heart of the solution. Take any instance
of T (any class) and GenericAsyncWrapper&lt;T&gt; puts an event based asynchronous
wrapper that allows you to call any method on the instance asynchronously.
</p>
        <p>
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 <a href="http://support.microsoft.com/kb/315582">How
to call a Visual C# method asynchronously</a> 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.
</p>
        <p>
Here's my test class. It does nothing, as you can see, but it does allow me to test
my wrapper.
</p>
        <pre class="brush: c-sharp;" name="code">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.";
  }
}</pre>
        <p>
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.
</p>
        <pre class="brush: c-sharp;" name="code">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&lt;&gt; and Func&lt;&gt; delgate calls");
    Action action = new Action(mytest.DoNothingNoParams);
    action.BeginInvoke(new AsyncCallback(ActionCallback), "test1");

    Func&lt;string, string&gt; func = new Func&lt;string, string&gt;(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&lt;MyTestClass&gt;(mytest);
    wrapper.AsyncCompleted += new EventHandler&lt;GenericAsyncWrapperCompletedEventArgs&gt;(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&lt;object, object&gt; deleg = ((AsyncResult)result).AsyncDelegate as Func&lt;object, object&gt;;
    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 &lt; e.InValues.Length; i++)
        {
          Console.WriteLine("   value[{0}] = {1}", i, e.InValues[i]);
        }
      }
    }
    else
    {
      Console.WriteLine(e.Error.ToString());
    }
  }
}</pre>
        <p>
Now here's the real magic. The GenericAsyncWrapper&lt;T&gt; class and its attendant
event args class.
</p>
        <pre class="brush: c-sharp;" name="code">public class GenericAsyncWrapper&lt;T&gt; 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&lt;GenericAsyncWrapperCompletedEventArgs&gt; 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&lt;MethodInfo, object[], object&gt; func = new Func&lt;MethodInfo, object[], object&gt;(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&lt;MethodInfo, object[], object&gt;)((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; }
}</pre>
        <p>
You can download the code here <a href="http://www.tsjensen.com/blog/content/binary/GenericUtils.zip">GenericUtils.zip
(7.33 KB)</a>. 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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=9a413d75-82de-472e-b2d4-40f4d190b28a" />
      </body>
      <title>Generic Asynchronous Wrapper for .NET</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,9a413d75-82de-472e-b2d4-40f4d190b28a.aspx</guid>
      <link>http://www.tsjensen.com/blog/2010/05/13/Generic+Asynchronous+Wrapper+For+NET.aspx</link>
      <pubDate>Thu, 13 May 2010 20:39:41 GMT</pubDate>
      <description>&lt;p&gt;
Recently I extended a &lt;a href="http://www.tsjensen.com/blog/2010/03/29/WCF+Plugin+Architecture+For+NET+Windows+Service+With+Easy+Debug+Console+Mode.aspx"&gt;previous
blog post&lt;/a&gt; and published it on Code Project under the title &lt;a href="http://www.codeproject.com/KB/WCF/GenericWcfServiceHostAndC.aspx"&gt;Generic
WCF Service Host and Client&lt;/a&gt;. An astute reader asked about calling a service method
asynchronously, something I had not given much thought.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
So I went to work experimenting. If you want the WCF version of the solution, visit
the &lt;a href="http://www.codeproject.com/KB/WCF/GenericWcfServiceHostAndC.aspx"&gt;Code
Project article&lt;/a&gt; and you can get the updated code there just as soon as I get an
update published.
&lt;/p&gt;
&lt;p&gt;
In this post, I'll present a more generalized version of the solution I created. The
GenericAsyncWrapper&amp;lt;T&amp;gt; class is the heart of the solution. Take any instance
of T (any class) and GenericAsyncWrapper&amp;lt;T&amp;gt; puts an event based asynchronous
wrapper that allows you to call any method on the instance asynchronously.
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://support.microsoft.com/kb/315582"&gt;How
to call a Visual C# method asynchronously&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
Here's my test class. It does nothing, as you can see, but it does allow me to test
my wrapper.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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.";
  }
}&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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&amp;lt;&gt; and Func&amp;lt;&gt; delgate calls");
    Action action = new Action(mytest.DoNothingNoParams);
    action.BeginInvoke(new AsyncCallback(ActionCallback), "test1");

    Func&amp;lt;string, string&gt; func = new Func&amp;lt;string, string&gt;(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&amp;lt;MyTestClass&gt;(mytest);
    wrapper.AsyncCompleted += new EventHandler&amp;lt;GenericAsyncWrapperCompletedEventArgs&gt;(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&amp;lt;object, object&gt; deleg = ((AsyncResult)result).AsyncDelegate as Func&amp;lt;object, object&gt;;
    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 &amp;lt; e.InValues.Length; i++)
        {
          Console.WriteLine("   value[{0}] = {1}", i, e.InValues[i]);
        }
      }
    }
    else
    {
      Console.WriteLine(e.Error.ToString());
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
Now here's the real magic. The GenericAsyncWrapper&amp;lt;T&amp;gt; class and its attendant
event args class.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;public class GenericAsyncWrapper&amp;lt;T&gt; 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&amp;lt;GenericAsyncWrapperCompletedEventArgs&gt; 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&amp;lt;MethodInfo, object[], object&gt; func = new Func&amp;lt;MethodInfo, object[], object&gt;(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&amp;lt;MethodInfo, object[], object&gt;)((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; }
}&lt;/pre&gt;
&lt;p&gt;
You can download the code here &lt;a href="http://www.tsjensen.com/blog/content/binary/GenericUtils.zip"&gt;GenericUtils.zip
(7.33 KB)&lt;/a&gt;. 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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=9a413d75-82de-472e-b2d4-40f4d190b28a" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,9a413d75-82de-472e-b2d4-40f4d190b28a.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=f1d610ad-b6cc-4a4f-a651-a24b19b3733a</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,f1d610ad-b6cc-4a4f-a651-a24b19b3733a.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,f1d610ad-b6cc-4a4f-a651-a24b19b3733a.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f1d610ad-b6cc-4a4f-a651-a24b19b3733a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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?).
</p>
        <p>
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 <strong>most importantly</strong> 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.
</p>
        <p>
Start with the <strong>AppManifest.xaml</strong> (in Dinorythm.xap) 
<br />
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 <a href="http://weblogs.asp.net/scottgu/archive/2010/04/15/silverlight-4-released.aspx">Silverlight
4 Released</a> blog post).
</p>
        <pre class="brush: xml;" name="code">&lt;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"&gt;
  &lt;Deployment.Parts&gt;
    &lt;AssemblyPart x:Name="Dinorythm" Source="Dinorythm.dll" /&gt;
    &lt;AssemblyPart x:Name="DinoContracts" Source="DinoContracts.dll" /&gt;
    &lt;AssemblyPart x:Name="System.ComponentModel.DataAnnotations" Source="System.ComponentModel.DataAnnotations.dll" /&gt;
    &lt;AssemblyPart x:Name="System.ServiceModel.DomainServices.Client" Source="System.ServiceModel.DomainServices.Client.dll" /&gt;
    &lt;AssemblyPart x:Name="System.ServiceModel.DomainServices.Client.Web" Source="System.ServiceModel.DomainServices.Client.Web.dll" /&gt;
    &lt;AssemblyPart x:Name="System.ServiceModel.Web.Extensions" Source="System.ServiceModel.Web.Extensions.dll" /&gt;
    &lt;AssemblyPart x:Name="System.Windows.Controls" Source="System.Windows.Controls.dll" /&gt;
    &lt;AssemblyPart x:Name="System.Windows.Controls.Navigation" Source="System.Windows.Controls.Navigation.dll" /&gt;
  &lt;/Deployment.Parts&gt;
&lt;/Deployment&gt;</pre>
        <p>
 
</p>
        <p>
          <strong>DinoContracts</strong> a Silverlight 4 Class Library (in Dinorythm.xap). 
<br />
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.
</p>
        <pre class="brush: c-sharp;" name="code">namespace DinoContracts
{
  public interface IMySecretCode
  {
    string DoSecretWork(string input);
  }
}</pre>
        <p>
 
</p>
        <p>
          <strong>SecretAlgorithms</strong> a Silverlight 4 Class Library (<strong>NOT</strong> in
Dinorythm.xap)<br />
This library has a project reference to DinoContracts and copies it's output to the
Dynorythm.Web/App_Data folder.
</p>
        <pre class="brush: c-sharp;" name="code">namespace SecretAlgorithms
{
  public class MySecretCode : IMySecretCode
  {
    public string DoSecretWork(string input)
    {
      return "results of my secret code";
    }
  }
}</pre>
        <p>
 
</p>
        <p>
          <strong>Dinorythm.Web</strong> an ASP.NET MVC 2 project<br />
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.
</p>
        <pre class="brush: c-sharp;" name="code">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;
    }
  }
}</pre>
        <p>
 
</p>
        <p>
          <strong>Dinorythm</strong> a Silverlight 4 Navigation Application<br />
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.
</p>
        <pre class="brush: c-sharp;" name="code">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";
    }
  }
}</pre>
        <p>
Help credits go to Tim Heuer for some comparison with <a href="http://timheuer.com/blog/archive/2009/07/13/silverlight-3-cached-assembly-feature.aspx">cached
assemblies</a> and to the practical help from a <a href="http://blogs.silverlight.net/blogs/msnow/archive/2009/01/21/silverlight-tip-of-the-day-84-how-to-dynamically-load-a-control-from-a-dll.aspx">Silverlight
Tip of the Day</a>.
</p>
        <p>
          <strong>A Note About Security:</strong> 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.)
</p>
        <p>
If you find this code useful, I'd love to hear from you. Download <a href="http://www.tsjensen.com/blog/content/binary/Dinorythm.zip">Dinorythm.zip
(313.34 KB)</a> here.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f1d610ad-b6cc-4a4f-a651-a24b19b3733a" />
      </body>
      <title>Prevent Reflection and Disassembly of Silverlight Class Libary Code</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,f1d610ad-b6cc-4a4f-a651-a24b19b3733a.aspx</guid>
      <link>http://www.tsjensen.com/blog/2010/04/21/Prevent+Reflection+And+Disassembly+Of+Silverlight+Class+Libary+Code.aspx</link>
      <pubDate>Wed, 21 Apr 2010 03:17:49 GMT</pubDate>
      <description>&lt;p&gt;
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?).
&lt;/p&gt;
&lt;p&gt;
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 &lt;strong&gt;most importantly&lt;/strong&gt; 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.
&lt;/p&gt;
&lt;p&gt;
Start with the &lt;strong&gt;AppManifest.xaml&lt;/strong&gt; (in Dinorythm.xap) 
&lt;br /&gt;
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 &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/04/15/silverlight-4-released.aspx"&gt;Silverlight
4 Released&lt;/a&gt; blog post).
&lt;/p&gt;
&lt;pre class="brush: xml;" name="code"&gt;&amp;lt;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"&gt;
  &amp;lt;Deployment.Parts&gt;
    &amp;lt;AssemblyPart x:Name="Dinorythm" Source="Dinorythm.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="DinoContracts" Source="DinoContracts.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="System.ComponentModel.DataAnnotations" Source="System.ComponentModel.DataAnnotations.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="System.ServiceModel.DomainServices.Client" Source="System.ServiceModel.DomainServices.Client.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="System.ServiceModel.DomainServices.Client.Web" Source="System.ServiceModel.DomainServices.Client.Web.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="System.ServiceModel.Web.Extensions" Source="System.ServiceModel.Web.Extensions.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="System.Windows.Controls" Source="System.Windows.Controls.dll" /&gt;
    &amp;lt;AssemblyPart x:Name="System.Windows.Controls.Navigation" Source="System.Windows.Controls.Navigation.dll" /&gt;
  &amp;lt;/Deployment.Parts&gt;
&amp;lt;/Deployment&gt;&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DinoContracts&lt;/strong&gt; a Silverlight 4 Class Library (in Dinorythm.xap). 
&lt;br /&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;namespace DinoContracts
{
  public interface IMySecretCode
  {
    string DoSecretWork(string input);
  }
}&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;SecretAlgorithms&lt;/strong&gt; a Silverlight 4 Class Library (&lt;strong&gt;NOT&lt;/strong&gt; in
Dinorythm.xap)&lt;br /&gt;
This library has a project reference to DinoContracts and copies it's output to the
Dynorythm.Web/App_Data folder.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;namespace SecretAlgorithms
{
  public class MySecretCode : IMySecretCode
  {
    public string DoSecretWork(string input)
    {
      return "results of my secret code";
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Dinorythm.Web&lt;/strong&gt; an ASP.NET MVC 2 project&lt;br /&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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;
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Dinorythm&lt;/strong&gt; a Silverlight 4 Navigation Application&lt;br /&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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";
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
Help credits go to Tim Heuer for some comparison with &lt;a href="http://timheuer.com/blog/archive/2009/07/13/silverlight-3-cached-assembly-feature.aspx"&gt;cached
assemblies&lt;/a&gt; and to the practical help from a &lt;a href="http://blogs.silverlight.net/blogs/msnow/archive/2009/01/21/silverlight-tip-of-the-day-84-how-to-dynamically-load-a-control-from-a-dll.aspx"&gt;Silverlight
Tip of the Day&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;A Note About Security:&lt;/strong&gt; 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.)
&lt;/p&gt;
&lt;p&gt;
If you find this code useful, I'd love to hear from you. Download &lt;a href="http://www.tsjensen.com/blog/content/binary/Dinorythm.zip"&gt;Dinorythm.zip
(313.34 KB)&lt;/a&gt; here.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f1d610ad-b6cc-4a4f-a651-a24b19b3733a" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,f1d610ad-b6cc-4a4f-a651-a24b19b3733a.aspx</comments>
      <category>Code</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=ebf0f909-a38b-439b-846c-46e08a8d1289</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,ebf0f909-a38b-439b-846c-46e08a8d1289.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,ebf0f909-a38b-439b-846c-46e08a8d1289.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ebf0f909-a38b-439b-846c-46e08a8d1289</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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:
</p>
        <pre class="brush: c-sharp;" name="code">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; }
  }
}</pre>
        <p>
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 (<a href="http://www.tsjensen.com/blog/content/binary/PluggableWcfServiceHost.zip">download
PluggableWcfServiceHost.zip (38.05 KB)</a>):
</p>
        <ul>
          <li>
Fast net.tcp binding</li>
          <li>
Windows credentials and authentication</li>
          <li>
Encrypted and signed transport (no packet sniffing allowed)</li>
          <li>
Simplified configuration (hide everything I don't want to see)</li>
          <li>
Windows Service host that behaves like a Console app when I'm debugging</li>
          <li>
Dynamic loading of the service (no changes to the host code to add a new service)</li>
          <li>
Generic client so I don't have to write or generate proxy code</li>
          <li>
Client that is truly IDisposable (hide Abort vs Close for me)</li>
          <li>
Long timeout in DEBUG mode so I can really take my time while debugging</li>
          <li>
Inclusion of exception details in DEBUG mode only</li>
          <li>
Base service class with a simple Authorize method to support multiple Windows groups</li>
          <li>
Support for multiple Windows group authorization</li>
          <li>
Identical configuration for server and client</li>
          <li>
Cached resolution of service plugin service and contract types</li>
          <li>
Minimal number of assemblies (projects) in the solution</li>
          <li>
Keep the implementation of the service hidden from the client</li>
          <li>
(Probably some I've forgotten to mention)</li>
        </ul>
        <p>
Here's the simplified config with two services configured:
</p>
        <pre class="brush: xml;" name="code">&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;configuration&gt;
  &lt;configSections&gt;
    &lt;section name="wcfServices" 
          type="WcfServiceCommon.WcfServiceConfigurationSection, WcfServiceCommon" /&gt;
  &lt;/configSections&gt;
  &lt;appSettings/&gt;
  &lt;connectionStrings/&gt;
  &lt;wcfServices consoleMode="On"&gt;
    &lt;services&gt;
      &lt;add key="test1"
          serviceAddressPort="localhost:2981"
          endpointName="Test1EndPoint"
          authorizedGroups="WcfServiceClients,someOtherGoup"
          hostType="Test1Service.ThatOneService, Test1Service"
          contractType="Test1Common.IThatOneService, Test1Common" /&gt;
      &lt;add key="test2"
          serviceAddressPort="localhost:2981"
          endpointName="Test2EndPoint"
          authorizedGroups="WcfServiceClients,someOtherGoup"
          hostType="Test2Service.MyOtherService, Test2Service"
          contractType="Test2Common.IMyOtherService, Test2Common" /&gt;
    &lt;/services&gt;
  &lt;/wcfServices&gt;
&lt;/configuration&gt;</pre>
        <p>
And here's the implementation of the service (It really is simple):
</p>
        <pre class="brush: c-sharp;" name="code">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" };
    }
  }
}</pre>
        <p>
Now for the really fun part. The client. Hey, where's the proxy? Hidden away just
like it ought to be.
</p>
        <pre class="brush: c-sharp;" name="code">namespace WcfSvcTest
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var client1 = WcfServiceClient&lt;IThatOneService&gt;.Create("test1"))
      {
        Console.WriteLine(client1.Instance.GetName("seed"));
        var add = client1.Instance.GetAddress(8);
        Console.WriteLine("{0}", add.City);
      }

      using (var client2 = WcfServiceClient&lt;IMyOtherService&gt;.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&lt;WcfServiceFault&gt; fault)
        {
          Console.WriteLine(fault.ToString());
        }
        catch (Exception e) //handles exceptions not in wcf communication
        {
          Console.WriteLine(e.ToString());
        }
      }

      Console.ReadLine();
    }
  }
}</pre>
        <p>
To save space, I only wrapped the use of the client in try catch on the second test
service.
</p>
        <p>
          <strong>Note:</strong> 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.
</p>
        <p>
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.
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/PluggableWcfServiceHost.zip">Download
PluggableWcfServiceHost.zip (38.05 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ebf0f909-a38b-439b-846c-46e08a8d1289" />
      </body>
      <title>WCF Plugin Architecture for .NET Windows Service with Easy Debug Console Mode</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,ebf0f909-a38b-439b-846c-46e08a8d1289.aspx</guid>
      <link>http://www.tsjensen.com/blog/2010/03/29/WCF+Plugin+Architecture+For+NET+Windows+Service+With+Easy+Debug+Console+Mode.aspx</link>
      <pubDate>Mon, 29 Mar 2010 02:58:40 GMT</pubDate>
      <description>&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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; }
  }
}&lt;/pre&gt;
&lt;p&gt;
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 (&lt;a href="http://www.tsjensen.com/blog/content/binary/PluggableWcfServiceHost.zip"&gt;download
PluggableWcfServiceHost.zip (38.05 KB)&lt;/a&gt;):
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Fast net.tcp binding&lt;/li&gt;
&lt;li&gt;
Windows credentials and authentication&lt;/li&gt;
&lt;li&gt;
Encrypted and signed transport (no packet sniffing allowed)&lt;/li&gt;
&lt;li&gt;
Simplified configuration (hide everything I don't want to see)&lt;/li&gt;
&lt;li&gt;
Windows Service host that behaves like a Console app when I'm debugging&lt;/li&gt;
&lt;li&gt;
Dynamic loading of the service (no changes to the host code to add a new service)&lt;/li&gt;
&lt;li&gt;
Generic client so I don't have to write or generate proxy code&lt;/li&gt;
&lt;li&gt;
Client that is truly IDisposable (hide Abort vs Close for me)&lt;/li&gt;
&lt;li&gt;
Long timeout in DEBUG mode so I can really take my time while debugging&lt;/li&gt;
&lt;li&gt;
Inclusion of exception details in DEBUG mode only&lt;/li&gt;
&lt;li&gt;
Base service class with a simple Authorize method to support multiple Windows groups&lt;/li&gt;
&lt;li&gt;
Support for multiple Windows group authorization&lt;/li&gt;
&lt;li&gt;
Identical configuration for server and client&lt;/li&gt;
&lt;li&gt;
Cached resolution of service plugin service and contract types&lt;/li&gt;
&lt;li&gt;
Minimal number of assemblies (projects) in the solution&lt;/li&gt;
&lt;li&gt;
Keep the implementation of the service hidden from the client&lt;/li&gt;
&lt;li&gt;
(Probably some I've forgotten to mention)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Here's the simplified config with two services configured:
&lt;/p&gt;
&lt;pre class="brush: xml;" name="code"&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&gt;
&amp;lt;configuration&gt;
  &amp;lt;configSections&gt;
    &amp;lt;section name="wcfServices" 
          type="WcfServiceCommon.WcfServiceConfigurationSection, WcfServiceCommon" /&gt;
  &amp;lt;/configSections&gt;
  &amp;lt;appSettings/&gt;
  &amp;lt;connectionStrings/&gt;
  &amp;lt;wcfServices consoleMode="On"&gt;
    &amp;lt;services&gt;
      &amp;lt;add key="test1"
          serviceAddressPort="localhost:2981"
          endpointName="Test1EndPoint"
          authorizedGroups="WcfServiceClients,someOtherGoup"
          hostType="Test1Service.ThatOneService, Test1Service"
          contractType="Test1Common.IThatOneService, Test1Common" /&gt;
      &amp;lt;add key="test2"
          serviceAddressPort="localhost:2981"
          endpointName="Test2EndPoint"
          authorizedGroups="WcfServiceClients,someOtherGoup"
          hostType="Test2Service.MyOtherService, Test2Service"
          contractType="Test2Common.IMyOtherService, Test2Common" /&gt;
    &amp;lt;/services&gt;
  &amp;lt;/wcfServices&gt;
&amp;lt;/configuration&gt;&lt;/pre&gt;
&lt;p&gt;
And here's the implementation of the service (It really is simple):
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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" };
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
Now for the really fun part. The client. Hey, where's the proxy? Hidden away just
like it ought to be.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;namespace WcfSvcTest
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var client1 = WcfServiceClient&amp;lt;IThatOneService&gt;.Create("test1"))
      {
        Console.WriteLine(client1.Instance.GetName("seed"));
        var add = client1.Instance.GetAddress(8);
        Console.WriteLine("{0}", add.City);
      }

      using (var client2 = WcfServiceClient&amp;lt;IMyOtherService&gt;.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&amp;lt;WcfServiceFault&gt; fault)
        {
          Console.WriteLine(fault.ToString());
        }
        catch (Exception e) //handles exceptions not in wcf communication
        {
          Console.WriteLine(e.ToString());
        }
      }

      Console.ReadLine();
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
To save space, I only wrapped the use of the client in try catch on the second test
service.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Note:&lt;/strong&gt; 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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/PluggableWcfServiceHost.zip"&gt;Download
PluggableWcfServiceHost.zip (38.05 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ebf0f909-a38b-439b-846c-46e08a8d1289" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,ebf0f909-a38b-439b-846c-46e08a8d1289.aspx</comments>
      <category>Code</category>
      <category>WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=f0753073-14b0-437e-9a1a-cbc6a62a5b40</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,f0753073-14b0-437e-9a1a-cbc6a62a5b40.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,f0753073-14b0-437e-9a1a-cbc6a62a5b40.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f0753073-14b0-437e-9a1a-cbc6a62a5b40</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few years ago I worked on a project called <a href="http://www.codeplex.com/atrax">Atrax</a> which
among other things included an implementation of the <a title="http://ymatsuo.com/papers/ijait04.pdf" href="http://ymatsuo.com/papers/ijait04.pdf">work</a> of
Yutaka Matsuo of the National Institute of Advanced Industrial Science and Technology
in Tokyo and by Mitsuru Ishizuka of the University of Tokyo.
</p>
        <p>
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 <a href="http://www.tsjensen.com/blog/content/binary/Keyword.zip">Keyword.zip
(17.87 KB)</a>.
</p>
        <p>
Here are the top ten keywords the code returns from the Gettysburg Address and from <a href="http://weblogs.asp.net/scottgu/archive/2010/03/11/asp-net-mvc-2-released.aspx">Scot
Gu’s most recent blog post</a>:
</p>
        <blockquote>
          <p>
            <strong>gettys</strong>
            <br />
   dedicated<br />
   nation<br />
   great<br />
   gave<br />
   dead<br />
   rather<br />
   people<br />
   devotion<br />
   people people<br />
   lives
</p>
          <p>
            <strong>gu</strong>
            <br />
   ASP.NET MVC<br />
   VS 2010 and Visual Web Developer<br />
   ASP.NET 3.5<br />
   ASP.NET<br />
   MVC<br />
   Web Developer 2008 Express<br />
   VS 2010<br />
   VS 2008<br />
   release<br />
   Improved Visual Studio
</p>
        </blockquote>
        <p>
Let me know if you end up using the implementation of the algorithm and if you happen
to make improvements to it.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f0753073-14b0-437e-9a1a-cbc6a62a5b40" />
      </body>
      <title>Keyword Extraction in C# with Word Co-occurrence Algorithm</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,f0753073-14b0-437e-9a1a-cbc6a62a5b40.aspx</guid>
      <link>http://www.tsjensen.com/blog/2010/03/14/Keyword+Extraction+In+C+With+Word+Cooccurrence+Algorithm.aspx</link>
      <pubDate>Sun, 14 Mar 2010 22:56:37 GMT</pubDate>
      <description>&lt;p&gt;
A few years ago I worked on a project called &lt;a href="http://www.codeplex.com/atrax"&gt;Atrax&lt;/a&gt; which
among other things included an implementation of the &lt;a title="http://ymatsuo.com/papers/ijait04.pdf" href="http://ymatsuo.com/papers/ijait04.pdf"&gt;work&lt;/a&gt; of
Yutaka Matsuo of the National Institute of Advanced Industrial Science and Technology
in Tokyo and by Mitsuru Ishizuka of the University of Tokyo.
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://www.tsjensen.com/blog/content/binary/Keyword.zip"&gt;Keyword.zip
(17.87 KB)&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Here are the top ten keywords the code returns from the Gettysburg Address and from &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/03/11/asp-net-mvc-2-released.aspx"&gt;Scot
Gu’s most recent blog post&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;gettys&lt;/strong&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; dedicated&lt;br&gt;
&amp;nbsp;&amp;nbsp; nation&lt;br&gt;
&amp;nbsp;&amp;nbsp; great&lt;br&gt;
&amp;nbsp;&amp;nbsp; gave&lt;br&gt;
&amp;nbsp;&amp;nbsp; dead&lt;br&gt;
&amp;nbsp;&amp;nbsp; rather&lt;br&gt;
&amp;nbsp;&amp;nbsp; people&lt;br&gt;
&amp;nbsp;&amp;nbsp; devotion&lt;br&gt;
&amp;nbsp;&amp;nbsp; people people&lt;br&gt;
&amp;nbsp;&amp;nbsp; lives
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;gu&lt;/strong&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; ASP.NET MVC&lt;br&gt;
&amp;nbsp;&amp;nbsp; VS 2010 and Visual Web Developer&lt;br&gt;
&amp;nbsp;&amp;nbsp; ASP.NET 3.5&lt;br&gt;
&amp;nbsp;&amp;nbsp; ASP.NET&lt;br&gt;
&amp;nbsp;&amp;nbsp; MVC&lt;br&gt;
&amp;nbsp;&amp;nbsp; Web Developer 2008 Express&lt;br&gt;
&amp;nbsp;&amp;nbsp; VS 2010&lt;br&gt;
&amp;nbsp;&amp;nbsp; VS 2008&lt;br&gt;
&amp;nbsp;&amp;nbsp; release&lt;br&gt;
&amp;nbsp;&amp;nbsp; Improved Visual Studio
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Let me know if you end up using the implementation of the algorithm and if you happen
to make improvements to it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f0753073-14b0-437e-9a1a-cbc6a62a5b40" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,f0753073-14b0-437e-9a1a-cbc6a62a5b40.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=904052d4-8ee0-47b5-bacb-eb1788137233</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,904052d4-8ee0-47b5-bacb-eb1788137233.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,904052d4-8ee0-47b5-bacb-eb1788137233.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=904052d4-8ee0-47b5-bacb-eb1788137233</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>ASP.NET MVC 2 MinStringLength Custom Validation Attribute</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,904052d4-8ee0-47b5-bacb-eb1788137233.aspx</guid>
      <link>http://www.tsjensen.com/blog/2010/03/11/ASPNET+MVC+2+MinStringLength+Custom+Validation+Attribute.aspx</link>
      <pubDate>Thu, 11 Mar 2010 20:21:29 GMT</pubDate>
      <description>&lt;p&gt;
I love ASP.NET MVC 2 validations for client and server via annotations. Steve Sanderson's &lt;a href="http://xval.codeplex.com/"&gt;xVal&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
At first I attacked this deficiency with a regex like this:
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;
[RegularExpression("[\\S]{6,}", ErrorMessage = "Must be at least 6 characters.")]
public string Password { get; set; }&lt;/pre&gt;
&lt;p&gt;
This approach just seems clunky. Happily, while reading Scott Allen's piece on &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee336030.aspx"&gt;MVC
2 validation in MSDN magazine&lt;/a&gt;, I came across a critical reference to one of Phil
Haack's blog posts which I must have overlooked.
&lt;/p&gt;
&lt;p&gt;
Thanks go to Phil's easy to follow instructions on &lt;a href="http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx"&gt;writing
a custom validator for MVC 2&lt;/a&gt; that will work on both client and server sides.
&lt;/p&gt;
&lt;p&gt;
So here's my custom MinStringLengthAttribute and supporting code which let's me do
something easier and cleaner like this:
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;
[StringLength(128, ErrorMessage = "Must be under 128 characters.")]
[MinStringLength(3, ErrorMessage = "Must be at least 3 characters.")]
public string PasswordAnswer { get; set; }&lt;/pre&gt;
&lt;p&gt;
If you really wanted to get creative, you could produce a combination of the two,
but I'll leave that for another day.
&lt;/p&gt;
&lt;p&gt;
Here's the code for the attribute and the required validator:
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;
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 &amp;lt; MinLength)
      return false;
    else
      return true;
  }
}

public class MinStringLengthValidator : DataAnnotationsModelValidator&amp;lt;MinStringLengthAttribute&gt;
{
  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&amp;lt;ModelClientValidationRule&gt; GetClientValidationRules()
  {
    var rule = new ModelClientValidationRule
    {
      ErrorMessage = message,
      ValidationType = "minlen"
    };
    rule.ValidationParameters.Add("min", minLength);
    return new[] { rule };
  }
}&lt;/pre&gt;
&lt;p&gt;
Here's the code in the Global.asax.cs that registers the validator:
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;
protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);
  DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MinStringLengthAttribute), typeof(MinStringLengthValidator));
}&lt;/pre&gt;
&lt;p&gt;
Here's the javascript to hook up the client side:
&lt;/p&gt;
&lt;pre class="brush: js;" name="code"&gt;&lt; minLen) 
      return rule.ErrorMessage;
    else
      return true;  /* success */
  };
};&lt;/pre&gt;
Sys.Mvc.ValidatorRegistry.validators["minlen"] = function(rule) {
  //initialization
  var minLen = rule.ValidationParameters["min"];

  //return validator function
  return function(value, context) {
    if (value.length 


&lt;p&gt;
Now, in your view, add &amp;lt;% Html.EnableClientValidation(); %&gt; and that's all there
is to it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=904052d4-8ee0-47b5-bacb-eb1788137233" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,904052d4-8ee0-47b5-bacb-eb1788137233.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=2bc9bb3e-9a62-442c-afe8-643ebfb964a5</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,2bc9bb3e-9a62-442c-afe8-643ebfb964a5.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,2bc9bb3e-9a62-442c-afe8-643ebfb964a5.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2bc9bb3e-9a62-442c-afe8-643ebfb964a5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <pre class="brush: c-sharp;" name="code">
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;
  }
}</pre>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2bc9bb3e-9a62-442c-afe8-643ebfb964a5" />
      </body>
      <title>EventLog WriteEntry Helper Class</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,2bc9bb3e-9a62-442c-afe8-643ebfb964a5.aspx</guid>
      <link>http://www.tsjensen.com/blog/2010/01/06/EventLog+WriteEntry+Helper+Class.aspx</link>
      <pubDate>Wed, 06 Jan 2010 22:01:07 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;
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;
  }
}&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2bc9bb3e-9a62-442c-afe8-643ebfb964a5" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,2bc9bb3e-9a62-442c-afe8-643ebfb964a5.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=1bc5872b-9601-428f-ad70-f90999085525</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1bc5872b-9601-428f-ad70-f90999085525</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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. 
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
Here’s the only configuration you need for accessing Azure storage:
</p>
        <pre class="brush: xml;" name="code">&lt;?xml version="1.0"?&gt;
&lt;ServiceConfiguration serviceName="MyFilesCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"&gt;
  &lt;Role name="MyFiles"&gt;
    &lt;Instances count="1" /&gt;
    &lt;ConfigurationSettings&gt;
      &lt;!-- Add your storage account information and uncomment this to target Windows Azure storage. 
      &lt;Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&gt;
      &lt;Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&gt;
      --&gt;

      &lt;!-- local settings --&gt;
      &lt;Setting name="DataConnectionString" value="UseDevelopmentStorage=true" /&gt;
      &lt;Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" /&gt;
    &lt;/ConfigurationSettings&gt;
  &lt;/Role&gt;
&lt;/ServiceConfiguration&gt;</pre>
        <p>
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: 
</p>
        <pre class="brush: c-sharp;" name="code">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) =&gt;
    {
      // Provide the configSetter with the initial value
      configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

      RoleEnvironment.Changed += (sender, arg) =&gt;
      {
        if (arg.Changes.OfType&lt;RoleEnvironmentConfigurationSettingChange&gt;()
           .Any((change) =&gt; (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 =&gt; change is RoleEnvironmentConfigurationSettingChange))
    {
      // Set e.Cancel to true to restart this role instance
      e.Cancel = true;
    }
  }
}</pre>
        <p>
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.
</p>
        <pre class="brush: c-sharp;" name="code">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&lt;AdventureRow&gt; GetAdventureList()
    {
      var svc = _client.GetDataServiceContext();
      DataServiceQuery&lt;AdventureRow&gt; queryService = svc.CreateQuery&lt;AdventureRow&gt;(_tableName);
      var query = (from adv in queryService select adv).AsTableServiceQuery();
      IEnumerable&lt;AdventureRow&gt; rows = query.Execute();
      List&lt;AdventureRow&gt; list = new List&lt;AdventureRow&gt;(rows);
      return list;
    }
  }
}</pre>
        <p>
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.
</p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=1bc5872b-9601-428f-ad70-f90999085525" />
      </body>
      <title>Windows Azure 1.0 CloudTableClient Minimal Configuration</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/11/30/Windows+Azure+10+CloudTableClient+Minimal+Configuration.aspx</link>
      <pubDate>Mon, 30 Nov 2009 02:13:26 GMT</pubDate>
      <description>&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Here’s the only configuration you need for accessing Azure storage:
&lt;/p&gt;
&lt;pre class="brush: xml;" name="code"&gt;&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;ServiceConfiguration serviceName="MyFilesCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"&amp;gt;
  &amp;lt;Role name="MyFiles"&amp;gt;
    &amp;lt;Instances count="1" /&amp;gt;
    &amp;lt;ConfigurationSettings&amp;gt;
      &amp;lt;!-- Add your storage account information and uncomment this to target Windows Azure storage. 
      &amp;lt;Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&amp;gt;
      &amp;lt;Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" /&amp;gt;
      --&amp;gt;

      &amp;lt;!-- local settings --&amp;gt;
      &amp;lt;Setting name="DataConnectionString" value="UseDevelopmentStorage=true" /&amp;gt;
      &amp;lt;Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" /&amp;gt;
    &amp;lt;/ConfigurationSettings&amp;gt;
  &amp;lt;/Role&amp;gt;
&amp;lt;/ServiceConfiguration&amp;gt;&lt;/pre&gt;
&lt;p&gt;
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: 
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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) =&amp;gt;
    {
      // Provide the configSetter with the initial value
      configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

      RoleEnvironment.Changed += (sender, arg) =&amp;gt;
      {
        if (arg.Changes.OfType&amp;lt;RoleEnvironmentConfigurationSettingChange&amp;gt;()
           .Any((change) =&amp;gt; (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 =&amp;gt; change is RoleEnvironmentConfigurationSettingChange))
    {
      // Set e.Cancel to true to restart this role instance
      e.Cancel = true;
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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&amp;lt;AdventureRow&amp;gt; GetAdventureList()
    {
      var svc = _client.GetDataServiceContext();
      DataServiceQuery&amp;lt;AdventureRow&amp;gt; queryService = svc.CreateQuery&amp;lt;AdventureRow&amp;gt;(_tableName);
      var query = (from adv in queryService select adv).AsTableServiceQuery();
      IEnumerable&amp;lt;AdventureRow&amp;gt; rows = query.Execute();
      List&amp;lt;AdventureRow&amp;gt; list = new List&amp;lt;AdventureRow&amp;gt;(rows);
      return list;
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=1bc5872b-9601-428f-ad70-f90999085525" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,1bc5872b-9601-428f-ad70-f90999085525.aspx</comments>
      <category>Azure</category>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=62145f3a-71c9-4f6a-8d54-e3029266b103</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=62145f3a-71c9-4f6a-8d54-e3029266b103</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;displaylang=en">Windows
Azure 1.0</a> and what is now called <a href="http://silverlight.net/getstarted/riaservices/">WCF
RIA Services Beta</a> have since been released. Lot’s of great changes make using
these together with the new <a href="http://code.msdn.microsoft.com/windowsazuresamples">AspProvider
sample</a> 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.
</p>
        <p>
          <strong>
            <font color="#ff0000">WARNING:</font>
          </strong> 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.
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advnew3" border="0" alt="advnew3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_thumb.png" width="484" height="642" />
          </a>
        </p>
        <p>
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:
</p>
        <ol>
          <li>
Create a new Silverlight Business Application called Adventure which produces Adventure.Web
application as well.</li>
          <li>
Add new CloudService project with WebRole called AdventureCloudService and WebRole1.</li>
          <li>
Copy WebRole.cs to Adventure.Web and rename namespace.</li>
          <li>
Add 3 azure refs to Adventure.Web.</li>
          <li>
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.)</li>
          <li>
The node under Roles in the cloud service project shows an error. Right click it and
choose “associate” and pick Adventure.Web.</li>
          <li>
Copy system.diagnostics section from WebRole1 web.config to that of Adventure.Web.</li>
          <li>
Remove WebRole1 from solution and set service project as startup.</li>
          <li>
Copy and new AspProviders project and sections from demo web.config into Adventure.Web,
changing DefaultProviderApplicationName and applicationName="Adventure".</li>
          <li>
Do the same previous steps to create/copy UserProfile class and IUserProfile with
FriendlyName property too. Added to the Models directory this time. <strong>NOTE:</strong> Be
sure to get the magic strings right in the UserProfile class or you will get unexpected
results. 
</li>
          <li>
Add Global.asax and AppInitializer class to it from previous project without the CreateTableFromModel
calls which are no longer needed as I understand it. 
</li>
          <li>
Drop in the code to create the admin user if it does not already exist. 
</li>
          <li>
When I go to modify the LoginStatus.xaml which was previously LoginControl.xaml, but
find the needed modification is already there. Skip this step.</li>
          <li>
Just hit F5 and error is thrown. 
</li>
        </ol>
        <p>
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. 
</p>
        <p>
          <strong>
            <font color="#ff0000">AspProvider Fix Found</font>
            <br />
          </strong>Replace <strong>e.InnerException</strong> in line 484 in TableStorageRoleProvider.cs
with <strong>e.InnerException.InnerException</strong>. The first inner exception is
another InvalidOperationException. The second inner exception is the DataServiceClientException
we're looking for. 
</p>
        <p>
Login with admin/admin and we see Administrator displayed in the newly renamed LoginStatus
area. 
</p>
        <p>
And we’re back to par. <a href="http://www.tsjensen.com/blog/content/binary/Adventure3.zip">Download
the code here (566KB)</a>. <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=62145f3a-71c9-4f6a-8d54-e3029266b103" /></p>
      </body>
      <title>Enterprise Silverlight 3 with WCF RIA Services on Windows Azure 1.0 Part 1 Redux</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/11/24/Enterprise+Silverlight+3+With+WCF+RIA+Services+On+Windows+Azure+10+Part+1+Redux.aspx</link>
      <pubDate>Tue, 24 Nov 2009 03:48:05 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;amp;displaylang=en"&gt;Windows
Azure 1.0&lt;/a&gt; and what is now called &lt;a href="http://silverlight.net/getstarted/riaservices/"&gt;WCF
RIA Services Beta&lt;/a&gt; have since been released. Lot’s of great changes make using
these together with the new &lt;a href="http://code.msdn.microsoft.com/windowsazuresamples"&gt;AspProvider
sample&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font color="#ff0000"&gt;WARNING:&lt;/font&gt;&lt;/strong&gt; 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.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advnew3" border="0" alt="advnew3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/EnterpriseSilverlight3withWC.0Part1Redux_112DF/advnew3_thumb.png" width="484" height="642"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Create a new Silverlight Business Application called Adventure which produces Adventure.Web
application as well.&lt;/li&gt;
&lt;li&gt;
Add new CloudService project with WebRole called AdventureCloudService and WebRole1.&lt;/li&gt;
&lt;li&gt;
Copy WebRole.cs to Adventure.Web and rename namespace.&lt;/li&gt;
&lt;li&gt;
Add 3 azure refs to Adventure.Web.&lt;/li&gt;
&lt;li&gt;
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.)&lt;/li&gt;
&lt;li&gt;
The node under Roles in the cloud service project shows an error. Right click it and
choose “associate” and pick Adventure.Web.&lt;/li&gt;
&lt;li&gt;
Copy system.diagnostics section from WebRole1 web.config to that of Adventure.Web.&lt;/li&gt;
&lt;li&gt;
Remove WebRole1 from solution and set service project as startup.&lt;/li&gt;
&lt;li&gt;
Copy and new AspProviders project and sections from demo web.config into Adventure.Web,
changing DefaultProviderApplicationName and applicationName="Adventure".&lt;/li&gt;
&lt;li&gt;
Do the same previous steps to create/copy UserProfile class and IUserProfile with
FriendlyName property too. Added to the Models directory this time. &lt;strong&gt;NOTE:&lt;/strong&gt; Be
sure to get the magic strings right in the UserProfile class or you will get unexpected
results. 
&lt;/li&gt;
&lt;li&gt;
Add Global.asax and AppInitializer class to it from previous project without the CreateTableFromModel
calls which are no longer needed as I understand it. 
&lt;/li&gt;
&lt;li&gt;
Drop in the code to create the admin user if it does not already exist. 
&lt;/li&gt;
&lt;li&gt;
When I go to modify the LoginStatus.xaml which was previously LoginControl.xaml, but
find the needed modification is already there. Skip this step.&lt;/li&gt;
&lt;li&gt;
Just hit F5 and error is thrown. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font color="#ff0000"&gt;AspProvider Fix Found&lt;/font&gt;
&lt;br&gt;
&lt;/strong&gt;Replace &lt;strong&gt;e.InnerException&lt;/strong&gt; in line 484 in TableStorageRoleProvider.cs
with &lt;strong&gt;e.InnerException.InnerException&lt;/strong&gt;. The first inner exception is
another InvalidOperationException. The second inner exception is the DataServiceClientException
we're looking for. 
&lt;/p&gt;
&lt;p&gt;
Login with admin/admin and we see Administrator displayed in the newly renamed LoginStatus
area. 
&lt;p&gt;
And we’re back to par. &lt;a href="http://www.tsjensen.com/blog/content/binary/Adventure3.zip"&gt;Download
the code here (566KB)&lt;/a&gt;. &lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=62145f3a-71c9-4f6a-8d54-e3029266b103" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,62145f3a-71c9-4f6a-8d54-e3029266b103.aspx</comments>
      <category>Azure</category>
      <category>Code</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=6162ea94-2509-40f7-a63c-70b00c1fa3e9</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,6162ea94-2509-40f7-a63c-70b00c1fa3e9.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,6162ea94-2509-40f7-a63c-70b00c1fa3e9.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6162ea94-2509-40f7-a63c-70b00c1fa3e9</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The 1.0 release of Windows Azure SDK is now available. Download and read about what’s
new <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;displaylang=en">here</a>.
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.
</p>
        <p>
          <strong>Update (11/22/09) - AspProviders in Additional C# Examples: </strong>One comment
and an additional private email from readers have pointed out <a href="http://code.msdn.microsoft.com/windowsazuresamples">Azure
Code Samples on MSDN</a> 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.
</p>
        <p>
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:
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-01_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="az-nov09-01" border="0" alt="az-nov09-01" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-01_thumb.png" width="488" height="376" />
          </a>  
</p>
        <p>
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.
</p>
        <p>
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:
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-02_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="az-nov09-02" border="0" alt="az-nov09-02" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-02_thumb.png" width="387" height="92" />
          </a>
        </p>
        <p>
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.
</p>
        <p>
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.
</p>
        <pre class="brush: c-sharp;" name="code">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 =&gt; change is RoleEnvironmentConfigurationSettingChange))
		{
			// Set e.Cancel to true to restart this role instance
			e.Cancel = true;
		}
	}
}
</pre>
        <p>
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.
</p>
        <p>
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.”
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=6162ea94-2509-40f7-a63c-70b00c1fa3e9" />
      </body>
      <title>Windows Azure Tools SDK (November 2009) Refactor or Restart?</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,6162ea94-2509-40f7-a63c-70b00c1fa3e9.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/11/15/Windows+Azure+Tools+SDK+November+2009+Refactor+Or+Restart.aspx</link>
      <pubDate>Sun, 15 Nov 2009 22:42:06 GMT</pubDate>
      <description>&lt;p&gt;
The 1.0 release of Windows Azure SDK is now available. Download and read about what’s
new &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;amp;displaylang=en"&gt;here&lt;/a&gt;.
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update (11/22/09) - AspProviders in Additional C# Examples: &lt;/strong&gt;One comment
and an additional private email from readers have pointed out &lt;a href="http://code.msdn.microsoft.com/windowsazuresamples"&gt;Azure
Code Samples on MSDN&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-01_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="az-nov09-01" border="0" alt="az-nov09-01" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-01_thumb.png" width="488" height="376"&gt;&lt;/a&gt;&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-02_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="az-nov09-02" border="0" alt="az-nov09-02" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/WindowsAzureToolsSDKNovember2009Refactor_D9BB/az-nov09-02_thumb.png" width="387" height="92"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;pre class="brush: c-sharp;" name="code"&gt;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 =&amp;gt; change is RoleEnvironmentConfigurationSettingChange))
		{
			// Set e.Cancel to true to restart this role instance
			e.Cancel = true;
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.”
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=6162ea94-2509-40f7-a63c-70b00c1fa3e9" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,6162ea94-2509-40f7-a63c-70b00c1fa3e9.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=52f313e4-c45a-4b0a-ac21-c8a6b841f2c8</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,52f313e4-c45a-4b0a-ac21-c8a6b841f2c8.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,52f313e4-c45a-4b0a-ac21-c8a6b841f2c8.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=52f313e4-c45a-4b0a-ac21-c8a6b841f2c8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://www.asp.net">www.asp.net</a> 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.
</p>
        <p>
Download <a href="http://www.tsjensen.com/blog/content/binary/OraHelper.zip">OraHelper
(12KB)</a> here.
</p>
        <p>
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.
</p>
        <p>
For those of you who are doing .NET database access to Oracle, you may be helped even
more by looking at <a href="http://www.oracle.com/technology/tech/dotnet/index.html">Oracle’s
.NET Developer Center</a>. 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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=52f313e4-c45a-4b0a-ac21-c8a6b841f2c8" />
      </body>
      <title>OraHelper – An Oracle Version of the SqlHelper Class</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,52f313e4-c45a-4b0a-ac21-c8a6b841f2c8.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/10/21/OraHelper+An+Oracle+Version+Of+The+SqlHelper+Class.aspx</link>
      <pubDate>Wed, 21 Oct 2009 15:05:51 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;a href="http://www.asp.net"&gt;www.asp.net&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
Download &lt;a href="http://www.tsjensen.com/blog/content/binary/OraHelper.zip"&gt;OraHelper
(12KB)&lt;/a&gt; here.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
For those of you who are doing .NET database access to Oracle, you may be helped even
more by looking at &lt;a href="http://www.oracle.com/technology/tech/dotnet/index.html"&gt;Oracle’s
.NET Developer Center&lt;/a&gt;. 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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=52f313e4-c45a-4b0a-ac21-c8a6b841f2c8" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,52f313e4-c45a-4b0a-ac21-c8a6b841f2c8.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=aa40f3e2-afc5-484d-b4e9-6a5227e73590&amp;displaylang=en">Windows
Azure SDK</a> or perhaps the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=8D75D4F7-77A4-4ADF-BCE8-1B10608574BB&amp;displaylang=en">Visual
Studio 2008 Tools for Azure</a>. 
</p>
        <p>
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 
</p>
        <p>
You can <a href="http://www.tsjensen.com/blog/content/binary/cloud1.zip">download
the entire solution file (434KB)</a> 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.)
</p>
        <p>
Here’s the step-by-step details. I’ll try to spare the you excruciating minutiae and
keep it as exciting as possible.     
</p>
        <p>
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.
</p>
        <p>
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.)
</p>
        <p>
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. 
</p>
        <p>
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:
</p>
        <pre name="code" class="brush: c-sharp;">
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; }
      }
   }
}
</pre>
        <p>
I boldly hit F5 again and get this gem:
</p>
        <blockquote>
          <p>
Configuration Error 
<br />
Initialization of data service structures (tables and/or blobs) failed!<br />
The most probable reason for this is that the storage endpoints are not configured
correctly.<br />
Line 133: type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
</p>
        </blockquote>
        <p>
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:
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent3" border="0" alt="advent3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_thumb.png" width="459" height="204" />
          </a>
        </p>
        <blockquote>
          <p>
DevTableGen : Generating database 'MyFilesCloudService'<br />
DevTableGen : Generating table 'Roles' for type 'Microsoft.Samples.ServiceHosting.AspProviders.RoleRow'<br />
DevTableGen : Generating table 'Sessions' for type 'Microsoft.Samples.ServiceHosting.AspProviders.SessionRow'<br />
DevTableGen : Generating table 'Membership' for type 'Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow'<br />
===== Create test storage tables succeeded =====
</p>
        </blockquote>
        <p>
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.
</p>
        <p>
So I experiment a little and create a couple of test tables like this:
</p>
        <pre name="code" class="brush: c-sharp;">
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<MyTestRow>
Roles { get { return this.CreateQuery<MyTestRow>
("MyTest"); } } } public class MyTestRow : TableStorageEntity { public string MyTestName
{ get; set; } } }
</MyTestRow></MyTestRow></pre>
        <p>
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:
</p>
        <blockquote>
          <p>
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
</p>
        </blockquote>
        <p>
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).
</p>
        <pre name="code" class="brush: c-sharp;">
protected void Application_BeginRequest(object sender, EventArgs e)	
{	
   HttpApplication app = sender as HttpApplication;   
   if (app != null)   
   {   
      HttpContext context = app.Context;   
      AppInitializer.Initialize(context);   
   }   
}</pre>
        <p>
I then add the initializer class at the bottom of that same code file.
</p>
        <pre name="code" class="brush: c-sharp;">
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));
   }
}</pre>
        <p>
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.
</p>
        <p>
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:
</p>
        <pre name="code" class="brush: c-sharp;">
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();
}</pre>
        <p>
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&lt;T&gt; base class
used for the AuthenticationService domain service class:
</p>
        <pre name="code" class="brush: c-sharp;">
// 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.</pre>
        <p>
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:
</p>
        <pre name="code" class="brush: c-sharp;">
public interface IUserProfile	
{	
   string Country { get; set; }   
   string Gender { get; set; }   
   int Age { get; set; }   
}</pre>
        <p>
And then add the same properties found in UserProfile to the User class in the AuthenticationService.cs
file as follows:
</p>
        <pre name="code" class="brush: c-sharp;">
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; }   
}</pre>
        <p>
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:
</p>
        <pre name="code" class="brush: xml;">
&lt;!-- handlers and httpHandlers sections require the following additions --&gt;
&lt;handlers&gt;
   &lt;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"/&gt;		
&lt;/handlers&gt;

&lt;httpHandlers&gt;
   &lt;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"/&gt;		
&lt;/httpHandlers&gt;

&lt;!-- the ServiceDefinition.csdef gets the enableNativeCodeExecution set to true --&gt;
&lt;WebRole name="WebFilesRole" enableNativeCodeExecution="true"&gt;</pre>
        <p>
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.
</p>
        <pre name="code" class="brush: xml;">
&lt;StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}"&gt;
   &lt;TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/&gt;
   &lt;TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
      &lt;TextBlock Text="" x:Name="ProfileText" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
   &lt;Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" /&gt;
&lt;/StackPanel&gt;</pre>
        <p>
With the code behind changed like this:
</p>
        <pre name="code" class="brush: c-sharp;">
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);   
      }   
   }
}</pre>
        <p>
Now when I login, I get to look at something like this:
</p>
        <p>
          <a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent8" border="0" alt="advent8" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_thumb.png" width="447" height="162" />
          </a>
        </p>
        <p>
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.
</p>
        <p>
If you have any questions or ways to do this better, I’d love to hear from you.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f" />
      </body>
      <title>Building Enterprise Applications with Silverlight 3, .NET RIA Services and Windows Azure Part 1</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/10/19/Building+Enterprise+Applications+With+Silverlight+3+NET+RIA+Services+And+Windows+Azure+Part+1.aspx</link>
      <pubDate>Mon, 19 Oct 2009 01:58:29 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;a href="http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=aa40f3e2-afc5-484d-b4e9-6a5227e73590&amp;amp;displaylang=en"&gt;Windows
Azure SDK&lt;/a&gt; or perhaps the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=8D75D4F7-77A4-4ADF-BCE8-1B10608574BB&amp;amp;displaylang=en"&gt;Visual
Studio 2008 Tools for Azure&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
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 
&lt;/p&gt;
&lt;p&gt;
You can &lt;a href="http://www.tsjensen.com/blog/content/binary/cloud1.zip"&gt;download
the entire solution file (434KB)&lt;/a&gt; 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.)
&lt;/p&gt;
&lt;p&gt;
Here’s the step-by-step details. I’ll try to spare the you excruciating minutiae and
keep it as exciting as possible.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.)
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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; }
      }
   }
}
&lt;/pre&gt;
&lt;p&gt;
I boldly hit F5 again and get this gem:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Configuration Error 
&lt;br&gt;
Initialization of data service structures (tables and/or blobs) failed!&lt;br&gt;
The most probable reason for this is that the storage endpoints are not configured
correctly.&lt;br&gt;
Line 133: type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent3" border="0" alt="advent3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent3_thumb.png" width="459" height="204"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
DevTableGen : Generating database 'MyFilesCloudService'&lt;br&gt;
DevTableGen : Generating table 'Roles' for type 'Microsoft.Samples.ServiceHosting.AspProviders.RoleRow'&lt;br&gt;
DevTableGen : Generating table 'Sessions' for type 'Microsoft.Samples.ServiceHosting.AspProviders.SessionRow'&lt;br&gt;
DevTableGen : Generating table 'Membership' for type 'Microsoft.Samples.ServiceHosting.AspProviders.MembershipRow'&lt;br&gt;
===== Create test storage tables succeeded =====
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
So I experiment a little and create a couple of test tables like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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&lt;MyTestRow&gt;
Roles { get { return this.CreateQuery&lt;MyTestRow&gt;
("MyTest"); } } } public class MyTestRow : TableStorageEntity { public string MyTestName
{ get; set; } } }
&lt;/pre&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
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
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
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).
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
protected void Application_BeginRequest(object sender, EventArgs e)	
{	
   HttpApplication app = sender as HttpApplication;   
   if (app != null)   
   {   
      HttpContext context = app.Context;   
      AppInitializer.Initialize(context);   
   }   
}&lt;/pre&gt;
&lt;p&gt;
I then add the initializer class at the bottom of that same code file.
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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));
   }
}&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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();
}&lt;/pre&gt;
&lt;p&gt;
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&amp;nbsp; System.Web.Ria.ApplicationServices.AuthenticationBase&amp;lt;T&amp;gt; base class
used for the AuthenticationService domain service class:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
// 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.&lt;/pre&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
public interface IUserProfile	
{	
   string Country { get; set; }   
   string Gender { get; set; }   
   int Age { get; set; }   
}&lt;/pre&gt;
&lt;p&gt;
And then add the same properties found in UserProfile to the User class in the AuthenticationService.cs
file as follows:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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; }   
}&lt;/pre&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt;
&amp;lt;!-- handlers and httpHandlers sections require the following additions --&gt;
&amp;lt;handlers&gt;
   &amp;lt;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"/&gt;		
&amp;lt;/handlers&gt;

&amp;lt;httpHandlers&gt;
   &amp;lt;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"/&gt;		
&amp;lt;/httpHandlers&gt;

&amp;lt;!-- the ServiceDefinition.csdef gets the enableNativeCodeExecution set to true --&gt;
&amp;lt;WebRole name="WebFilesRole" enableNativeCodeExecution="true"&gt;&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt;
&amp;lt;StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}"&gt;
   &amp;lt;TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/&gt;
   &amp;lt;TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &amp;lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
      &amp;lt;TextBlock Text="" x:Name="ProfileText" Style="{StaticResource WelcomeTextStyle}"/&gt;
      &amp;lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
   &amp;lt;Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" /&gt;
&amp;lt;/StackPanel&gt;&lt;/pre&gt;
&lt;p&gt;
With the code behind changed like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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);   
      }   
   }
}&lt;/pre&gt;
&lt;p&gt;
Now when I login, I get to look at something like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="advent8" border="0" alt="advent8" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3RIA.NETProviderModelforAzure_10745/advent8_thumb.png" width="447" height="162"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
If you have any questions or ways to do this better, I’d love to hear from you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=0ccd0ced-18e1-4fe3-81e8-fd38fba4347f" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,0ccd0ced-18e1-4fe3-81e8-fd38fba4347f.aspx</comments>
      <category>Azure</category>
      <category>Code</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=967c21b6-13a8-4385-94ba-f94893f8e347</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,967c21b6-13a8-4385-94ba-f94893f8e347.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,967c21b6-13a8-4385-94ba-f94893f8e347.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=967c21b6-13a8-4385-94ba-f94893f8e347</wfw:commentRss>
      <title>Silverlight 3 and .NET RIA Services Forms Security</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,967c21b6-13a8-4385-94ba-f94893f8e347.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/10/12/Silverlight+3+And+NET+RIA+Services+Forms+Security.aspx</link>
      <pubDate>Mon, 12 Oct 2009 21:01:52 GMT</pubDate>
      <description>&lt;p&gt;
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. 
&lt;p&gt;
&lt;strong&gt;Tools&lt;/strong&gt;
&lt;br&gt;
Before you follow along on your own machine, be sure that you have these: 
&lt;p&gt;
&lt;strong&gt;1. Visual Studio 2008 Pro &lt;/strong&gt;(&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=83c3a1ec-ed72-4a79-8961-25635db0192b&amp;amp;displaylang=en"&gt;Visual
Studio 2008 Professional Edition (90-day Trial)&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;2. Visual Studio 2008 SP1 &lt;/strong&gt;(&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;amp;displaylang=en"&gt;Microsoft
Visual Studio 2008 Service Pack 1 (Installer)&lt;/a&gt;) 
&lt;p&gt;
&lt;strong&gt;3. Silverlight SDK &lt;/strong&gt;(&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9442b0f2-7465-417a-88f3-5e7b5409e9dd&amp;amp;displaylang=en"&gt;Microsoft®
Silverlight™ 3 Tools for Visual Studio 2008 SP1&lt;/a&gt;) 
&lt;p&gt;
&lt;strong&gt;4. RIA Services July 2009 Preview &lt;/strong&gt;(&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;amp;displaylang=en"&gt;Microsoft
.NET RIA Services July 2009 Preview&lt;/a&gt;) 
&lt;p&gt;
&lt;strong&gt;5. Download code for this post&lt;/strong&gt; (&lt;a href="http://www.tsjensen.com/blog/content/binary/DemoAgRia.zip"&gt;download
DemoAgRia.zip 427KB&lt;/a&gt;). 
&lt;p&gt;
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. 
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s1_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="s1" border="0" alt="s1" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s1_thumb_1.png" width="802" height="541"&gt;&lt;/a&gt; 
&lt;p&gt;
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. 
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s2_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="s2" border="0" alt="s2" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s2_thumb.png" width="373" height="584"&gt;&lt;/a&gt; 
&lt;p&gt;
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. 
&lt;p&gt;
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: 
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt;
&amp;lt;authentication mode="Forms"/&gt;

&amp;lt;roleManager enabled="true" defaultProvider="AgRoleProvider"&gt;
  &amp;lt;providers&gt;
    &amp;lt;clear /&gt;
    &amp;lt;add name="AgRoleProvider" type="DemoAgRia.Web.AgRoleProvider" /&gt;
  &amp;lt;/providers&gt;
&amp;lt;/roleManager&gt;
&amp;lt;membership defaultProvider="AgMembershipProvider"&gt;
  &amp;lt;providers&gt;
    &amp;lt;clear /&gt;
    &amp;lt;add name="AgMembershipProvider" type="DemoAgRia.Web.AgMembershipProvider" /&gt;
  &amp;lt;/providers&gt;
&amp;lt;/membership&gt;
&amp;lt;profile enabled="true" defaultProvider="AgProfileProvider"&gt;
  &amp;lt;providers&gt;
    &amp;lt;clear /&gt;
    &amp;lt;add name="AgProfileProvider" type="DemoAgRia.Web.AgProfileProvider" /&gt;
  &amp;lt;/providers&gt;
  &amp;lt;properties&gt;
    &amp;lt;clear /&gt;
    &amp;lt;add name="PhoneNumber" /&gt;
    &amp;lt;add name="FullName" /&gt;
  &amp;lt;/properties&gt;
&amp;lt;/profile&gt;
&lt;/pre&gt;
&lt;p&gt;
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. 
&lt;p&gt;
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: 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;in AgProfileProvider.cs:&lt;/strong&gt;
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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;
}
&lt;/pre

&lt;p&gt;&lt;strong&gt;in
AuthenticationService.cs:&lt;/strong&gt;&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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; }
}
&lt;/pre&gt;
&lt;p&gt;
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. 
&lt;p&gt;
Here's the existing XAML which we will modify:
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt;
&amp;lt;StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}"&gt;
  &amp;lt;TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/&gt;
  &amp;lt;TextBlock Text="{Binding Path=User.Name}" Style="{StaticResource WelcomeTextStyle}"/&gt;
  &amp;lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
  &amp;lt;Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" /&gt;  
&amp;lt;/StackPanel&gt;
&lt;/pre&gt;
&lt;p&gt;
We now modify this XAML snippet to this:
&lt;/p&gt;
&lt;pre name="code" class="brush: xml;"&gt; 
&amp;lt;StackPanel x:Name="logoutControls" Style="{StaticResource LoginPanelStyle}"&gt;
  &amp;lt;TextBlock Text="welcome " Style="{StaticResource WelcomeTextStyle}"/&gt;
  &amp;lt;TextBlock Text="{Binding Path=User.FullName}" Style="{StaticResource WelcomeTextStyle}"/&gt;
  &amp;lt;TextBlock Text="  |  phone: " Style="{StaticResource SpacerStyle}"/&gt;
  &amp;lt;TextBlock Text="{Binding Path=User.PhoneNumber}" Style="{StaticResource WelcomeTextStyle}"/&gt;
  &amp;lt;TextBlock Text="  |  " Style="{StaticResource SpacerStyle}"/&gt;
  &amp;lt;Button x:Name="logoutButton" Content="logout" Click="LogoutButton_Click" Style="{StaticResource LoginRegisterLinkStyle}" /&gt;
&amp;lt;/StackPanel&gt;
&lt;/pre&gt;
&lt;p&gt;
Now lets add a DomainService for fecthing some data. Right click on the web application's
Services folder and select Add | New Item. 
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s3_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="s3" border="0" alt="s3" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s3_thumb.png" width="806" height="488"&gt;&lt;/a&gt; 
&lt;p&gt;
Of course, we don't have a data or object context class, so we don't have any to choose
from in the dialog. 
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s4_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="s4" border="0" alt="s4" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s4_thumb.png" width="452" height="602"&gt;&lt;/a&gt; 
&lt;p&gt;
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. 
&lt;p&gt;
Now you'll see something like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt; 
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
  {
  }
}
&lt;/pre&gt;
&lt;p&gt;
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. 
&lt;p&gt;
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.
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt; 
[EnableClientAccess()]
public class DemoDataService : DomainService
{
  [ServiceOperation]
  public string GetApplicationName()
  {
    return "Demo Ag Ria";
  }

  [ServiceOperation]
  public string GetApplicationAddress()
  {
    return "http://www.demoagria.com";
  }
}
&lt;/pre&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt; 
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&amp;lt;string&gt; invAddress = ddc.GetApplicationAddress();
      invAddress.Completed += new EventHandler(invAddress_Completed);
      
      InvokeOperation&amp;lt;string&gt; invAppName = ddc.GetApplicationName();
      invAppName.Completed += new EventHandler(invAppName_Completed);
    }

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

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

  }
}
&lt;/pre&gt;
&lt;p&gt;
If you F5 and run a debug test, you'll note that the text in the Home page gets modified
as expected. 
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s5_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="s5" border="0" alt="s5" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s5_thumb.png" width="341" height="216"&gt;&lt;/a&gt; 
&lt;p&gt;
Now let's add a RequiresAuthentication to the GetApplicationName method:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
[ServiceOperation, RequiresAuthentication]
public string GetApplicationName()
{
  return "Demo Ag Ria";
}
&lt;/pre&gt;
&lt;p&gt;
Run the app again and you will notice that the GetApplicationName's InvokeOperation&amp;lt;string&amp;gt;
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. 
&lt;p&gt;
&lt;a href="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s6_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="s6" border="0" alt="s6" src="http://www.tsjensen.com/blog/content/binary/WindowsLiveWriter/Silverlight3.NETRIAServicesFormsSecurity_CDDD/s6_thumb.png" width="357" height="238"&gt;&lt;/a&gt; 
&lt;p&gt;
Now try modifying the GetApplicationAddress method like this:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
[ServiceOperation, RequiresRoles("Supervisor")]
public string GetApplicationAddress()
{
  return "http://www.demoagria.com";
}
&lt;/pre&gt;
&lt;p&gt;
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. 
&lt;p&gt;
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. &lt;pre name="code" class="brush: c-sharp;"&gt;
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(); 
        }
      }
    }
  }
}
&lt;/pre&gt;
&lt;p&gt;
To test this code, I've added the following code to the About.xaml.cs code to see
how it plays. &lt;pre name="code" class="brush: c-sharp;"&gt;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
  PageSecurity ps = new PageSecurity(this);
  ps.Authenticate("Home");
}
&lt;/pre&gt;
&lt;p&gt;
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. &lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=967c21b6-13a8-4385-94ba-f94893f8e347" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,967c21b6-13a8-4385-94ba-f94893f8e347.aspx</comments>
      <category>Code</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=ef18048e-e87a-4467-b5f0-ace8ca3e4753</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,ef18048e-e87a-4467-b5f0-ace8ca3e4753.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,ef18048e-e87a-4467-b5f0-ace8ca3e4753.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ef18048e-e87a-4467-b5f0-ace8ca3e4753</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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&lt;int, string&gt;,
then you’ve come to the right place. So dress up that drab enum with a Description
attribute like you see below and call <strong><font face="Courier New">EnumConverter.ConvertToDictionary&lt;<font color="#0000ff">DrabEnum</font>&gt;();</font></strong></p>
        <p>
And let me know how it works out.
</p>
        <pre name="code" class="brush: c-sharp;">
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&lt;Type, Dictionary&lt;int, string&gt;&gt; enumStore = 
      new Dictionary&lt;Type, Dictionary&lt;int, string&gt;&gt;();

    /// &lt;summary&gt;
    /// Returns thread safe copy of enum value and name dictionary. Where Description &lt;br /&gt;
    /// attribute exists, returns the description value.
    /// &lt;/summary&gt;
    /// &lt;typeparam name="T"&gt;&lt;/typeparam&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public static Dictionary&lt;int, string&gt; ConvertToDictionary&lt;T&gt;() 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&lt;int, string&gt;(enumStore[t]);
      }
    }

    private static Dictionary&lt;int, string&gt; Load(Type t)
    {
      Dictionary&lt;int, string&gt; list = new Dictionary&lt;int, string&gt;();
      foreach (MemberInfo m in t.GetMembers())
      {
        if (m.MemberType == MemberTypes.Field &amp;&amp; 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 &gt; 0)
              {
                label = da.Description;
              }
            }
          }
          int id = Convert.ToInt32(System.Enum.Parse(t, m.Name));
          list.Add(id, label);
        }
      }
      return list;
    }
  }
}
</pre>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ef18048e-e87a-4467-b5f0-ace8ca3e4753" />
      </body>
      <title>Enum to Dictionary with Description Attribute Reflection</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,ef18048e-e87a-4467-b5f0-ace8ca3e4753.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/08/28/Enum+To+Dictionary+With+Description+Attribute+Reflection.aspx</link>
      <pubDate>Fri, 28 Aug 2009 03:15:44 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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&amp;lt;int, string&amp;gt;,
then you’ve come to the right place. So dress up that drab enum with a Description
attribute like you see below and call &lt;strong&gt;&lt;font face="Courier New"&gt;EnumConverter.ConvertToDictionary&amp;lt;&lt;font color="#0000ff"&gt;DrabEnum&lt;/font&gt;&amp;gt;();&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
And let me know how it works out.
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
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&amp;lt;Type, Dictionary&amp;lt;int, string&amp;gt;&amp;gt; enumStore = 
      new Dictionary&amp;lt;Type, Dictionary&amp;lt;int, string&amp;gt;&amp;gt;();

    /// &amp;lt;summary&amp;gt;
    /// Returns thread safe copy of enum value and name dictionary. Where Description &amp;lt;br /&amp;gt;
    /// attribute exists, returns the description value.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    public static Dictionary&amp;lt;int, string&amp;gt; ConvertToDictionary&amp;lt;T&amp;gt;() 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&amp;lt;int, string&amp;gt;(enumStore[t]);
      }
    }

    private static Dictionary&amp;lt;int, string&amp;gt; Load(Type t)
    {
      Dictionary&amp;lt;int, string&amp;gt; list = new Dictionary&amp;lt;int, string&amp;gt;();
      foreach (MemberInfo m in t.GetMembers())
      {
        if (m.MemberType == MemberTypes.Field &amp;amp;&amp;amp; 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 &amp;gt; 0)
              {
                label = da.Description;
              }
            }
          }
          int id = Convert.ToInt32(System.Enum.Parse(t, m.Name));
          list.Add(id, label);
        }
      }
      return list;
    }
  }
}
&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ef18048e-e87a-4467-b5f0-ace8ca3e4753" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,ef18048e-e87a-4467-b5f0-ace8ca3e4753.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=316f5697-6b9e-466a-8d7f-f18070b95c6f</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,316f5697-6b9e-466a-8d7f-f18070b95c6f.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,316f5697-6b9e-466a-8d7f-f18070b95c6f.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=316f5697-6b9e-466a-8d7f-f18070b95c6f</wfw:commentRss>
      <slash:comments>8</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
So I took a second look at <a href="http://www.plinqo.com">PLINQO</a> with <a href="http://www.codesmithtools">CodeSmith
5.0</a>, 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.
</p>
        <p>
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.
</p>
        <p>
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 <a href="http://www.plinqo.com">PLINQO</a>.
I mean, who couldn't fall in love with code like this all buttoned up for you automatically:
</p>
        <pre name="code" class="brush: c-sharp;">
private long _userId;

//// &lt;summary&gt;
/// Gets the USER_ID column value.
/// &lt;/summary&gt;
[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();
        }
    }
}
</pre>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=316f5697-6b9e-466a-8d7f-f18070b95c6f" />
      </body>
      <title>PLINQO a Better LINQ to SQL</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,316f5697-6b9e-466a-8d7f-f18070b95c6f.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/04/28/PLINQO+A+Better+LINQ+To+SQL.aspx</link>
      <pubDate>Tue, 28 Apr 2009 03:31:03 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
So I took a second look at &lt;a href="http://www.plinqo.com"&gt;PLINQO&lt;/a&gt; with &lt;a href="http://www.codesmithtools"&gt;CodeSmith
5.0&lt;/a&gt;, 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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://www.plinqo.com"&gt;PLINQO&lt;/a&gt;.
I mean, who couldn't fall in love with code like this all buttoned up for you automatically:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
private long _userId;

//// &amp;lt;summary&gt;
/// Gets the USER_ID column value.
/// &amp;lt;/summary&gt;
[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();
        }
    }
}
&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=316f5697-6b9e-466a-8d7f-f18070b95c6f" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,316f5697-6b9e-466a-8d7f-f18070b95c6f.aspx</comments>
      <category>Code</category>
      <category>Review</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=ef244248-d15c-4d5c-aac7-fa52aaee7905</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,ef244248-d15c-4d5c-aac7-fa52aaee7905.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,ef244248-d15c-4d5c-aac7-fa52aaee7905.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ef244248-d15c-4d5c-aac7-fa52aaee7905</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <strong>Create </strong>method and the standard <strong>ClientBase </strong>constructors
have been marked as internal to prevent creation of the client in any other way.
</p>
        <pre name="code" class="brush: c-sharp;">
public class ControlServiceClient : ClientBase&lt;IControlService&gt;, 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);
    }
}
</pre>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ef244248-d15c-4d5c-aac7-fa52aaee7905" />
      </body>
      <title>Enforce WCF Proxy Net.Tcp Config in Code</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,ef244248-d15c-4d5c-aac7-fa52aaee7905.aspx</guid>
      <link>http://www.tsjensen.com/blog/2009/03/15/Enforce+WCF+Proxy+NetTcp+Config+In+Code.aspx</link>
      <pubDate>Sun, 15 Mar 2009 15:29:31 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;strong&gt;Create &lt;/strong&gt;method and the standard &lt;strong&gt;ClientBase &lt;/strong&gt;constructors
have been marked as internal to prevent creation of the client in any other way.
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
public class ControlServiceClient : ClientBase&amp;lt;IControlService&gt;, 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);
    }
}
&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ef244248-d15c-4d5c-aac7-fa52aaee7905" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,ef244248-d15c-4d5c-aac7-fa52aaee7905.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=d36e8727-4a37-457a-9249-c7677fd56f60</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,d36e8727-4a37-457a-9249-c7677fd56f60.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,d36e8727-4a37-457a-9249-c7677fd56f60.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d36e8727-4a37-457a-9249-c7677fd56f60</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://www.codeproject.com/KB/cs/base36.aspx">Base
36 type sample on Code Project article by Steve Barker</a> that gave me a great start. 
</p>
        <p>
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. 
</p>
        <p>
I downloaded the code and went to work making the modifications. Here's the core of
the Base 30 struct:
</p>
        <pre name="code" class="brush: c-sharp;">
//removed are chars similar to numbers or another char when printed: I, J, O, Q, V, Z
private static List&lt;char&gt; alphaDigits = new List&lt;char&gt;(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) &gt; -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 &lt;= 29.
    if(NumericValue &gt; 29)
    {
        throw new InvalidBase30DigitValueException(NumericValue);
    }

    //Numbers:
    if(NumericValue &lt; 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&lt;char&gt;
        int index = NumericValue - 10;
        return alphaDigits[index]; //(char)(NumericValue + 55);
    }
}
</pre>
        <p>
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:
</p>
        <pre name="code" class="brush: c-sharp;">
/// &lt;summary&gt;
/// Convert a Guid to a set of four Base30 string values connected by a dash character.
/// &lt;/summary&gt;
/// &lt;param name="g"&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
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);
}

/// &lt;summary&gt;
/// Convert the Base30 set string produced by GuidToBase30Set back to a Guid.
/// &lt;/summary&gt;
/// &lt;param name="s"&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
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.");
    }
}
</pre>
        <p>
The code above gets you something like this:
</p>
        <blockquote>
          <p>
            <font face="Courier New">Common Guid string: <strong>b908d243-c1ac-4ea4-a954-121e4ab5c334<br /></strong>Base30Set from same: <strong>47PGC95-1S8WCHP-MPTTA1-16CUN8P</strong></font>
          </p>
        </blockquote>
        <p>
You can <a href="http://www.tsjensen.com/blog/content/binary/Base30.zip">download
the code here (Base30.zip 3.6 KB)</a>.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=d36e8727-4a37-457a-9249-c7677fd56f60" />
      </body>
      <title>Base 30 Type in C#</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,d36e8727-4a37-457a-9249-c7677fd56f60.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/11/25/Base+30+Type+In+C.aspx</link>
      <pubDate>Tue, 25 Nov 2008 00:27:19 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;a href="http://www.codeproject.com/KB/cs/base36.aspx"&gt;Base
36 type sample on Code Project article by Steve Barker&lt;/a&gt; that gave me a great start. 
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
I downloaded the code and went to work making the modifications. Here's the core of
the Base 30 struct:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
//removed are chars similar to numbers or another char when printed: I, J, O, Q, V, Z
private static List&amp;lt;char&gt; alphaDigits = new List&amp;lt;char&gt;(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) &gt; -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 &amp;lt;= 29.
    if(NumericValue &gt; 29)
    {
        throw new InvalidBase30DigitValueException(NumericValue);
    }

    //Numbers:
    if(NumericValue &amp;lt; 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&amp;lt;char&gt;
        int index = NumericValue - 10;
        return alphaDigits[index]; //(char)(NumericValue + 55);
    }
}
&lt;/pre&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;pre name="code" class="brush: c-sharp;"&gt;
/// &amp;lt;summary&gt;
/// Convert a Guid to a set of four Base30 string values connected by a dash character.
/// &amp;lt;/summary&gt;
/// &amp;lt;param name="g"&gt;&amp;lt;/param&gt;
/// &amp;lt;returns&gt;&amp;lt;/returns&gt;
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);
}

/// &amp;lt;summary&gt;
/// Convert the Base30 set string produced by GuidToBase30Set back to a Guid.
/// &amp;lt;/summary&gt;
/// &amp;lt;param name="s"&gt;&amp;lt;/param&gt;
/// &amp;lt;returns&gt;&amp;lt;/returns&gt;
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.");
    }
}
&lt;/pre&gt;
&lt;p&gt;
The code above gets you something like this:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;Common Guid string: &lt;strong&gt;b908d243-c1ac-4ea4-a954-121e4ab5c334&lt;br&gt;
&lt;/strong&gt;Base30Set from same: &lt;strong&gt;47PGC95-1S8WCHP-MPTTA1-16CUN8P&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
You can &lt;a href="http://www.tsjensen.com/blog/content/binary/Base30.zip"&gt;download
the code here (Base30.zip 3.6 KB)&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=d36e8727-4a37-457a-9249-c7677fd56f60" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,d36e8727-4a37-457a-9249-c7677fd56f60.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=d207b2e3-0971-4d68-b836-3fa17ec453cc</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,d207b2e3-0971-4d68-b836-3fa17ec453cc.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,d207b2e3-0971-4d68-b836-3fa17ec453cc.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d207b2e3-0971-4d68-b836-3fa17ec453cc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my first attempt at creating a real applicaiton using the new ASP.NET MVC project
template (<a href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=MVC&amp;referringTitle=Home">Codeplex
Preview 5</a>), 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 <strong>[Authorize(Roles = "user")]</strong> attribute,
the "out of the box" Login action did not redirect me to the that controller/action
combo once I had successfully logged in.
</p>
        <p>
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.
</p>
        <p>
          <strong>Here's the code for the form:</strong>
        </p>
        <pre class="csharpcode">
          <span class="kwrd">&lt;</span>
          <span class="html">form</span>
          <span class="attr">method</span>
          <span class="kwrd">="post"</span>
          <span class="attr">action</span>
          <span class="kwrd">="&lt;%=
Html.AttributeEncode(Url.Action("</span>
          <span class="attr">Login</span>
          <span class="kwrd">"))
%&gt;"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">div</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">table</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">tr</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">td</span>
          <span class="kwrd">&gt;</span> Username: <span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="asp">&lt;%</span>=
Html.TextBox(<span class="str">"username"</span>) <span class="asp">%&gt;</span><span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span> Password: <span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="asp">&lt;%</span>=
Html.Password(<span class="str">"password"</span>) <span class="asp">%&gt;</span><span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">input</span><span class="attr">type</span><span class="kwrd">="checkbox"</span><span class="attr">name</span><span class="kwrd">="rememberMe"</span><span class="attr">value</span><span class="kwrd">="true"</span><span class="kwrd">/&gt;</span> Remember
me? <span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="rem">&lt;!--
Added to handle the returnUrl --&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="asp">&lt;%</span>=
Html.Hidden(<span class="str">"returnUrl"</span>, ViewData[<span class="str">"ReturnUrl"</span>].ToString()) <span class="asp">%&gt;</span><span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;</span><span class="html">input</span><span class="attr">type</span><span class="kwrd">="submit"</span><span class="attr">value</span><span class="kwrd">="Login"</span><span class="kwrd">/&gt;</span><span class="kwrd">&lt;/</span><span class="html">td</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">tr</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">table</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">form</span><span class="kwrd">&gt;</span></pre>
        <p>
          <strong>Here's the code for the Login action:</strong>
        </p>
        <pre class="csharpcode">
          <span class="kwrd">public</span> ActionResult Login(<span class="kwrd">string</span> username, <span class="kwrd">string</span> password, <span class="kwrd">bool</span>?
rememberMe, <span class="kwrd">string</span> returnUrl) { ViewData[<span class="str">"Title"</span>]
= <span class="str">"Login"</span>; <span class="kwrd">string</span> url = (<span class="kwrd">string</span>.IsNullOrEmpty(returnUrl)
? Request.QueryString[<span class="str">"ReturnUrl"</span>] ?? <span class="kwrd">string</span>.Empty
: returnUrl) .Trim(<span class="str">'/'</span>); ViewData[<span class="str">"ReturnUrl"</span>]
= url; <span class="rem">// Non-POST requests should just display the Login form </span><span class="kwrd">if</span> (Request.HttpMethod
!= <span class="str">"POST"</span>) { <span class="kwrd">return</span> View(); } <span class="rem">//
Basic parameter validation</span> List&lt;<span class="kwrd">string</span>&gt; errors
= <span class="kwrd">new</span> List&lt;<span class="kwrd">string</span>&gt;(); <span class="kwrd">if</span> (String.IsNullOrEmpty(username))
{ errors.Add(<span class="str">"You must specify a username."</span>); } <span class="kwrd">if</span> (errors.Count
== 0) { <span class="rem">// Attempt to login</span><span class="kwrd">bool</span> loginSuccessful
= Provider.ValidateUser(username, password); <span class="kwrd">if</span> (loginSuccessful)
{ FormsAuth.SetAuthCookie(username, rememberMe ?? <span class="kwrd">false</span>); <span class="kwrd">if</span> (url
!= <span class="kwrd">null</span> &amp;&amp; url.Length &gt; 0) <span class="kwrd">return</span> RedirectToAction(<span class="str">"Index"</span>,
url); <span class="kwrd">else</span><span class="kwrd">return</span> RedirectToAction(<span class="str">"Index"</span>, <span class="str">"Home"</span>);
} <span class="kwrd">else</span> { errors.Add(<span class="str">"The username or password
provided is incorrect."</span>); } } <span class="rem">// If we got this far, something
failed, redisplay form</span> ViewData[<span class="str">"errors"</span>] = errors;
ViewData[<span class="str">"username"</span>] = username; <span class="kwrd">return</span> View();
} </pre>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=d207b2e3-0971-4d68-b836-3fa17ec453cc" />
      </body>
      <title>ASP.NET MVC RedirectUrl on Login</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,d207b2e3-0971-4d68-b836-3fa17ec453cc.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/09/17/ASPNET+MVC+RedirectUrl+On+Login.aspx</link>
      <pubDate>Wed, 17 Sep 2008 14:20:31 GMT</pubDate>
      <description>&lt;p&gt;
In my first attempt at creating a real applicaiton using the new ASP.NET MVC project
template (&lt;a href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=MVC&amp;amp;referringTitle=Home"&gt;Codeplex
Preview 5&lt;/a&gt;), 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 &lt;strong&gt;[Authorize(Roles = "user")]&lt;/strong&gt; attribute,
the "out of the box" Login action did not redirect me to the that controller/action
combo once I had successfully logged in.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Here's the code for the form:&lt;/strong&gt;
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;method&lt;/span&gt;&lt;span class="kwrd"&gt;="post"&lt;/span&gt; &lt;span class="attr"&gt;action&lt;/span&gt;&lt;span class="kwrd"&gt;="&amp;lt;%=
Html.AttributeEncode(Url.Action("&lt;/span&gt;&lt;span class="attr"&gt;Login&lt;/span&gt;&lt;span class="kwrd"&gt;"))
%&amp;gt;"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;table&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; Username: &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=
Html.TextBox(&lt;span class="str"&gt;"username"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; Password: &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=
Html.Password(&lt;span class="str"&gt;"password"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="checkbox"&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="rememberMe"&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; Remember
me? &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!--
Added to handle the returnUrl --&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=
Html.Hidden(&lt;span class="str"&gt;"returnUrl"&lt;/span&gt;, ViewData[&lt;span class="str"&gt;"ReturnUrl"&lt;/span&gt;].ToString()) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="submit"&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="Login"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;table&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Here's the code for the Login action:&lt;/strong&gt;
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Login(&lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; password, &lt;span class="kwrd"&gt;bool&lt;/span&gt;?
rememberMe, &lt;span class="kwrd"&gt;string&lt;/span&gt; returnUrl) { ViewData[&lt;span class="str"&gt;"Title"&lt;/span&gt;]
= &lt;span class="str"&gt;"Login"&lt;/span&gt;; &lt;span class="kwrd"&gt;string&lt;/span&gt; url = (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(returnUrl)
? Request.QueryString[&lt;span class="str"&gt;"ReturnUrl"&lt;/span&gt;] ?? &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty
: returnUrl) .Trim(&lt;span class="str"&gt;'/'&lt;/span&gt;); ViewData[&lt;span class="str"&gt;"ReturnUrl"&lt;/span&gt;]
= url; &lt;span class="rem"&gt;// Non-POST requests should just display the Login form &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (Request.HttpMethod
!= &lt;span class="str"&gt;"POST"&lt;/span&gt;) { &lt;span class="kwrd"&gt;return&lt;/span&gt; View(); } &lt;span class="rem"&gt;//
Basic parameter validation&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; errors
= &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(); &lt;span class="kwrd"&gt;if&lt;/span&gt; (String.IsNullOrEmpty(username))
{ errors.Add(&lt;span class="str"&gt;"You must specify a username."&lt;/span&gt;); } &lt;span class="kwrd"&gt;if&lt;/span&gt; (errors.Count
== 0) { &lt;span class="rem"&gt;// Attempt to login&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; loginSuccessful
= Provider.ValidateUser(username, password); &lt;span class="kwrd"&gt;if&lt;/span&gt; (loginSuccessful)
{ FormsAuth.SetAuthCookie(username, rememberMe ?? &lt;span class="kwrd"&gt;false&lt;/span&gt;); &lt;span class="kwrd"&gt;if&lt;/span&gt; (url
!= &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; url.Length &amp;gt; 0) &lt;span class="kwrd"&gt;return&lt;/span&gt; RedirectToAction(&lt;span class="str"&gt;"Index"&lt;/span&gt;,
url); &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; RedirectToAction(&lt;span class="str"&gt;"Index"&lt;/span&gt;, &lt;span class="str"&gt;"Home"&lt;/span&gt;);
} &lt;span class="kwrd"&gt;else&lt;/span&gt; { errors.Add(&lt;span class="str"&gt;"The username or password
provided is incorrect."&lt;/span&gt;); } } &lt;span class="rem"&gt;// If we got this far, something
failed, redisplay form&lt;/span&gt; ViewData[&lt;span class="str"&gt;"errors"&lt;/span&gt;] = errors;
ViewData[&lt;span class="str"&gt;"username"&lt;/span&gt;] = username; &lt;span class="kwrd"&gt;return&lt;/span&gt; View();
} &lt;/pre&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=d207b2e3-0971-4d68-b836-3fa17ec453cc" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,d207b2e3-0971-4d68-b836-3fa17ec453cc.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=22b6ed69-fe4f-4e2a-959f-95c7a0175b54</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,22b6ed69-fe4f-4e2a-959f-95c7a0175b54.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,22b6ed69-fe4f-4e2a-959f-95c7a0175b54.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=22b6ed69-fe4f-4e2a-959f-95c7a0175b54</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've just installed the plugin <a href="http://blogs.msdn.com/mikeormond/archive/2006/08/24/716900.aspx">blogged
about by Mike Ormond</a> and here's an example of it's output taken from code in the <a href="http://www.codeplex.com/atrax">Atrax
project I've just published to Codeplex</a>.
</p>
        <pre class="csharpcode">
          <span class="kwrd">namespace</span> Atrax.Library { [DataContract,
Serializable] <span class="kwrd">public</span><span class="kwrd">class</span> QueryResult
{ <span class="rem">/// &lt;summary&gt;</span><span class="rem">/// The original
query sent by the client.</span><span class="rem">/// &lt;/summary&gt;</span> [DataMember] <span class="kwrd">public</span> Query
Query { get; set; } <span class="rem">/// &lt;summary&gt;</span><span class="rem">///
Status code sent back to query client's callback url.</span><span class="rem">///
&lt;/summary&gt;</span> [DataMember] <span class="kwrd">public</span><span class="kwrd">string</span> StatusCode
{ get; set; } <span class="rem">/// &lt;summary&gt;</span><span class="rem">/// Status
description sent back to query client's callback url.</span><span class="rem">///
&lt;/summary&gt;</span> [DataMember] <span class="kwrd">public</span><span class="kwrd">string</span> StatusDescription
{ get; set; } <span class="rem">/// &lt;summary&gt;</span><span class="rem">/// The
XML schema for the result XML.</span><span class="rem">/// &lt;/summary&gt;</span> [DataMember] <span class="kwrd">public</span><span class="kwrd">string</span> ResultSchema
{ get; set; } <span class="rem">/// &lt;summary&gt;</span><span class="rem">/// The
result produced by the query processor, usually XML.</span><span class="rem">///
&lt;/summary&gt;</span> [DataMember] <span class="kwrd">public</span><span class="kwrd">string</span> Result
{ get; set; } } } </pre>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=22b6ed69-fe4f-4e2a-959f-95c7a0175b54" />
      </body>
      <title>Live Writer Source Code Format Plugin</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,22b6ed69-fe4f-4e2a-959f-95c7a0175b54.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/09/09/Live+Writer+Source+Code+Format+Plugin.aspx</link>
      <pubDate>Tue, 09 Sep 2008 18:22:07 GMT</pubDate>
      <description>&lt;p&gt;
I've just installed the plugin &lt;a href="http://blogs.msdn.com/mikeormond/archive/2006/08/24/716900.aspx"&gt;blogged
about by Mike Ormond&lt;/a&gt; and here's an example of it's output taken from code in the &lt;a href="http://www.codeplex.com/atrax"&gt;Atrax
project I've just published to Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Atrax.Library { [DataContract,
Serializable] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; QueryResult
{ &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;/// The original
query sent by the client.&lt;/span&gt; &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt; [DataMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; Query
Query { get; set; } &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;///
Status code sent back to query client's callback url.&lt;/span&gt; &lt;span class="rem"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; [DataMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; StatusCode
{ get; set; } &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;/// Status
description sent back to query client's callback url.&lt;/span&gt; &lt;span class="rem"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; [DataMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; StatusDescription
{ get; set; } &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;/// The
XML schema for the result XML.&lt;/span&gt; &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt; [DataMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ResultSchema
{ get; set; } &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span class="rem"&gt;/// The
result produced by the query processor, usually XML.&lt;/span&gt; &lt;span class="rem"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt; [DataMember] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Result
{ get; set; } } } &lt;/pre&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=22b6ed69-fe4f-4e2a-959f-95c7a0175b54" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,22b6ed69-fe4f-4e2a-959f-95c7a0175b54.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=2980bf7d-88eb-4c3e-b15f-8c91321416ea</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,2980bf7d-88eb-4c3e-b15f-8c91321416ea.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,2980bf7d-88eb-4c3e-b15f-8c91321416ea.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2980bf7d-88eb-4c3e-b15f-8c91321416ea</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Two and a half years ago I wrote an implementation in C# of an algorithm published
in 2003 in a <a href="http://www.miv.t.u-tokyo.ac.jp/papers/matsuoIJAIT04.pdf">short
academic paper</a> by <a href="http://ymatsuo.com/top_eng.htm">Yutaka Matsuo</a> and <a href="http://www.miv.t.u-tokyo.ac.jp/ishizuka/eng.html">Mitsuru
Ishizuka</a> 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.
</p>
        <p>
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 <a href="http://www.apache.org/licenses/">Apache
2.0 license</a>. You can get the code in the Atrax.Html project, a part of the entire
Atrax project which I've just released, at <a href="http://www.codeplex.com/atrax">http://www.codeplex.com/atrax</a>.
Here's the core of the code.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
terms <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[termsG.Count];<br />
termsG.Values.CopyTo(terms, 0); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//gives
terms array where last term is the MAX g in G</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> w <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> terms)<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> sumZ <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">for</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> i <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;
i &lt; terms.Length <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> 1;
i++) <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//do
calcs for all but MAX</span><br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> g <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> terms[i];<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (w
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> g) <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//skip
where on the diagonal</span><br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> nw <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> termNw[w];<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> Pg <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> termPg[g];<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> D <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> nw <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">*</span> Pg;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (D
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0.0m)<br />
            {<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> Fwg <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> termFwg[w][terms[i]];<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> T <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Fwg <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> D;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> Z <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (T <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">*</span> T) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/</span> D;<br />
                sumZ
+= Z;<br />
            }<br />
        }<br />
    }<br />
    termsX2[w] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> sumZ;<br />
}<br /><br />
SortedDictionary&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;
sortedX2 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SortedDictionary&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;();<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span> (KeyValuePair&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span>&gt;
pair <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> termsX2)<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">decimal</span> x2 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> pair.Value;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">while</span> (sortedX2.ContainsKey(x2))<br />
    {<br />
        x2 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> x2 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> 0.00001m;<br />
    }<br />
    sortedX2.Add(x2, pair.Key);<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//now
get simple array of values as lowest to highest X2 terms</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
x2Terms <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[sortedX2.Count];<br />
sortedX2.Values.CopyTo(x2Terms, 0);<br /></span>
        </p>
        <p>
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 <a href="http://www.codeplex.com/atrax">Atrax
project page on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2980bf7d-88eb-4c3e-b15f-8c91321416ea" />
      </body>
      <title>Atrax Keyword Extraction Algorithm</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,2980bf7d-88eb-4c3e-b15f-8c91321416ea.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/09/07/Atrax+Keyword+Extraction+Algorithm.aspx</link>
      <pubDate>Sun, 07 Sep 2008 20:12:27 GMT</pubDate>
      <description>&lt;p&gt;
Two and a half years ago I wrote an implementation in C# of an algorithm published
in 2003 in a&amp;nbsp;&lt;a href="http://www.miv.t.u-tokyo.ac.jp/papers/matsuoIJAIT04.pdf"&gt;short
academic paper&lt;/a&gt; by &lt;a href="http://ymatsuo.com/top_eng.htm"&gt;Yutaka Matsuo&lt;/a&gt; and &lt;a href="http://www.miv.t.u-tokyo.ac.jp/ishizuka/eng.html"&gt;Mitsuru
Ishizuka&lt;/a&gt; in the International Journal of Artificial Intelligence Tools. Of course,
the algorithm is not&amp;nbsp;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.
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://www.apache.org/licenses/"&gt;Apache
2.0 license&lt;/a&gt;. You can get the code in the Atrax.Html project, a part of the entire
Atrax project which I've just released, at &lt;a href="http://www.codeplex.com/atrax"&gt;http://www.codeplex.com/atrax&lt;/a&gt;.
Here's the core of the code.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
terms &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[termsG.Count];&lt;br&gt;
termsG.Values.CopyTo(terms, 0); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//gives
terms array where last term is the MAX g in G&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;foreach&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; w &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; terms)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; sumZ &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;for&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; i &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;
i &amp;lt; terms.Length &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; 1;
i++) &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//do
calcs for all but MAX&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; g &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; terms[i];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (w
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; g) &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//skip
where on the diagonal&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; nw &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; termNw[w];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; Pg &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; termPg[g];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; D &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; nw &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;*&lt;/span&gt; Pg;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (D
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0.0m)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; Fwg &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; termFwg[w][terms[i]];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; T &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Fwg &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; D;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; Z &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; (T &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;*&lt;/span&gt; T) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&lt;/span&gt; D;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sumZ
+= Z;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;termsX2[w] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; sumZ;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
SortedDictionary&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;
sortedX2 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SortedDictionary&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;foreach&lt;/span&gt; (KeyValuePair&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt;&amp;gt;
pair &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; termsX2)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;decimal&lt;/span&gt; x2 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; pair.Value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;while&lt;/span&gt; (sortedX2.ContainsKey(x2))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x2 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; x2 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; 0.00001m;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sortedX2.Add(x2, pair.Key);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//now
get simple array of values as lowest to highest X2 terms&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
x2Terms &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[sortedX2.Count];&lt;br&gt;
sortedX2.Values.CopyTo(x2Terms, 0);&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://www.codeplex.com/atrax"&gt;Atrax
project page on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2980bf7d-88eb-4c3e-b15f-8c91321416ea" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,2980bf7d-88eb-4c3e-b15f-8c91321416ea.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=460888b4-f5e9-4337-9c16-232da71414d0</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,460888b4-f5e9-4337-9c16-232da71414d0.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,460888b4-f5e9-4337-9c16-232da71414d0.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=460888b4-f5e9-4337-9c16-232da71414d0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I want to thank <a href="http://weblogs.asp.net/scottgu/">Scott Guthrie</a> and <a href="http://www.hanselman.com/blog/">Scott
Hanselman</a> and the whole <a href="http://www.codeplex.com/aspnet">ASP.NET MVC</a> team
for making web development fun again.
</p>
        <p>
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 <a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15389">MVC
Preview 4</a> to the test. I was not disappointed.
</p>
        <p>
I mean, who could not fall in love with the elegant simplicity of this view?
</p>
        <font color="#0000ff" size="3">
          <font color="#0000ff" size="3">
            <p>
              <font face="Courier New" size="2">&lt;</font>
            </p>
          </font>
        </font>
        <font face="Courier New">
          <font color="#a31515">
            <font color="#a31515">tr</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;<br /></font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;</font>
          </font>Current
password:<font color="#0000ff"><font color="#0000ff">&lt;/</font></font><font color="#a31515"><font color="#a31515">td</font></font><font color="#0000ff"><font color="#0000ff">&gt;<br /></font></font></font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;</font>
          </font>&lt;%<font color="#0000ff"><font color="#0000ff">=</font></font> Html.Password(<font color="#a31515"><font color="#a31515">"currentPassword"</font></font>)
%&gt;<font color="#0000ff"><font color="#0000ff">&lt;/</font></font><font color="#a31515"><font color="#a31515">td</font></font></font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;/</font>
          </font>
        </font>
        <font color="#a31515">
          <font face="Courier New" color="#a31515">tr</font>
        </font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;</font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#a31515">
            <font color="#a31515">tr</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;<br /></font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;</font>
          </font>New
password:<font color="#0000ff"><font color="#0000ff">&lt;/</font></font><font color="#a31515"><font color="#a31515">td</font></font><font color="#0000ff"><font color="#0000ff">&gt;<br /></font></font></font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;</font>
          </font>&lt;%<font color="#0000ff"><font color="#0000ff">=</font></font> Html.Password(<font color="#a31515"><font color="#a31515">"newPassword"</font></font>)
%&gt;<font color="#0000ff"><font color="#0000ff">&lt;/</font></font><font color="#a31515"><font color="#a31515">td</font></font></font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;/</font>
          </font>
        </font>
        <font color="#a31515">
          <font face="Courier New" color="#a31515">tr</font>
        </font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;</font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#a31515">
            <font color="#a31515">tr</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;<br /></font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;</font>
          </font>Confirm
new password:<font color="#0000ff"><font color="#0000ff">&lt;/</font></font><font color="#a31515"><font color="#a31515">td</font></font><font color="#0000ff"><font color="#0000ff">&gt;<br /></font></font></font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;</font>
          </font>&lt;%<font color="#0000ff"><font color="#0000ff">=</font></font> Html.Password(<font color="#a31515"><font color="#a31515">"confirmPassword"</font></font>)
%&gt;<font color="#0000ff"><font color="#0000ff">&lt;/</font></font><font color="#a31515"><font color="#a31515">td</font></font></font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;/</font>
          </font>
        </font>
        <font color="#a31515">
          <font face="Courier New" color="#a31515">tr</font>
        </font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;</font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#a31515">
            <font color="#a31515">tr</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;<br /></font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;&lt;/</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;<br /></font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#0000ff">
            <font color="#0000ff"> 
&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;&lt;</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">input</font>
          </font>
          <font color="#ff0000">
            <font color="#ff0000">type</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">="submit"</font>
          </font>
          <font color="#ff0000">
            <font color="#ff0000">value</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">="Change
Password"</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">/&gt;&lt;/</font>
          </font>
          <font color="#a31515">
            <font color="#a31515">td</font>
          </font>
        </font>
        <font color="#0000ff">
          <font color="#0000ff">
            <font face="Courier New">&gt;<br /></font>
            <font face="Courier New">&lt;/</font>
          </font>
        </font>
        <font face="Courier New">
          <font color="#a31515">
            <font color="#a31515">tr</font>
          </font>
          <font color="#0000ff">
            <font color="#0000ff">&gt;
</font>
          </font>
        </font>
        <p>
Handled by this controller:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[Authorize]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> ActionResult
ChangePassword(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> currentPassword, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> newPassword, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> confirmPassword)<br />
{<br /><br />
    ViewData[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Title"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Change
Password"</span>;<br />
    ViewData[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"PasswordLength"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Provider.MinRequiredPasswordLength;<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Non-POST requests should just display the ChangePassword form </span><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (Request.HttpMethod
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"POST"</span>)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> View();<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Basic parameter validation</span><br />
    List&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;
errors <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> List&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;();<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (String.IsNullOrEmpty(currentPassword))<br />
    {<br />
        errors.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"You
must specify a current password."</span>);<br />
    }<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (newPassword
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span> ||
newPassword.Length &lt; Provider.MinRequiredPasswordLength)<br />
    {<br />
        errors.Add(String.Format(CultureInfo.InvariantCulture,<br />
                    <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"You
must specify a new password of {0} or more characters."</span>,<br />
                    Provider.MinRequiredPasswordLength));<br />
    }<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (!String.Equals(newPassword,
confirmPassword, StringComparison.Ordinal))<br />
    {<br />
        errors.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"The
new password and confirmation password do not match."</span>);<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (errors.Count
== 0)<br />
    {<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Attempt to change password</span><br />
        MembershipUser currentUser <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Provider.GetUser(User.Identity.Name, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/*
userIsOnline */</span>);<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> changeSuccessful <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span><br />
        {<br />
            changeSuccessful <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> currentUser.ChangePassword(currentPassword,
newPassword);<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span><br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
An exception is thrown if the new password does not meet the provider's requirements</span><br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (changeSuccessful)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> RedirectToAction(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"ChangePasswordSuccess"</span>);<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
        {<br />
            errors.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"The
current password is incorrect or the new password is invalid."</span>);<br />
        }<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
If we got this far, something failed, redisplay form</span><br />
    ViewData[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"errors"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> errors;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> View();<br />
}<br /></span>
        </p>
        <p>
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.
</p>
        <p>
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. 
</p>
        <p>
ASP.NET never looked better!
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=460888b4-f5e9-4337-9c16-232da71414d0" />
      </body>
      <title>ASP.NET MVC Making Web Development Fun Again</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,460888b4-f5e9-4337-9c16-232da71414d0.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/08/05/ASPNET+MVC+Making+Web+Development+Fun+Again.aspx</link>
      <pubDate>Tue, 05 Aug 2008 01:03:06 GMT</pubDate>
      <description>&lt;p&gt;
I want to thank &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt; and &lt;a href="http://www.hanselman.com/blog/"&gt;Scott
Hanselman&lt;/a&gt; and the whole &lt;a href="http://www.codeplex.com/aspnet"&gt;ASP.NET&amp;nbsp;MVC&lt;/a&gt; team
for making web development fun again.
&lt;/p&gt;
&lt;p&gt;
The simplicity of Rails, the power of .NET, and so much more. I've been reading the
posts and watching some of the&amp;nbsp;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 &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15389"&gt;MVC
Preview 4&lt;/a&gt; to the test. I was not disappointed.
&lt;/p&gt;
&lt;p&gt;
I mean, who could not fall in love with the elegant simplicity of this view?
&lt;/p&gt;
&lt;font color=#0000ff size=3&gt;&lt;font color=#0000ff size=3&gt; 
&lt;p&gt;
&lt;font face="Courier New" size=2&gt;&amp;lt;&lt;/font&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;Current
password:&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&amp;lt;%&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;=&lt;/font&gt;&lt;/font&gt; Html.Password(&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;"currentPassword"&lt;/font&gt;&lt;/font&gt;)
%&amp;gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font face="Courier New" color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;New
password:&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&amp;lt;%&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;=&lt;/font&gt;&lt;/font&gt; Html.Password(&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;"newPassword"&lt;/font&gt;&lt;/font&gt;)
%&amp;gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font face="Courier New" color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;Confirm
new password:&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&amp;lt;%&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;=&lt;/font&gt;&lt;/font&gt; Html.Password(&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;"confirmPassword"&lt;/font&gt;&lt;/font&gt;)
%&amp;gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font face="Courier New" color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;nbsp;
&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;input&lt;/font&gt;&lt;/font&gt; &lt;font color=#ff0000&gt;&lt;font color=#ff0000&gt;type&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;="submit"&lt;/font&gt;&lt;/font&gt; &lt;font color=#ff0000&gt;&lt;font color=#ff0000&gt;value&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;="Change
Password"&lt;/font&gt;&lt;/font&gt; &lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;/&amp;gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;td&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;lt;/&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#a31515&gt;&lt;font color=#a31515&gt;tr&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font color=#0000ff&gt;&amp;gt;&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;
Handled by this controller:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[Authorize]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; ActionResult
ChangePassword(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; currentPassword, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; newPassword, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; confirmPassword)&lt;br&gt;
{&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ViewData[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Title"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Change
Password"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ViewData[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"PasswordLength"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Provider.MinRequiredPasswordLength;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Non-POST requests should just display the ChangePassword form &lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (Request.HttpMethod
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"POST"&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; View();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Basic parameter validation&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;
errors &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (String.IsNullOrEmpty(currentPassword))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"You
must specify a current password."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (newPassword
== &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt; ||
newPassword.Length &amp;lt; Provider.MinRequiredPasswordLength)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(String.Format(CultureInfo.InvariantCulture,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"You
must specify a new password of {0} or more characters."&lt;/span&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Provider.MinRequiredPasswordLength));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (!String.Equals(newPassword,
confirmPassword, StringComparison.Ordinal))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"The
new password and confirmation password do not match."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (errors.Count
== 0)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Attempt to change password&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MembershipUser currentUser &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Provider.GetUser(User.Identity.Name, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/*
userIsOnline */&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; changeSuccessful &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;changeSuccessful &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; currentUser.ChangePassword(currentPassword,
newPassword);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;catch&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
An exception is thrown if the new password does not meet the provider's requirements&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (changeSuccessful)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; RedirectToAction(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"ChangePasswordSuccess"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"The
current password is incorrect or the new password is invalid."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
If we got this far, something failed, redisplay form&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ViewData[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"errors"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; errors;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; View();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
ASP.NET never looked better!
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=460888b4-f5e9-4337-9c16-232da71414d0" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,460888b4-f5e9-4337-9c16-232da71414d0.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=240221cb-3343-473d-86c6-3ccb251bec9c</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,240221cb-3343-473d-86c6-3ccb251bec9c.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,240221cb-3343-473d-86c6-3ccb251bec9c.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=240221cb-3343-473d-86c6-3ccb251bec9c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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 <a href="http://www.idesign.net/">http://www.idesign.net/</a> web site. If
you need help with your WCF work, I urge you to contact them.
</p>
        <p>
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.
</p>
        <p>
          <strong>Framework/Architecture</strong>
          <br />
The architecture of this little test application is simple. 
</p>
        <ul>
          <li>
            <strong>MyWcfService</strong> - (server) A Windows service application 
</li>
          <li>
            <strong>MyWcfMon </strong>- (client) A Windows Forms application with a simplistic
test 
</li>
          <li>
            <strong>MyWcfLib </strong>- A class library defining the service contract used by
client and server</li>
        </ul>
        <p>
          <strong>MyWcfLib</strong>
          <br />
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).
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[ServiceContract]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">interface</span> IMyWcfServiceControl<br />
{<br />
    [OperationContract]<br />
    MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command);<br />
}<br /><br />
[DataContract]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyWcfServiceCommand<br />
{<br />
    [DataMember]<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Command
{ get; set; }<br />
}<br /><br />
[DataContract]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyWcfServiceResponse<br />
{<br />
    [DataMember]<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Response
{ get; set; }<br />
}<br /></span>
        </p>
        <p>
As you can see, we have a simple service contract with a single operation and a simple
command object taken and response object returned.
</p>
        <p>
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.
</p>
        <p>
          <strong>MyWcfService<br /></strong>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.
</p>
        <p>
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.
</p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Uri
tcpBaseAddress <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Uri(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>.Format(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"net.tcp://localhost:{0}/"</span>,
m_port));<br />
serviceHost <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ServiceHost(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(MyWcfServer),
tcpBaseAddress);<br /><br />
NetTcpBinding tcpBinding <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> NetTcpBinding(SecurityMode.Transport, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
tcpBinding.Security.Transport.ClientCredentialType <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> TcpClientCredentialType.Windows;<br />
tcpBinding.Security.Transport.ProtectionLevel <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ProtectionLevel.EncryptAndSign;<br /><br />
serviceHost.AddServiceEndpoint(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(IMyWcfServiceControl),
tcpBinding, 
<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>.Format(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"net.tcp://localhost:{0}/MyWcfServiceControl"</span>,
m_port));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//this
is the default but good to know</span><br />
serviceHost.Authorization.PrincipalPermissionMode <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> PrincipalPermissionMode.UseWindowsGroups;<br /><br />
serviceHost.Open();</span>
          </p>
        </span>
        <p>
That's it. We're now configured. Not so hard. Not really any more difficult than raw
.NET remoting configuration. In fact, probably easier. 
</p>
        <p>
Of course, the Stop method on the ServiceRunner class executes the Close method on
the service host. 
</p>
        <p>
Now to the implementation of the IMyWcfServiceControl interface in the MyWcfServer.cs
file:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyWcfServer
: IMyWcfServiceControl<br />
{<br />
    [PrincipalPermission(SecurityAction.Demand, Role <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@"nbdev2\allwcfgroup"</span>)]<br />
    [PrincipalPermission(SecurityAction.Demand, Role <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@"nbdev2\mywcfgroup"</span>)]<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> MyWcfServiceResponse
ExecuteCommand(MyWcfServiceCommand command)<br />
    {<br />
        MyWcfServiceResponse response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (IsAuthorized())<br />
        {<br />
            response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceResponse() 
<br />
            { 
<br />
                Response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> command.Command <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
response "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> DateTime.Now.ToLongTimeString() 
<br />
            };<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
        {<br />
            response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceResponse() 
<br />
            { 
<br />
                Response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Error:
user not authorized"</span><br />
            };<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> response;<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> IsAuthorized()<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//The
PrincipalPermission attributes are an OR proposition.</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//The
following enforces the AND requirement.</span><br />
        IPrincipal p <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Thread.CurrentPrincipal;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (p.IsInRole(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@"nbdev2\allwcfgroup"</span>)
&amp;&amp; p.IsInRole(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@"nbdev2\mywcfgroup"</span>))<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>;<br />
    }<br />
}<br /></span>
        </p>
        <p>
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. 
</p>
        <p>
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...
</p>
        <p>
          <strong>MyWcfMon</strong>
          <br />
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:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span> MyWcfServiceResponse
ExecuteCommand(MyWcfServiceCommand command)<br />
{<br />
    NetTcpBinding tcpBinding <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> NetTcpBinding(SecurityMode.Transport, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
    tcpBinding.Security.Transport.ClientCredentialType <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> TcpClientCredentialType.Windows;<br />
    tcpBinding.Security.Transport.ProtectionLevel <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ProtectionLevel.EncryptAndSign;<br /><br />
    EndpointAddress endpointAddress <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> EndpointAddress(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>.Format(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"net.tcp://{0}:{1}/MyWcfServiceControl"</span>,
m_server, m_port));<br />
    <br />
    MyWcfServiceControlClient proxy <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceControlClient(tcpBinding,
endpointAddress);<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//Note:
current user credentials are used unless we use runtime provided credentials like
this </span><br />
    NetworkCredential credentials <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> NetworkCredential(m_userName,
m_password);<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (m_domain
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)
credentials <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> NetworkCredential(m_userName,
m_password, m_domain);<br />
    proxy.ClientCredentials.Windows.ClientCredential <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> credentials;<br />
    <br />
    MyWcfServiceResponse response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> proxy.ExecuteCommand(command);<br />
    <br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//if
proxy is in Faulted state, Close throws CommunicationObjectFaultedException</span><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (proxy.State
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> CommunicationState.Faulted)
proxy.Close();<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> response;<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyWcfServiceControlClient
: ClientBase&lt;IMyWcfServiceControl&gt;, IMyWcfServiceControl<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> MyWcfServiceControlClient(Binding
binding, EndpointAddress address) : <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>(binding,
address) { }<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> MyWcfServiceResponse
ExecuteCommand(MyWcfServiceCommand command)<br />
    {<br />
        MyWcfServiceResponse response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span><br />
        {<br />
            response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Channel.ExecuteCommand(command);<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span> (SecurityNegotiationException
ne)<br />
        {<br />
            response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceResponse()
{ Response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ne.Message
};<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span> (SecurityAccessDeniedException
ae)<br />
        {<br />
            response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceResponse()
{ Response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ae.Message
};<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> response;<br />
    }<br />
}</span>
        </p>
        <p>
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.
</p>
        <p>
So now, we have a simple Form that does this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> userName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> txtUserName.Text;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> password <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> txtPassword.Text;<br />
MyWcfServiceProxy sp <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceProxy(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"localhost"</span>,
8239, userName, password, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>);<br />
MyWcfServiceCommand command <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWcfServiceCommand()<br />
{<br />
    Command <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Hello
world."</span><br />
};<br />
MyWcfServiceResponse response <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> sp.ExecuteCommand(command);<br />
lblTest.Text <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> response.Response;</span>
        </p>
        <p>
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.
</p>
        <p>
If you find this useful, I'd love to hear about it. The code can be found here <a href="http://www.netbrick.net/blog/content/binary/MyWcfService.zip">MyWcfService.zip
(31.55 KB)</a> under the MIT license. Enjoy! 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=240221cb-3343-473d-86c6-3ccb251bec9c" />
      </body>
      <title>Windows Form Talks to Windows Service via WCF without Config File</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,240221cb-3343-473d-86c6-3ccb251bec9c.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/03/27/Windows+Form+Talks+To+Windows+Service+Via+WCF+Without+Config+File.aspx</link>
      <pubDate>Thu, 27 Mar 2008 20:29:41 GMT</pubDate>
      <description>&lt;p&gt;
I am fascinated with&amp;nbsp;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.
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://www.idesign.net/"&gt;http://www.idesign.net/&lt;/a&gt; web site. If
you need help with your WCF work, I urge you to contact them.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Framework/Architecture&lt;/strong&gt;
&lt;br&gt;
The architecture of this little test application is simple. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MyWcfService&lt;/strong&gt; - (server) A Windows service application 
&lt;li&gt;
&lt;strong&gt;MyWcfMon &lt;/strong&gt;- (client) A Windows Forms application with a simplistic
test 
&lt;li&gt;
&lt;strong&gt;MyWcfLib &lt;/strong&gt;- A class library defining the service contract used by
client and server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;MyWcfLib&lt;/strong&gt;
&lt;br&gt;
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).
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[ServiceContract]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;interface&lt;/span&gt; IMyWcfServiceControl&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[OperationContract]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyWcfServiceResponse ExecuteCommand(MyWcfServiceCommand command);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[DataContract]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyWcfServiceCommand&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[DataMember]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Command
{ get; set; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[DataContract]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyWcfServiceResponse&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[DataMember]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Response
{ get; set; }&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, we have a simple service contract with a single operation and a simple
command object taken and response object returned.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;MyWcfService&lt;br&gt;
&lt;/strong&gt;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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Uri
tcpBaseAddress &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Uri(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;.Format(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"net.tcp://localhost:{0}/"&lt;/span&gt;,
m_port));&lt;br&gt;
serviceHost &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ServiceHost(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(MyWcfServer),
tcpBaseAddress);&lt;br&gt;
&lt;br&gt;
NetTcpBinding tcpBinding &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; NetTcpBinding(SecurityMode.Transport, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
tcpBinding.Security.Transport.ClientCredentialType &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; TcpClientCredentialType.Windows;&lt;br&gt;
tcpBinding.Security.Transport.ProtectionLevel &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ProtectionLevel.EncryptAndSign;&lt;br&gt;
&lt;br&gt;
serviceHost.AddServiceEndpoint(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(IMyWcfServiceControl),
tcpBinding, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;.Format(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"net.tcp://localhost:{0}/MyWcfServiceControl"&lt;/span&gt;,
m_port));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//this
is the default but good to know&lt;/span&gt;
&lt;br&gt;
serviceHost.Authorization.PrincipalPermissionMode &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; PrincipalPermissionMode.UseWindowsGroups;&lt;br&gt;
&lt;br&gt;
serviceHost.Open();&lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt; 
&lt;p&gt;
That's it. We're now configured. Not so hard. Not really any more difficult than raw
.NET remoting configuration. In fact, probably easier. 
&lt;/p&gt;
&lt;p&gt;
Of course, the Stop method on the ServiceRunner class executes the Close method on
the service host. 
&lt;/p&gt;
&lt;p&gt;
Now to the implementation of the IMyWcfServiceControl interface in the MyWcfServer.cs
file:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyWcfServer
: IMyWcfServiceControl&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[PrincipalPermission(SecurityAction.Demand, Role &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;@"nbdev2\allwcfgroup"&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[PrincipalPermission(SecurityAction.Demand, Role &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;@"nbdev2\mywcfgroup"&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; MyWcfServiceResponse
ExecuteCommand(MyWcfServiceCommand command)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyWcfServiceResponse response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (IsAuthorized())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceResponse() 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; command.Command &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
response "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; DateTime.Now.ToLongTimeString() 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceResponse() 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Error:
user not authorized"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; response;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; IsAuthorized()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//The
PrincipalPermission attributes are an OR proposition.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//The
following enforces the AND requirement.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IPrincipal p &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Thread.CurrentPrincipal;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (p.IsInRole(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;@"nbdev2\allwcfgroup"&lt;/span&gt;)
&amp;amp;&amp;amp; p.IsInRole(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;@"nbdev2\mywcfgroup"&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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...
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;MyWcfMon&lt;/strong&gt;
&lt;br&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; MyWcfServiceResponse
ExecuteCommand(MyWcfServiceCommand command)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NetTcpBinding tcpBinding &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; NetTcpBinding(SecurityMode.Transport, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tcpBinding.Security.Transport.ClientCredentialType &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; TcpClientCredentialType.Windows;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tcpBinding.Security.Transport.ProtectionLevel &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ProtectionLevel.EncryptAndSign;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EndpointAddress endpointAddress &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; EndpointAddress(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;.Format(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"net.tcp://{0}:{1}/MyWcfServiceControl"&lt;/span&gt;,
m_server, m_port));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyWcfServiceControlClient proxy &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceControlClient(tcpBinding,
endpointAddress);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Note:
current user credentials are used unless we use runtime provided credentials like
this &lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NetworkCredential credentials &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; NetworkCredential(m_userName,
m_password);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (m_domain
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)
credentials &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; NetworkCredential(m_userName,
m_password, m_domain);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy.ClientCredentials.Windows.ClientCredential &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; credentials;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyWcfServiceResponse response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; proxy.ExecuteCommand(command);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//if
proxy is in Faulted state, Close throws CommunicationObjectFaultedException&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (proxy.State
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; CommunicationState.Faulted)
proxy.Close();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; response;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyWcfServiceControlClient
: ClientBase&amp;lt;IMyWcfServiceControl&amp;gt;, IMyWcfServiceControl&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; MyWcfServiceControlClient(Binding
binding, EndpointAddress address) : &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;base&lt;/span&gt;(binding,
address) { }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; MyWcfServiceResponse
ExecuteCommand(MyWcfServiceCommand command)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyWcfServiceResponse response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Channel.ExecuteCommand(command);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;catch&lt;/span&gt; (SecurityNegotiationException
ne)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceResponse()
{ Response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ne.Message
};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;catch&lt;/span&gt; (SecurityAccessDeniedException
ae)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceResponse()
{ Response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ae.Message
};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; response;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
So now, we have a simple Form that does this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; userName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; txtUserName.Text;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; password &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; txtPassword.Text;&lt;br&gt;
MyWcfServiceProxy sp &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceProxy(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"localhost"&lt;/span&gt;,
8239, userName, password, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;);&lt;br&gt;
MyWcfServiceCommand command &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWcfServiceCommand()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Command &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Hello
world."&lt;/span&gt;
&lt;br&gt;
};&lt;br&gt;
MyWcfServiceResponse response &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; sp.ExecuteCommand(command);&lt;br&gt;
lblTest.Text &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; response.Response;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
If you find this useful, I'd love to hear about it. The code can be found here &lt;a href="http://www.netbrick.net/blog/content/binary/MyWcfService.zip"&gt;MyWcfService.zip
(31.55 KB)&lt;/a&gt;&amp;nbsp;under the MIT license. Enjoy! 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=240221cb-3343-473d-86c6-3ccb251bec9c" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,240221cb-3343-473d-86c6-3ccb251bec9c.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=f730239f-5be1-4cb2-87b8-b28b3bd118e9</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,f730239f-5be1-4cb2-87b8-b28b3bd118e9.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,f730239f-5be1-4cb2-87b8-b28b3bd118e9.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f730239f-5be1-4cb2-87b8-b28b3bd118e9</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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:
</p>
        <p>
          <strong>
            <font color="#ff0000">The default value for the property 'size' has different
type than the one of the property itself. </font>
          </strong>
        </p>
        <p>
Huh? Turns out the type inference on the DefaultValue property in the ConfigurationProperty
attribute is rather picky. Here's what I had originally:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[ConfigurationProperty(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>, <font color="#ff0000"><strong>DefaultValue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1</strong></font>,
IsKey <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
IsRequired <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Size<br />
{<br />
    get<br />
    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span>)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>];
}<br />
    set<br />
    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value.ToString();
}<br />
}<br /></span>
        </p>
        <p>
And here's what I changed it to thinking it would run just fine:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[ConfigurationProperty(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>, <strong><font color="#ff0000">DefaultValue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1</font></strong>,
IsKey <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
IsRequired <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span> Size<br />
{<br />
    get<br />
    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span>)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>];
}<br />
    set<br />
    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value.ToString();
}<br />
}<br /></span>
        </p>
        <p>
Just because the above code compiled, does not mean it will work correctly. So here's
what really worked:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">[ConfigurationProperty(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>, <strong><font color="#ff0000">DefaultValue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1.0</font></strong>,
IsKey <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
IsRequired <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span> Size<br />
{<br />
    get<br />
    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span>)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>];
}<br />
    set<br />
    { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value.ToString();
}<br />
}<br /></span>
        </p>
        <p>
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.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Text;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Configuration;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Xml;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> MyConfigBox<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> SizeLimitConfigurationSection
: ConfigurationSection<br />
    {<br />
        [ConfigurationProperty(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"hostSize"</span>)]<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> HostSizeConfigCollection
HostSize<br />
        {<br />
            get<br />
            {<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> ((HostSizeConfigCollection)(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"hostSize"</span>]));<br />
            }<br />
        }<br />
    }<br /><br />
    [ConfigurationCollectionAttribute(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(HostSizeConfigElement))]<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> HostSizeConfigCollection
: ConfigurationElementCollection<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span> ConfigurationElement
CreateNewElement()<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> HostSizeConfigElement();<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> GetElementKey(ConfigurationElement
element)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> ((HostSizeConfigElement)(element)).Name;<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Add(HostSizeConfigElement
element)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.BaseAdd(element);<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Remove(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> key)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.BaseRemove(key);<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Clear()<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.BaseClear();<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> HostSizeConfigElement <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> idx]<br />
        {<br />
            get { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> (HostSizeConfigElement)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[idx];
}<br />
        }<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> HostSizeConfigElement
: ConfigurationElement<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> HostSizeConfigElement()
{ }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> HostSizeConfigElement(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> name, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span> size)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> name;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.Size <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> size;<br />
        }<br /><br />
        [ConfigurationProperty(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"name"</span>,
DefaultValue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"_"</span>,
IsKey=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>,
IsRequired <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)]<br />
        [StringValidator(InvalidCharacters <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"~!@#$%^&amp;()[]{}/;'\"|\\"</span>,
MinLength <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1,
MaxLength <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 260)]<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Name<br />
        {<br />
            get<br />
            { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"name"</span>];
}<br />
            set<br />
            { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"name"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;
}<br />
        }<br /><br />
        [ConfigurationProperty(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>,
DefaultValue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 1.0,
IsKey <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
IsRequired <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>)]<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span> Size<br />
        {<br />
            get<br />
            { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">double</span>)<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>];
}<br />
            set<br />
            { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"size"</span>] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value.ToString();
}<br />
        }<br />
    }<br />
}<br /></span>
        </p>
        <p>
And now here's the config file (some items removed to clean it up a bit and just show
the relevant parts):
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;?xml
version="1.0"?&gt;<br />
&lt;configuration&gt;<br />
    &lt;configSections&gt;<br />
        &lt;section name="sizeLimits" type="MyConfigBox.SizeLimitConfigurationSection,
MyConfigBox" /&gt;<br />
    &lt;/configSections&gt;<br />
    &lt;appSettings/&gt;<br />
    &lt;connectionStrings/&gt;<br /><br />
    &lt;sizeLimits&gt;<br />
        &lt;hostSize&gt;<br />
            &lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">add</span> name="netbrick.net"
size="17.5" /&gt;<br />
            &lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">add</span> name="duovia.com"
size="42.4" /&gt;<br />
        &lt;/hostSize&gt;<br />
    &lt;/sizeLimits&gt;<br /><br />
&lt;/configuration&gt;<br /></span>
        </p>
        <p>
And here's an example of how to use the custom config handler in code:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SizeLimitConfigurationSection
config <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><br />
   (SizeLimitConfigurationSection)(System.Configuration.ConfigurationManager.GetSection(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"sizeLimits"</span>));<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//now
use config to get at the items in the hostSize collection of HostSizeConfigElement
objects</span></span>
        </p>
        <p>
So watch those attribute values because sometimes the compiler won't.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f730239f-5be1-4cb2-87b8-b28b3bd118e9" />
      </body>
      <title>ConfigurationSection Lesson on ConfigurationErrorsException</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,f730239f-5be1-4cb2-87b8-b28b3bd118e9.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/03/18/ConfigurationSection+Lesson+On+ConfigurationErrorsException.aspx</link>
      <pubDate>Tue, 18 Mar 2008 21:32:54 GMT</pubDate>
      <description>&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font color=#ff0000&gt;The default value for the property 'size' has different
type than the one of the property itself. &lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Huh? Turns out the type inference on the DefaultValue property in the ConfigurationProperty
attribute is rather picky. Here's what I had originally:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[ConfigurationProperty(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;, &lt;font color=#ff0000&gt;&lt;strong&gt;DefaultValue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1&lt;/strong&gt;&lt;/font&gt;,
IsKey &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
IsRequired &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Size&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;];
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value.ToString();
}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And here's what I changed it to thinking it would run just fine:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[ConfigurationProperty(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;, &lt;strong&gt;&lt;font color=#ff0000&gt;DefaultValue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1&lt;/font&gt;&lt;/strong&gt;,
IsKey &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
IsRequired &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt; Size&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt;)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;];
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value.ToString();
}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Just because the above code compiled, does not mean it will work correctly. So&amp;nbsp;here's
what really worked:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;[ConfigurationProperty(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;, &lt;strong&gt;&lt;font color=#ff0000&gt;DefaultValue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1.0&lt;/font&gt;&lt;/strong&gt;,
IsKey &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
IsRequired &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt; Size&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt;)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;];
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value.ToString();
}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Text;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Configuration;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Xml;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; MyConfigBox&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; SizeLimitConfigurationSection
: ConfigurationSection&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ConfigurationProperty(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"hostSize"&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; HostSizeConfigCollection
HostSize&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; ((HostSizeConfigCollection)(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;base&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"hostSize"&lt;/span&gt;]));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ConfigurationCollectionAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(HostSizeConfigElement))]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; HostSizeConfigCollection
: ConfigurationElementCollection&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; ConfigurationElement
CreateNewElement()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; HostSizeConfigElement();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; GetElementKey(ConfigurationElement
element)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; ((HostSizeConfigElement)(element)).Name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Add(HostSizeConfigElement
element)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.BaseAdd(element);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Remove(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; key)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.BaseRemove(key);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Clear()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.BaseClear();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; HostSizeConfigElement &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; idx]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get { &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; (HostSizeConfigElement)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[idx];
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; HostSizeConfigElement
: ConfigurationElement&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; HostSizeConfigElement()
{ }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; HostSizeConfigElement(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; name, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt; size)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.Name &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.Size &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; size;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ConfigurationProperty(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"name"&lt;/span&gt;,
DefaultValue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"_"&lt;/span&gt;,
IsKey=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;,
IsRequired &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[StringValidator(InvalidCharacters &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"~!@#$%^&amp;amp;()[]{}/;'\"|\\"&lt;/span&gt;,
MinLength &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1,
MaxLength &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 260)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Name&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"name"&lt;/span&gt;];
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"name"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ConfigurationProperty(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;,
DefaultValue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 1.0,
IsKey &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
IsRequired &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt; Size&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;double&lt;/span&gt;)&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;];
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"size"&lt;/span&gt;] &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value.ToString();
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And now here's the config file (some items removed to clean it up a bit and just show
the relevant parts):
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;?xml
version="1.0"?&amp;gt;&lt;br&gt;
&amp;lt;configuration&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;configSections&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;section name="sizeLimits" type="MyConfigBox.SizeLimitConfigurationSection,
MyConfigBox" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/configSections&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;appSettings/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;connectionStrings/&amp;gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;sizeLimits&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;hostSize&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;add&lt;/span&gt; name="netbrick.net"
size="17.5" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;add&lt;/span&gt; name="duovia.com"
size="42.4" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/hostSize&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/sizeLimits&amp;gt;&lt;br&gt;
&lt;br&gt;
&amp;lt;/configuration&amp;gt;&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And here's an example of how to use the custom config handler in code:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SizeLimitConfigurationSection
config &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp; (SizeLimitConfigurationSection)(System.Configuration.ConfigurationManager.GetSection(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"sizeLimits"&lt;/span&gt;));&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//now
use config to get at the items in the hostSize collection of HostSizeConfigElement
objects&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
So watch those attribute values because sometimes the compiler won't.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f730239f-5be1-4cb2-87b8-b28b3bd118e9" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,f730239f-5be1-4cb2-87b8-b28b3bd118e9.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=01e3d137-1d63-4fa9-a001-c58514cca5bc</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,01e3d137-1d63-4fa9-a001-c58514cca5bc.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,01e3d137-1d63-4fa9-a001-c58514cca5bc.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=01e3d137-1d63-4fa9-a001-c58514cca5bc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
But sometimes it's fun to look under the hood. And who knows, it might show up on
a test.
</p>
        <p>
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? 
</p>
        <p>
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.
</p>
        <p>
          <strong>What is the Stack?</strong>
          <br />
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."
</p>
        <p>
          <strong>What is the Heap?<br /></strong>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.
</p>
        <p>
          <strong>What is a Value Type?<br /></strong>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:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <strong>Structs<br /></strong>Structs fall into these categories:<br />
  • numeric types<br />
    - integral types (<font color="#0000ff">byte, char, short, int,
long, sbyte, ushort, uint, ulong</font>)<br />
    - floating-point types (<font color="#0000ff">double, float</font>)<br />
    - <font color="#0000ff">decimal</font><br />
  • boolean<br />
  • user defined structs<br />
 <br />
 <strong>Enumerations</strong><br />
 Enumerations are a set of named constants with an underlying type which can
be any integral type except System.Char.
</p>
        </blockquote>
        <p>
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.
</p>
        <p>
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:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections.Generic;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Linq;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Text;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> StackHeap<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Program<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Main(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
args)<br />
        {<br />
            MyData me <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyData();<br />
            me.Age <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 42;<br />
            me.Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Sam"</span>;<br />
            me.Relationship <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"married"</span>;<br /><br />
            MyData her <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> me;<br />
            her.Age <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 44;<br />
            her.Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Mary"</span>;<br /><br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"I
am {0} years old. My name is {1}."</span>, me.Age, me.Name);<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"She
is {0} years old. Her name is {1}."</span>, her.Age, her.Name);<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"I
am {0} to her. She is {1} to me."</span>, me.Relationship, her.Relationship);<br /><br />
            Console.ReadLine();<br />
        }<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">struct</span> MyData<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Age;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Name;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Relationship;<br />
    }<br />
}<br /></span>
        </p>
        <p>
          <strong>Output</strong>
          <br />
          <font face="Courier New"> I am <font color="#ff0000"><strong>42</strong></font> years
old. My name is <strong><font color="#ff0000">Sam</font></strong>.<br />
 She is <strong><font color="#ff0000">44</font></strong> years old. Her name
is <strong><font color="#ff0000">Mary</font></strong>.<br />
 I am married to her. She is married to me.</font>
        </p>
        <p>
The assignment of the Age value applies only to the copy of the original. It is a
value type.
</p>
        <p>
Now consider the output if we make MyData a reference type by changing it to a class.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyData<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Age;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Name;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Relationship;<br />
    }<br /></span>
        </p>
        <p>
          <strong>Output</strong>
          <br />
          <font face="Courier New"> I am <strong><font color="#ff0000">44</font></strong> years
old. My name is <strong><font color="#ff0000">Mary</font></strong>.<br />
 She is <strong><font color="#ff0000">44</font></strong> years old. Her name
is <strong><font color="#ff0000">Mary</font></strong>.<br />
 I am married to her. She is married to me.</font>
        </p>
        <p>
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.
</p>
        <p>
The same behavior can be observed in using value types and reference types as parameters.
Consider this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections.Generic;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Linq;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Text;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> StackHeap<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Program<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Main(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
args)<br />
        {<br />
            MyData me <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyData();<br />
            me.Age <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 42;<br />
            me.Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Sam"</span>;<br />
            me.Relationship <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"married"</span>;<br /><br />
            MyData her <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> me;<br />
            her.Age <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 44;<br />
            her.Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Mary"</span>;<br /><br />
            ModifySomeData(me, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ref</span> her);<br /><br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"I
am {0} years old. My name is {1}."</span>, me.Age, me.Name);<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"She
is {0} years old. Her name is {1}."</span>, her.Age, her.Name);<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"I
am {0} to her. She is {1} to me."</span>, me.Relationship, her.Relationship);<br /><br />
            Console.ReadLine();<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ModifySomeData(MyData
me, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ref</span> MyData
her)<br />
        {<br />
            me.Age <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 50;<br />
            her.Age <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 50;<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"\nMy
age changed to {0} as value type parameter."</span>, me.Age);<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Her
age changed to {0} as value type parameter passed by ref.\n"</span>, me.Age);<br />
        }<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">struct</span> MyData<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Age;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Name;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Relationship;<br />
    }<br />
}<br /></span>
        </p>
        <p>
          <strong>Output</strong>
          <br />
          <font face="Courier New"> My age changed to <strong><font color="#ff0000">50</font></strong> as
value type parameter.<br />
 Her age changed to <strong><font color="#ff0000">50</font></strong> as value
type parameter passed by ref.<br />
 <br />
 I am <strong><font color="#ff0000">42</font></strong> years old. My name is
Sam.<br />
 She is <strong><font color="#ff0000">50</font></strong> years old. Her name
is Mary.<br />
 I am married to her. She is married to me.</font>
        </p>
        <p>
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:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyData<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Age;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Name;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Relationship;<br />
    }<br /></span>
        </p>
        <p>
          <strong>Output</strong>
          <br />
          <font face="Courier New"> My age changed to 50 as value type parameter.<br />
 Her age changed to 50 as value type parameter passed by ref.<br />
 <br />
 I am <strong><font color="#ff0000">50</font></strong> years old. My name is
Mary.<br />
 She is <strong><font color="#ff0000">50</font></strong> years old. Her name
is Mary.<br />
 I am married to her. She is married to me.<br /></font> 
</p>
        <p>
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.
</p>
        <p>
          <br />
          <strong>What is a Reference Type?<br /></strong>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.
</p>
        <p>
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).
</p>
        <p>
          <strong>What is the GC?<br /></strong>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.
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
          <strong>Summary</strong>
          <br />
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. :)
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=01e3d137-1d63-4fa9-a001-c58514cca5bc" />
      </body>
      <title>Heap, Stack, Reference Types and Value Types in .NET</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,01e3d137-1d63-4fa9-a001-c58514cca5bc.aspx</guid>
      <link>http://www.tsjensen.com/blog/2008/01/31/Heap+Stack+Reference+Types+And+Value+Types+In+NET.aspx</link>
      <pubDate>Thu, 31 Jan 2008 01:21:40 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
But sometimes it's fun to look under the hood. And who knows, it might show up on
a test.
&lt;/p&gt;
&lt;p&gt;
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? 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;What is the Stack?&lt;/strong&gt;
&lt;br&gt;
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."
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;What is the Heap?&lt;br&gt;
&lt;/strong&gt;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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;What is a Value Type?&lt;br&gt;
&lt;/strong&gt;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:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;strong&gt;Structs&lt;br&gt;
&lt;/strong&gt;Structs fall into these categories:&lt;br&gt;
&amp;nbsp;&amp;nbsp;• numeric types&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - integral types (&lt;font color=#0000ff&gt;byte, char, short, int, long,
sbyte, ushort, uint, ulong&lt;/font&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - floating-point types (&lt;font color=#0000ff&gt;double, float&lt;/font&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - &lt;font color=#0000ff&gt;decimal&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;• boolean&lt;br&gt;
&amp;nbsp;&amp;nbsp;• user defined structs&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&amp;nbsp;&lt;strong&gt;Enumerations&lt;/strong&gt;
&lt;br&gt;
&amp;nbsp;Enumerations are a set of named constants with an underlying type which can
be any integral type except System.Char.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Text;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; StackHeap&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Program&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Main(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
args)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyData me &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyData();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Age &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 42;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Name &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Sam"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Relationship &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"married"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyData her &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; me;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;her.Age &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 44;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;her.Name &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Mary"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"I
am {0} years old. My name is {1}."&lt;/span&gt;, me.Age, me.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"She
is {0} years old. Her name is {1}."&lt;/span&gt;, her.Age, her.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"I
am {0} to her. She is {1} to me."&lt;/span&gt;, me.Relationship, her.Relationship);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.ReadLine();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;struct&lt;/span&gt; MyData&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Age;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Relationship;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Output&lt;/strong&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;I am &lt;font color=#ff0000&gt;&lt;strong&gt;42&lt;/strong&gt;&lt;/font&gt; years
old. My name is &lt;strong&gt;&lt;font color=#ff0000&gt;Sam&lt;/font&gt;&lt;/strong&gt;.&lt;br&gt;
&amp;nbsp;She is &lt;strong&gt;&lt;font color=#ff0000&gt;44&lt;/font&gt;&lt;/strong&gt; years old. Her name is &lt;strong&gt;&lt;font color=#ff0000&gt;Mary&lt;/font&gt;&lt;/strong&gt;.&lt;br&gt;
&amp;nbsp;I am married to her. She is married to me.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The assignment of the Age value applies only to the copy of the original. It is a
value type.
&lt;/p&gt;
&lt;p&gt;
Now consider the output if we make MyData a reference type by changing it to a class.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyData&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Age;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Relationship;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Output&lt;/strong&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;I am &lt;strong&gt;&lt;font color=#ff0000&gt;44&lt;/font&gt;&lt;/strong&gt; years
old. My name is &lt;strong&gt;&lt;font color=#ff0000&gt;Mary&lt;/font&gt;&lt;/strong&gt;.&lt;br&gt;
&amp;nbsp;She is &lt;strong&gt;&lt;font color=#ff0000&gt;44&lt;/font&gt;&lt;/strong&gt; years old. Her name is &lt;strong&gt;&lt;font color=#ff0000&gt;Mary&lt;/font&gt;&lt;/strong&gt;.&lt;br&gt;
&amp;nbsp;I am married to her. She is married to me.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
The same behavior can be observed in using value types and reference types as parameters.
Consider this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Text;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; StackHeap&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Program&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Main(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
args)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyData me &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyData();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Age &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 42;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Name &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Sam"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Relationship &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"married"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyData her &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; me;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;her.Age &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 44;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;her.Name &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Mary"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ModifySomeData(me, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ref&lt;/span&gt; her);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"I
am {0} years old. My name is {1}."&lt;/span&gt;, me.Age, me.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"She
is {0} years old. Her name is {1}."&lt;/span&gt;, her.Age, her.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"I
am {0} to her. She is {1} to me."&lt;/span&gt;, me.Relationship, her.Relationship);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.ReadLine();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; ModifySomeData(MyData
me, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ref&lt;/span&gt; MyData
her)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;me.Age &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 50;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;her.Age &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 50;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"\nMy
age changed to {0} as value type parameter."&lt;/span&gt;, me.Age);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Her
age changed to {0} as value type parameter passed by ref.\n"&lt;/span&gt;, me.Age);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;struct&lt;/span&gt; MyData&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Age;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Relationship;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Output&lt;/strong&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;My age changed to &lt;strong&gt;&lt;font color=#ff0000&gt;50&lt;/font&gt;&lt;/strong&gt; as
value type parameter.&lt;br&gt;
&amp;nbsp;Her age changed to &lt;strong&gt;&lt;font color=#ff0000&gt;50&lt;/font&gt;&lt;/strong&gt; as value type
parameter passed by ref.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&amp;nbsp;I am &lt;strong&gt;&lt;font color=#ff0000&gt;42&lt;/font&gt;&lt;/strong&gt; years old. My name is Sam.&lt;br&gt;
&amp;nbsp;She is &lt;strong&gt;&lt;font color=#ff0000&gt;50&lt;/font&gt;&lt;/strong&gt; years old. Her name is
Mary.&lt;br&gt;
&amp;nbsp;I am married to her. She is married to me.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyData&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Age;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Relationship;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Output&lt;/strong&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;My age changed to 50 as value type parameter.&lt;br&gt;
&amp;nbsp;Her age changed to 50 as value type parameter passed by ref.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&amp;nbsp;I am &lt;strong&gt;&lt;font color=#ff0000&gt;50&lt;/font&gt;&lt;/strong&gt; years old. My name is Mary.&lt;br&gt;
&amp;nbsp;She is &lt;strong&gt;&lt;font color=#ff0000&gt;50&lt;/font&gt;&lt;/strong&gt; years old. Her name is
Mary.&lt;br&gt;
&amp;nbsp;I am married to her. She is married to me.&lt;br&gt;
&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;strong&gt;What is a Reference Type?&lt;br&gt;
&lt;/strong&gt;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.
&lt;/p&gt;
&lt;p&gt;
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).
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;What is the GC?&lt;br&gt;
&lt;/strong&gt;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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Summary&lt;/strong&gt;
&lt;br&gt;
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. :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=01e3d137-1d63-4fa9-a001-c58514cca5bc" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,01e3d137-1d63-4fa9-a001-c58514cca5bc.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=2e5fbd91-9576-4c89-9c93-b3b14f78e15f</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,2e5fbd91-9576-4c89-9c93-b3b14f78e15f.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,2e5fbd91-9576-4c89-9c93-b3b14f78e15f.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2e5fbd91-9576-4c89-9c93-b3b14f78e15f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span> SqlParameter
CreateParameter(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> name,
SqlDbType type, 
<br />
    ParameterDirection direction, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span>?
size, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>?
precision, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> value)<br />
{<br />
    SqlParameter param <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlParameter(name,
type);<br />
    param.Direction <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> direction;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (size.HasValue)
param.Size <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> size.Value;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (precision.HasValue)
param.Precision <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> precision.Value;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (value
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)
param.Value <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span> param.Value <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> DBNull.Value;<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> param;<br />
}<br /></span>
        </p>
        <p>
And then when I'm building a command, I just do this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">cmd.Parameters.Add(DataAccess.CreateParameter(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@RETURN_VALUE"</span>, 
<br />
    SqlDbType.Int, ParameterDirection.ReturnValue, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>));<br />
cmd.Parameters.Add(DataAccess.CreateParameter(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@ID"</span>, 
<br />
    SqlDbType.Int, ParameterDirection.Input, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>,
id));<br />
cmd.Parameters.Add(DataAccess.CreateParameter(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@NAME"</span>, 
<br />
    SqlDbType.VarChar, ParameterDirection.Input, 50, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>,
name));<br /></span>
        </p>
        <p>
Of course, it won't work for everything, but it makes quick work out of most of my
parameter creation. Hooray for the factory.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2e5fbd91-9576-4c89-9c93-b3b14f78e15f" />
      </body>
      <title>SqlParameter Factory</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,2e5fbd91-9576-4c89-9c93-b3b14f78e15f.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/10/21/SqlParameter+Factory.aspx</link>
      <pubDate>Sun, 21 Oct 2007 02:46:44 GMT</pubDate>
      <description>&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; SqlParameter
CreateParameter(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; name,
SqlDbType type, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ParameterDirection direction, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;?
size, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;byte&lt;/span&gt;?
precision, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; value)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlParameter param &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlParameter(name,
type);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;param.Direction &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; direction;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (size.HasValue)
param.Size &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; size.Value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (precision.HasValue)
param.Precision &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; precision.Value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (value
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)
param.Value &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; param.Value &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; DBNull.Value;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; param;&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And then when I'm building a command, I just do this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;cmd.Parameters.Add(DataAccess.CreateParameter(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@RETURN_VALUE"&lt;/span&gt;, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlDbType.Int, ParameterDirection.ReturnValue, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;));&lt;br&gt;
cmd.Parameters.Add(DataAccess.CreateParameter(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@ID"&lt;/span&gt;, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlDbType.Int, ParameterDirection.Input, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;,
id));&lt;br&gt;
cmd.Parameters.Add(DataAccess.CreateParameter(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@NAME"&lt;/span&gt;, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SqlDbType.VarChar, ParameterDirection.Input, 50, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;,
name));&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Of course, it won't work for everything, but it makes quick work out of most of my
parameter creation. Hooray for the factory.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2e5fbd91-9576-4c89-9c93-b3b14f78e15f" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,2e5fbd91-9576-4c89-9c93-b3b14f78e15f.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
Here's how I deal with it.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Diagnostics;<br /></span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span>
            <br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//some
logging code that can throw an exception</span><br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//but
the exception has to be handled and logged</span><br />
    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//somehow</span><br />
}<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span> (Exception
e)<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span><br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//write
exception to OS event log</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (!EventLog.SourceExists(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"MyAppName"</span>)) 
<br />
            EventLog.CreateEventSource(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"MyAppName"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Application"</span>);<br />
        EventLog.WriteEntry(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"MyAppName"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Log
Exception: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> e.Message);<br />
    }<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span><br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//sorry
charlie</span><br />
    }<br />
}<br /></span>
        </p>
        <p>
It's not perfect, but it seems to work in most cases.
</p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1" />
      </body>
      <title>Logging Logger Exceptions</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/09/09/Logging+Logger+Exceptions.aspx</link>
      <pubDate>Sun, 09 Sep 2007 14:54:37 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Here's how I deal with it.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;try&lt;/span&gt;
&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//some
logging code that can throw an exception&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//but
the exception has to be handled and logged&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//somehow&lt;/span&gt;
&lt;br&gt;
}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;catch&lt;/span&gt; (Exception
e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//write
exception to OS event log&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (!EventLog.SourceExists(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"MyAppName"&lt;/span&gt;)) 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EventLog.CreateEventSource(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"MyAppName"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Application"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EventLog.WriteEntry(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"MyAppName"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Log
Exception: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; e.Message);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;catch&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//sorry
charlie&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
It's not perfect, but it seems to work in most cases.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,20f4a9e8-ceeb-4bb2-94ce-0d20807dc0b1.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=ea863647-b4e0-4cd5-9cef-bd5478705637</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,ea863647-b4e0-4cd5-9cef-bd5478705637.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,ea863647-b4e0-4cd5-9cef-bd5478705637.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ea863647-b4e0-4cd5-9cef-bd5478705637</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
Happily I found that MySQL AB has released a really great <a href="http://dev.mysql.com/downloads/connector/net/5.1.html">ADO.NET
provider for MySQL</a>.
</p>
        <p>
If you have used the SQL Server specific ADO.NET provider, you'll easily make the
transition to using this one.
</p>
        <p>
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:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SELECT</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">TOP</span> 1
* <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FROM</span> MYTABLE <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WHERE</span> FKID
= 3</span>
        </p>
        <p>
And for MySQL use:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SELECT</span> * <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FROM</span> MYTABLE <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WHERE</span> FKID
= 3 <font color="#0000ff">LIMIT</font> 1;</span>
        </p>
        <p>
Yes, I know. It ought to be obvious, but having a quick reminder here will help to
seal this minor difference into my brain.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ea863647-b4e0-4cd5-9cef-bd5478705637" />
      </body>
      <title>SQL Server TOP vs MySQL LIMIT</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,ea863647-b4e0-4cd5-9cef-bd5478705637.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/09/01/SQL+Server+TOP+Vs+MySQL+LIMIT.aspx</link>
      <pubDate>Sat, 01 Sep 2007 16:30:13 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Happily I found that MySQL AB has released a really great &lt;a href="http://dev.mysql.com/downloads/connector/net/5.1.html"&gt;ADO.NET
provider for MySQL&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
If you have used the SQL Server specific ADO.NET provider, you'll easily make the
transition to using this one.
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SELECT&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;TOP&lt;/span&gt; 1
* &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FROM&lt;/span&gt; MYTABLE &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WHERE&lt;/span&gt; FKID
= 3&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And for MySQL use:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SELECT&lt;/span&gt; * &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FROM&lt;/span&gt; MYTABLE &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WHERE&lt;/span&gt; FKID
= 3 &lt;font color=#0000ff&gt;LIMIT&lt;/font&gt; 1;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Yes, I know. It ought to be obvious, but having a quick reminder here will help to
seal this minor difference into my brain.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=ea863647-b4e0-4cd5-9cef-bd5478705637" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,ea863647-b4e0-4cd5-9cef-bd5478705637.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=1f609f30-baba-4897-9ed7-bea51d549054</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,1f609f30-baba-4897-9ed7-bea51d549054.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,1f609f30-baba-4897-9ed7-bea51d549054.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1f609f30-baba-4897-9ed7-bea51d549054</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
I recommend the reader purchase O'Reilly's book <a href="http://www.oreilly.com/catalog/xmlschema/index.html">XML
Schema by Eric van der Vlist</a>. It's been a most trustworthy companion. And then
to make the use of this XML configuration dreamscape even easier, I recommend <a href="http://www.thinktecture.com/resourcearchive/tools-and-software/wscf">Christian
Weyer's contract first tool</a>. I use this extremely useful tool to generate the
XAL (XML access layer) so I don't have to write it by hand. 
</p>
        <p>
With these two tools in hand, you can create something like this in Visual Studio:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;?xml
version="1.0" encoding="utf-8" ?&gt;<br />
&lt;xs:<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">schema</span> id="watchconfig"
targetNamespace="http://example.com/v1001/watchconfig.xsd"<br />
    elementFormDefault="qualified"<br />
    xmlns="http://example.com/v1001/watchconfig.xsd"<br />
    xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;<br />
    &lt;xs:element name="watchconfig"&gt;<br />
        &lt;xs:complexType&gt;<br />
            &lt;xs:sequence&gt;<br />
                &lt;xs:element
ref="watchgroup" minOccurs="0" maxOccurs="unbounded" /&gt;<br />
            &lt;/xs:sequence&gt;<br />
        &lt;/xs:complexType&gt;<br />
    &lt;/xs:element&gt;<br />
    &lt;xs:element name="watchgroup"&gt;<br />
        &lt;xs:complexType&gt;<br />
            &lt;xs:sequence&gt;<br />
                &lt;xs:element
ref="watcher" minOccurs="0" maxOccurs="unbounded" /&gt;<br />
            &lt;/xs:sequence&gt;<br />
            &lt;xs:attribute
name="id" type="xs:string" <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">use</span>="required"
/&gt;<br />
            &lt;xs:attribute
name="literalsconfigpath" type="xs:string" /&gt;<br />
        &lt;/xs:complexType&gt;<br />
    &lt;/xs:element&gt;<br />
    &lt;xs:element name="watcher"&gt;<br />
        &lt;xs:complexType&gt;<br />
            &lt;xs:attribute
name="sourcepath" type="xs:string" <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">use</span>="required"
/&gt;<br />
            &lt;xs:attribute
name="wippath" type="xs:string" <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">use</span>="required"
/&gt;<br />
            &lt;xs:attribute
name="outpath" type="xs:string" <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">use</span>="required"
/&gt;<br />
            &lt;xs:attribute
name="ssispath" type="xs:string" <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">use</span>="required"
/&gt;<br />
            &lt;xs:attribute
name="intakemap" type="xs:string" <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">use</span>="required"
/&gt;<br />
        &lt;/xs:complexType&gt;<br />
    &lt;/xs:element&gt;<br />
&lt;/xs:<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">schema</span>&gt;<br /></span>
        </p>
        <p>
And an XML file like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;?xml
version="1.0" encoding="utf-8" ?&gt;<br />
&lt;watchconfig xmlns="http://example.com/v1001/watchconfig.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;<br />
    &lt;watchgroup id="clientname" literalsconfigpath="H:\temp\literals_client"&gt;<br />
        &lt;watcher sourcepath="H:\temp\client\watch"<br />
                    wippath="H:\temp\client\wip"<br />
                    outpath="H:\temp\client\<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">out</span>"<br />
                    ssispath="H:\temp\client\ssis"<br />
                    intakemap="D:\Contracts\Code\map.xml"
/&gt;<br />
    &lt;/watchgroup&gt;<br />
&lt;/watchconfig&gt;</span>
        </p>
        <p>
And the nicely generated code like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span>
            <br />
[System.CodeDom.Compiler.GeneratedCodeAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"System.Xml"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"2.0.50727.42"</span>)]<br />
[System.SerializableAttribute()]<br />
[System.Diagnostics.DebuggerStepThroughAttribute()]<br />
[System.ComponentModel.DesignerCategoryAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"code"</span>)]<br />
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>,
TypeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watchconfig"</span>)]<br />
[System.Xml.Serialization.XmlRootAttribute(Namespace=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"http://example.com/v1001/watchconfig.xsd"</span>,
IsNullable=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
ElementName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watchconfig"</span>)]<br />
[System.ComponentModel.TypeConverterAttribute(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(System.ComponentModel.ExpandableObjectConverter))]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> partial <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Watchconfig<br />
{<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span> System.Collections.Generic.List&lt;Watchgroup&gt;
watchgroup;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> Watchconfig()<br />
{<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> Watchconfig(System.Collections.Generic.List&lt;Watchgroup&gt;
watchgroup)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watchgroup <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> watchgroup;<br />
}<br /><br />
[System.Xml.Serialization.XmlElementAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watchgroup"</span>,
Order=0)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> System.Collections.Generic.List&lt;Watchgroup&gt;
Watchgroup<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watchgroup;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watchgroup
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watchgroup <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br />
[System.CodeDom.Compiler.GeneratedCodeAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"System.Xml"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"2.0.50727.42"</span>)]<br />
[System.SerializableAttribute()]<br />
[System.Diagnostics.DebuggerStepThroughAttribute()]<br />
[System.ComponentModel.DesignerCategoryAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"code"</span>)]<br />
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>,
TypeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watchgroup"</span>)]<br />
[System.Xml.Serialization.XmlRootAttribute(Namespace=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"http://example.com/v1001/watchconfig.xsd"</span>,
IsNullable=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
ElementName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watchgroup"</span>)]<br />
[System.ComponentModel.TypeConverterAttribute(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(System.ComponentModel.ExpandableObjectConverter))]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> partial <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Watchgroup<br />
{<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span> System.Collections.Generic.List&lt;Watcher&gt;
watcher;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> id;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> literalsconfigpath;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> Watchgroup()<br />
{<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> Watchgroup(System.Collections.Generic.List&lt;Watcher&gt;
watcher, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> id, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> literalsconfigpath)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watcher <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> watcher;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.id <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> id;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.literalsconfigpath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> literalsconfigpath;<br />
}<br /><br />
[System.Xml.Serialization.XmlElementAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watcher"</span>,
Order=0)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> System.Collections.Generic.List&lt;Watcher&gt;
Watcher<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watcher;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watcher
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.watcher <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"id"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Id<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.id;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.id
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.id <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"literalsconfigpath"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Literalsconfigpath<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.literalsconfigpath;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.literalsconfigpath
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.literalsconfigpath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br />
[System.CodeDom.Compiler.GeneratedCodeAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"System.Xml"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"2.0.50727.42"</span>)]<br />
[System.SerializableAttribute()]<br />
[System.Diagnostics.DebuggerStepThroughAttribute()]<br />
[System.ComponentModel.DesignerCategoryAttribute(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"code"</span>)]<br />
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>,
TypeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watcher"</span>)]<br />
[System.Xml.Serialization.XmlRootAttribute(Namespace=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"http://example.com/v1001/watchconfig.xsd"</span>,
IsNullable=<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>,
ElementName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"watcher"</span>)]<br />
[System.ComponentModel.TypeConverterAttribute(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(System.ComponentModel.ExpandableObjectConverter))]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> partial <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Watcher<br />
{<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> sourcepath;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> wippath;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> outpath;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> ssispath;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;remarks/&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> intakemap;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> Watcher()<br />
{<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> Watcher(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> sourcepath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> wippath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> outpath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> ssispath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> intakemap)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.sourcepath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> sourcepath;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.wippath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> wippath;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.outpath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> outpath;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.ssispath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ssispath;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.intakemap <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> intakemap;<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"sourcepath"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Sourcepath<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.sourcepath;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.sourcepath
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.sourcepath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"wippath"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Wippath<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.wippath;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.wippath
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.wippath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"outpath"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Outpath<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.outpath;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.outpath
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.outpath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"ssispath"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Ssispath<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.ssispath;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.ssispath
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.ssispath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br /><br />
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"intakemap"</span>)]<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Intakemap<br />
{<br />
get<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.intakemap;<br />
}<br />
set<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> ((<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.intakemap
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value))<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.intakemap <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> value;<br />
}<br />
}<br />
}<br />
}<br /></span>
        </p>
        <p>
(Sorry, indentation got hosed, but you won't need it since you'll be generating this
code with one click.)
</p>
        <p>
 
</p>
        <p>
 
</p>
        <p>
 
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=1f609f30-baba-4897-9ed7-bea51d549054" />
      </body>
      <title>Value of Schema Driven XML Configuration</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,1f609f30-baba-4897-9ed7-bea51d549054.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/08/19/Value+Of+Schema+Driven+XML+Configuration.aspx</link>
      <pubDate>Sun, 19 Aug 2007 15:58:51 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
I recommend the reader purchase O'Reilly's book &lt;a href="http://www.oreilly.com/catalog/xmlschema/index.html"&gt;XML
Schema by Eric van der Vlist&lt;/a&gt;. It's been a most trustworthy companion. And then
to make the use of this XML configuration dreamscape even easier, I recommend &lt;a href="http://www.thinktecture.com/resourcearchive/tools-and-software/wscf"&gt;Christian
Weyer's contract first tool&lt;/a&gt;. I use this extremely useful tool to generate the
XAL (XML access layer) so I don't have to write it by hand. 
&lt;/p&gt;
&lt;p&gt;
With these two tools in hand, you can create something like this in Visual Studio:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;?xml
version="1.0" encoding="utf-8" ?&amp;gt;&lt;br&gt;
&amp;lt;xs:&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;schema&lt;/span&gt; id="watchconfig"
targetNamespace="http://example.com/v1001/watchconfig.xsd"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elementFormDefault="qualified"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns="http://example.com/v1001/watchconfig.xsd"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:element name="watchconfig"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:complexType&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:element
ref="watchgroup" minOccurs="0" maxOccurs="unbounded" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:complexType&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:element&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:element name="watchgroup"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:complexType&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:element
ref="watcher" minOccurs="0" maxOccurs="unbounded" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="id" type="xs:string" &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;use&lt;/span&gt;="required"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="literalsconfigpath" type="xs:string" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:complexType&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:element&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:element name="watcher"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:complexType&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="sourcepath" type="xs:string" &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;use&lt;/span&gt;="required"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="wippath" type="xs:string" &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;use&lt;/span&gt;="required"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="outpath" type="xs:string" &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;use&lt;/span&gt;="required"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="ssispath" type="xs:string" &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;use&lt;/span&gt;="required"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xs:attribute
name="intakemap" type="xs:string" &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;use&lt;/span&gt;="required"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:complexType&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xs:element&amp;gt;&lt;br&gt;
&amp;lt;/xs:&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;schema&lt;/span&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And an XML file like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;?xml
version="1.0" encoding="utf-8" ?&amp;gt;&lt;br&gt;
&amp;lt;watchconfig xmlns="http://example.com/v1001/watchconfig.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;watchgroup id="clientname" literalsconfigpath="H:\temp\literals_client"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;watcher sourcepath="H:\temp\client\watch"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wippath="H:\temp\client\wip"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;outpath="H:\temp\client\&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;out&lt;/span&gt;"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ssispath="H:\temp\client\ssis"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;intakemap="D:\Contracts\Code\map.xml"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/watchgroup&amp;gt;&lt;br&gt;
&amp;lt;/watchconfig&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
And the nicely generated code like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
[System.CodeDom.Compiler.GeneratedCodeAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"System.Xml"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"2.0.50727.42"&lt;/span&gt;)]&lt;br&gt;
[System.SerializableAttribute()]&lt;br&gt;
[System.Diagnostics.DebuggerStepThroughAttribute()]&lt;br&gt;
[System.ComponentModel.DesignerCategoryAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"code"&lt;/span&gt;)]&lt;br&gt;
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;,
TypeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watchconfig"&lt;/span&gt;)]&lt;br&gt;
[System.Xml.Serialization.XmlRootAttribute(Namespace=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"http://example.com/v1001/watchconfig.xsd"&lt;/span&gt;,
IsNullable=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
ElementName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watchconfig"&lt;/span&gt;)]&lt;br&gt;
[System.ComponentModel.TypeConverterAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(System.ComponentModel.ExpandableObjectConverter))]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; partial &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Watchconfig&lt;br&gt;
{&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; System.Collections.Generic.List&amp;lt;Watchgroup&amp;gt;
watchgroup;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; Watchconfig()&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; Watchconfig(System.Collections.Generic.List&amp;lt;Watchgroup&amp;gt;
watchgroup)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watchgroup &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; watchgroup;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlElementAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watchgroup"&lt;/span&gt;,
Order=0)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; System.Collections.Generic.List&amp;lt;Watchgroup&amp;gt;
Watchgroup&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watchgroup;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watchgroup
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watchgroup &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
[System.CodeDom.Compiler.GeneratedCodeAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"System.Xml"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"2.0.50727.42"&lt;/span&gt;)]&lt;br&gt;
[System.SerializableAttribute()]&lt;br&gt;
[System.Diagnostics.DebuggerStepThroughAttribute()]&lt;br&gt;
[System.ComponentModel.DesignerCategoryAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"code"&lt;/span&gt;)]&lt;br&gt;
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;,
TypeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watchgroup"&lt;/span&gt;)]&lt;br&gt;
[System.Xml.Serialization.XmlRootAttribute(Namespace=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"http://example.com/v1001/watchconfig.xsd"&lt;/span&gt;,
IsNullable=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
ElementName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watchgroup"&lt;/span&gt;)]&lt;br&gt;
[System.ComponentModel.TypeConverterAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(System.ComponentModel.ExpandableObjectConverter))]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; partial &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Watchgroup&lt;br&gt;
{&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; System.Collections.Generic.List&amp;lt;Watcher&amp;gt;
watcher;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; id;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; literalsconfigpath;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; Watchgroup()&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; Watchgroup(System.Collections.Generic.List&amp;lt;Watcher&amp;gt;
watcher, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; id, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; literalsconfigpath)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watcher &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; watcher;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.id &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; id;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.literalsconfigpath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; literalsconfigpath;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlElementAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watcher"&lt;/span&gt;,
Order=0)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; System.Collections.Generic.List&amp;lt;Watcher&amp;gt;
Watcher&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watcher;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watcher
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.watcher &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"id"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Id&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.id;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.id
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.id &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"literalsconfigpath"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Literalsconfigpath&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.literalsconfigpath;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.literalsconfigpath
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.literalsconfigpath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
[System.CodeDom.Compiler.GeneratedCodeAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"System.Xml"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"2.0.50727.42"&lt;/span&gt;)]&lt;br&gt;
[System.SerializableAttribute()]&lt;br&gt;
[System.Diagnostics.DebuggerStepThroughAttribute()]&lt;br&gt;
[System.ComponentModel.DesignerCategoryAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"code"&lt;/span&gt;)]&lt;br&gt;
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;,
TypeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watcher"&lt;/span&gt;)]&lt;br&gt;
[System.Xml.Serialization.XmlRootAttribute(Namespace=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"http://example.com/v1001/watchconfig.xsd"&lt;/span&gt;,
IsNullable=&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;,
ElementName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"watcher"&lt;/span&gt;)]&lt;br&gt;
[System.ComponentModel.TypeConverterAttribute(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(System.ComponentModel.ExpandableObjectConverter))]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; partial &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Watcher&lt;br&gt;
{&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; sourcepath;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; wippath;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; outpath;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; ssispath;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;remarks/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; intakemap;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; Watcher()&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; Watcher(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; sourcepath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; wippath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; outpath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; ssispath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; intakemap)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.sourcepath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; sourcepath;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.wippath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; wippath;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.outpath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; outpath;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ssispath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ssispath;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.intakemap &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; intakemap;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"sourcepath"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Sourcepath&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.sourcepath;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.sourcepath
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.sourcepath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"wippath"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Wippath&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.wippath;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.wippath
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.wippath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"outpath"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Outpath&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.outpath;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.outpath
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.outpath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"ssispath"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Ssispath&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ssispath;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ssispath
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ssispath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
[System.Xml.Serialization.XmlAttributeAttribute(AttributeName=&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"intakemap"&lt;/span&gt;)]&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Intakemap&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.intakemap;&lt;br&gt;
}&lt;br&gt;
set&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; ((&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.intakemap
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value))&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.intakemap &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; value;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
(Sorry, indentation got hosed, but you won't need it since you'll be generating this
code with one click.)
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=1f609f30-baba-4897-9ed7-bea51d549054" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,1f609f30-baba-4897-9ed7-bea51d549054.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=a7166475-3b34-4d33-b30a-428cd6f194a4</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,a7166475-3b34-4d33-b30a-428cd6f194a4.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,a7166475-3b34-4d33-b30a-428cd6f194a4.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a7166475-3b34-4d33-b30a-428cd6f194a4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I subscribe to CodeProject's newsletter and "product information" emails. Today I
received an interesting missive with the headline: "<a href="http://www-306.ibm.com/software/data/db2/express/index.html">Introducing
the new DB2 Express-C</a>". 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. 
</p>
        <p>
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.
</p>
        <p>
A little exploration reveals a nice article on the wiki about <a href="http://www-128.ibm.com/developerworks/db2/library/techarticle/dm-0602tham2/index.html">leveraging
your MySQL skills</a>. And there seems to be ample information on <a href="http://www-306.ibm.com/software/data/db2/windows/dotnet.html">using
DB2 with .NET</a>.
</p>
        <p>
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.
</p>
        <p>
So I'm downloading now and I'll give it a whirl and report what I find back here.
No promises on when.
</p>
        <hr />
        <p>
 Followup - Who am I kidding. The install is HUGE and I have had no time to eval
this thing. Toss another distraction overboard.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=a7166475-3b34-4d33-b30a-428cd6f194a4" />
      </body>
      <title>IBM Going After MySQL or SQL Server 2005 Express with DB2 Express-C</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,a7166475-3b34-4d33-b30a-428cd6f194a4.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/07/19/IBM+Going+After+MySQL+Or+SQL+Server+2005+Express+With+DB2+ExpressC.aspx</link>
      <pubDate>Thu, 19 Jul 2007 01:14:21 GMT</pubDate>
      <description>&lt;p&gt;
I subscribe to CodeProject's newsletter and "product information" emails. Today I
received an interesting missive with the headline: "&lt;a href="http://www-306.ibm.com/software/data/db2/express/index.html"&gt;Introducing
the new DB2 Express-C&lt;/a&gt;". 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. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
A little exploration reveals a nice article on the wiki about &lt;a href="http://www-128.ibm.com/developerworks/db2/library/techarticle/dm-0602tham2/index.html"&gt;leveraging
your MySQL skills&lt;/a&gt;. And there seems to be ample information on &lt;a href="http://www-306.ibm.com/software/data/db2/windows/dotnet.html"&gt;using
DB2 with .NET&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
So I'm downloading now and I'll give it a whirl and report what I find back here.
No promises on when.
&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;
&amp;nbsp;Followup - Who am I kidding. The install is HUGE and I have had no time to eval
this thing. Toss another distraction overboard.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=a7166475-3b34-4d33-b30a-428cd6f194a4" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,a7166475-3b34-4d33-b30a-428cd6f194a4.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=d6d02cb8-8a3d-41ec-9b48-88d70c0e479e</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,d6d02cb8-8a3d-41ec-9b48-88d70c0e479e.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,d6d02cb8-8a3d-41ec-9b48-88d70c0e479e.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d6d02cb8-8a3d-41ec-9b48-88d70c0e479e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
You learn something new every day. I just don't have time to blog about it every time.
This one seemed significant enough.
</p>
        <p>
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. 
</p>
        <p>
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.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Page_PreInit(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.Theme <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetTheme();<br />
}<br /></span>
        </p>
        <p>
That did the trick.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=d6d02cb8-8a3d-41ec-9b48-88d70c0e479e" />
      </body>
      <title>ASP.NET Theme Assignment</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,d6d02cb8-8a3d-41ec-9b48-88d70c0e479e.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/06/08/ASPNET+Theme+Assignment.aspx</link>
      <pubDate>Fri, 08 Jun 2007 15:36:51 GMT</pubDate>
      <description>&lt;p&gt;
You learn something new every day. I just don't have time to blog about it every time.
This one seemed significant enough.
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Page_PreInit(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.Theme &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetTheme();&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
That did the trick.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=d6d02cb8-8a3d-41ec-9b48-88d70c0e479e" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,d6d02cb8-8a3d-41ec-9b48-88d70c0e479e.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=9153b1ef-840a-4b34-af11-f6505e610046</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,9153b1ef-840a-4b34-af11-f6505e610046.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,9153b1ef-840a-4b34-af11-f6505e610046.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9153b1ef-840a-4b34-af11-f6505e610046</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://www.devincook.com">www.devincook.com</a>.
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.
</p>
        <p>
I even tried to share my enthusiasm with the <a href="http://www.utahdnug.org">.NET
Users Group</a> 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.
</p>
        <p>
In the code you can download below, you'll find my first attempt at a language: TROLL — <u>T</u>yler's <u>R</u>eally <u>O</u>btuse <u>L</u>ittle <u>L</u>anguage.
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).
</p>
        <p>
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. 
</p>
        <p>
So why one more programming language? Because now you can.
</p>
        <p>
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.
</p>
        <p>
Well, whatever your reason, download the code, download Devin Cook's GOLD Builder
and have some fun.
</p>
        <p>
          <a href="http://www.netbrick.net/samplecode.zip">Download code (659KB)</a>
        </p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=9153b1ef-840a-4b34-af11-f6505e610046" />
      </body>
      <title>A Kit for Writing Your Own Programming Language</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,9153b1ef-840a-4b34-af11-f6505e610046.aspx</guid>
      <link>http://www.tsjensen.com/blog/2007/03/11/A+Kit+For+Writing+Your+Own+Programming+Language.aspx</link>
      <pubDate>Sun, 11 Mar 2007 16:14:24 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;a href="http://www.devincook.com"&gt;www.devincook.com&lt;/a&gt;.
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.
&lt;/p&gt;
&lt;p&gt;
I even tried to share my enthusiasm with the &lt;a href="http://www.utahdnug.org"&gt;.NET
Users Group&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
In the code you can download below, you'll find my first attempt at a language: TROLL&amp;nbsp;—&amp;nbsp;&lt;u&gt;T&lt;/u&gt;yler's &lt;u&gt;R&lt;/u&gt;eally &lt;u&gt;O&lt;/u&gt;btuse &lt;u&gt;L&lt;/u&gt;ittle &lt;u&gt;L&lt;/u&gt;anguage.
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).
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
So why one more programming language? Because now you can.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Well, whatever your reason, download the code, download Devin Cook's GOLD Builder
and have some fun.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.netbrick.net/samplecode.zip"&gt;Download code (659KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=9153b1ef-840a-4b34-af11-f6505e610046" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,9153b1ef-840a-4b34-af11-f6505e610046.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=945fc698-72da-4904-90bd-73710bc6065a</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,945fc698-72da-4904-90bd-73710bc6065a.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,945fc698-72da-4904-90bd-73710bc6065a.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=945fc698-72da-4904-90bd-73710bc6065a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>Where's the response?</strong>
          <br />
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 <a href="http://www.netbrick.net/blog/ct.ashx?id=53978180-d3e9-4ba2-90c6-b58ae2894058&amp;url=http%3a%2f%2fwww.gotdotnet.com%2fCommunity%2fUserSamples%2fDetails.aspx%3fSampleGuid%3dbf59c98e-d708-4f8e-9795-8bae1825c3b6"><strong><font color="#2b5298">ManagedThreadPool</font></strong></a> in
my application could get to my request now or whether the request would
be pooled.
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font color="#0000ff">ManagedThreadPool.ActiveThreads
&lt; ManagedThreadPool.MaxThreads <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> 2</font>
            </span>
          </p>
        </blockquote>
        <p>
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.
</p>
        <p>
          <strong>Lesson Learned</strong>
          <br />
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.
</p>
        <p>
(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...)
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=945fc698-72da-4904-90bd-73710bc6065a" />
      </body>
      <title>ManagedThreadPool - Managing the Thread Pool</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,945fc698-72da-4904-90bd-73710bc6065a.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/11/01/ManagedThreadPool+Managing+The+Thread+Pool.aspx</link>
      <pubDate>Wed, 01 Nov 2006 19:46:49 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;Where's the response?&lt;/strong&gt;
&lt;br&gt;
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 &lt;a href="http://www.netbrick.net/blog/ct.ashx?id=53978180-d3e9-4ba2-90c6-b58ae2894058&amp;amp;url=http%3a%2f%2fwww.gotdotnet.com%2fCommunity%2fUserSamples%2fDetails.aspx%3fSampleGuid%3dbf59c98e-d708-4f8e-9795-8bae1825c3b6"&gt;&lt;strong&gt;&lt;font color=#2b5298&gt;ManagedThreadPool&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt; in
my application could&amp;nbsp;get to my request&amp;nbsp;now or whether the request would
be pooled.
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#0000ff&gt;ManagedThreadPool.ActiveThreads
&amp;lt; ManagedThreadPool.MaxThreads &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; 2&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Lesson Learned&lt;/strong&gt;
&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
(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...)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=945fc698-72da-4904-90bd-73710bc6065a" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,945fc698-72da-4904-90bd-73710bc6065a.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=e0061155-0a83-4f64-92da-fa26353c994f</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,e0061155-0a83-4f64-92da-fa26353c994f.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,e0061155-0a83-4f64-92da-fa26353c994f.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e0061155-0a83-4f64-92da-fa26353c994f</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> ImageTypeFinder<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> GetMimeType(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>[]
image)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"image/jpeg"</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> imgtype <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetImageType(image);<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">switch</span> (imgtype)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">case</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"bmp"</span>:<br />
                retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"image/bmp"</span>;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">break</span>;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">case</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"gif"</span>:<br />
                retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"image/gif"</span>;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">break</span>;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">case</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"tif"</span>:<br />
                retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"image/tiff"</span>;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">break</span>;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">case</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"png"</span>:<br />
                retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"image/png"</span>;<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">break</span>;<br />
        }<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> retval;<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> GetImageType(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>[]
image)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> len <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> image.Length;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (len
&gt; 32) len <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 32;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> first32 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ASCIIEncoding.ASCII.GetString(image,
0, len);<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> GetImageType(first32);<br />
    }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> GetImageType(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> first32)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>.Empty;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (first32.StartsWith(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"GIF87a"</span>)
|| first32.StartsWith(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"GIF89a"</span>))<br />
            retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"gif"</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (first32.StartsWith(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"MM"</span>)
|| first32.StartsWith(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"II"</span>))<br />
            retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"tif"</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (first32.Substring(6,
4) == <span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"JFIF"</span> ||
first32.Substring(6, 4) == <span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"Exif"</span>)<br />
            retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"jpg"</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (first32.StartsWith(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"BM"</span>))<br />
            retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"bmp"</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (first32.Substring(1,
3) == <span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"PNG"</span>)<br />
            retval <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"png"</span>;<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> retval;<br />
    }<br /><br />
}<br /></span>
        </p>
        <p>
It's a bit of an esoteric puzzle, but if you're trying to solve this one, the above
code should help.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=e0061155-0a83-4f64-92da-fa26353c994f" />
      </body>
      <title>Image MIME Type from the Byte[]</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,e0061155-0a83-4f64-92da-fa26353c994f.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/09/19/Image+MIME+Type+From+The+Byte.aspx</link>
      <pubDate>Tue, 19 Sep 2006 03:00:41 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; ImageTypeFinder&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; GetMimeType(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;byte&lt;/span&gt;[]
image)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"image/jpeg"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; imgtype &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetImageType(image);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;switch&lt;/span&gt; (imgtype)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"bmp"&lt;/span&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"image/bmp"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"gif"&lt;/span&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"image/gif"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"tif"&lt;/span&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"image/tiff"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"png"&lt;/span&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"image/png"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; retval;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; GetImageType(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;byte&lt;/span&gt;[]
image)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; len &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; image.Length;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (len
&amp;gt; 32) len &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 32;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; first32 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ASCIIEncoding.ASCII.GetString(image,
0, len);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; GetImageType(first32);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; GetImageType(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; first32)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;.Empty;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (first32.StartsWith(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"GIF87a"&lt;/span&gt;)
|| first32.StartsWith(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"GIF89a"&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"gif"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (first32.StartsWith(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"MM"&lt;/span&gt;)
|| first32.StartsWith(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"II"&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"tif"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (first32.Substring(6,
4) == &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"JFIF"&lt;/span&gt; ||
first32.Substring(6, 4) == &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"Exif"&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"jpg"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (first32.StartsWith(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"BM"&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"bmp"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (first32.Substring(1,
3) == &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"PNG"&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"png"&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; retval;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
It's a bit of an esoteric puzzle, but if you're trying to solve this one, the above
code should help.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=e0061155-0a83-4f64-92da-fa26353c994f" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,e0061155-0a83-4f64-92da-fa26353c994f.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=7c816aaa-19b8-4737-bf05-f810dcb2ba4d</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,7c816aaa-19b8-4737-bf05-f810dcb2ba4d.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,7c816aaa-19b8-4737-bf05-f810dcb2ba4d.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7c816aaa-19b8-4737-bf05-f810dcb2ba4d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
The .ASPX page looks something like this:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font color="#000000">&lt;%</font>@
Page Language=<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"C#"</span><br />
  </span>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AutoEventWireup=<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"true"</span><br />
  CodeBehind=<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"extract.aspx.cs"</span><br />
  Inherits=<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"KeyExtractWeb.extract"</span> %&gt;</span>
          </p>
        </blockquote>
        <p>
There is nothing else in the file. Now the code behind looks like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Data;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Configuration;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections.Generic;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections.Specialized;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.IO;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.Security;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI.WebControls;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI.WebControls.WebParts;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI.HtmlControls;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> KeyExtractWeb<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> partial <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> extract
: System.Web.UI.Page<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Page_Load(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> alldata <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>.Empty;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> (StreamReader
sr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> StreamReader(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.Request.InputStream))<br />
            {<br />
                alldata <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> sr.ReadToEnd();<br />
            }<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//convert
to strings - assumes URL encoded data</span><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
pairs <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> alldata.Split('&amp;'); 
<br />
            NameValueCollection
form <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> NameValueCollection(pairs.Length);<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> pair <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> pairs)<br />
            {<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
keyvalue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> pair.Split('<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span>'); 
<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (keyvalue.Length
== 2)<br />
                {<br />
                    form.Add(keyvalue[0],
HttpUtility.UrlDecode(keyvalue[1]));<br />
                }<br />
            }<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (alldata.Length
&gt; 0 &amp;&amp; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.Request.HttpMethod.ToUpper()
== <span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"POST"</span>)<br />
            {<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (form[<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"text"</span>]
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
                {<br />
                    <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//TODO
- do something with the data here</span><br />
                }<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
                    Response.Write(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"***
501 Invalid data ***"</span>);<br />
            }<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
                Response.Write(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">"***
599 GET method not supported. ***"</span>);<br /><br />
            Response.End();<br />
        }<br />
    }<br />
}<br /></span>
        </p>
        <p>
Well, there you have it. There are probably better ways to do this, but I didn't find
one. 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=7c816aaa-19b8-4737-bf05-f810dcb2ba4d" />
      </body>
      <title>Take a POST for REST without a Form in ASP.NET</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,7c816aaa-19b8-4737-bf05-f810dcb2ba4d.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/09/01/Take+A+POST+For+REST+Without+A+Form+In+ASPNET.aspx</link>
      <pubDate>Fri, 01 Sep 2006 09:52:53 GMT</pubDate>
      <description>&lt;p&gt;
Some time ago and again today,&amp;nbsp;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.
&lt;/p&gt;
&lt;p&gt;
The .ASPX page looks something like this:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;lt;%&lt;/font&gt;@
Page Language=&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"C#"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AutoEventWireup=&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"true"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp; CodeBehind=&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"extract.aspx.cs"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp; Inherits=&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"KeyExtractWeb.extract"&lt;/span&gt; %&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
There is nothing else in the file. Now the code behind looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Data;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Configuration;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections.Specialized;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.IO;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.Security;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI.WebControls;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI.WebControls.WebParts;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI.HtmlControls;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; KeyExtractWeb&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; partial &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; extract
: System.Web.UI.Page&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Page_Load(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; alldata &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;.Empty;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; (StreamReader
sr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; StreamReader(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.Request.InputStream))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alldata &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; sr.ReadToEnd();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//convert
to strings - assumes URL encoded data&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
pairs &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; alldata.Split('&amp;amp;'); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NameValueCollection
form &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; NameValueCollection(pairs.Length);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;foreach&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; pair &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; pairs)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
keyvalue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; pair.Split('&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;'); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (keyvalue.Length
== 2)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;form.Add(keyvalue[0],
HttpUtility.UrlDecode(keyvalue[1]));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (alldata.Length
&amp;gt; 0 &amp;amp;&amp;amp; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.Request.HttpMethod.ToUpper()
== &lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"POST"&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (form[&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"text"&lt;/span&gt;]
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//TODO
- do something with the data here&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Response.Write(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"***
501 Invalid data ***"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Response.Write(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;"***
599 GET method not supported. ***"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Response.End();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Well, there you have it. There are probably better ways to do this, but I didn't find
one. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=7c816aaa-19b8-4737-bf05-f810dcb2ba4d" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,7c816aaa-19b8-4737-bf05-f810dcb2ba4d.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=be9efc5f-5c3e-4b68-a833-e2e7b635acae</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,be9efc5f-5c3e-4b68-a833-e2e7b635acae.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,be9efc5f-5c3e-4b68-a833-e2e7b635acae.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=be9efc5f-5c3e-4b68-a833-e2e7b635acae</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>Thread Abortion</strong>
          <br />
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.
</p>
        <p>
          <strong>Clue: IIS 6 and Application Pools</strong>
          <br />
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.
</p>
        <p>
          <strong>Application Pool Properties</strong>
          <br />
I made the following changes on the assumption that because each request to the application
would launch work on a <a href="http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=bf59c98e-d708-4f8e-9795-8bae1825c3b6">ManagedThreadPool</a> 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.
</p>
        <ul>
          <li>
            <strong>Recycling</strong> tab - disable the check boxes</li>
          <li>
            <strong>Performance</strong> tab - diable the check boxes</li>
          <li>
            <strong>Health </strong>tab - uncheck "Enable rapid-fail protection"</li>
        </ul>
        <p>
          <strong>Positive Result</strong>
          <br />
Ran the test again and alakazam! No ThreadAbort exceptions.
</p>
        <p>
          <strong>Threading on ASP.NET</strong>
          <br />
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 <a href="http://blogs.msdn.com/toub/">Stephen
Toub</a> and this Application Pool thing have been among the trickiest.
</p>
        <p>
          <strong>What are the dangers?</strong>
          <br />
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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=be9efc5f-5c3e-4b68-a833-e2e7b635acae" />
      </body>
      <title>ASP.NET, Threading and Application Pools</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,be9efc5f-5c3e-4b68-a833-e2e7b635acae.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/07/31/ASPNET+Threading+And+Application+Pools.aspx</link>
      <pubDate>Mon, 31 Jul 2006 01:31:17 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;Thread Abortion&lt;/strong&gt;
&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Clue: IIS 6 and Application Pools&lt;/strong&gt;
&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Application Pool Properties&lt;/strong&gt;
&lt;br&gt;
I made the following changes on the assumption that because each request to the application
would launch work on a &lt;a href="http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=bf59c98e-d708-4f8e-9795-8bae1825c3b6"&gt;ManagedThreadPool&lt;/a&gt; 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.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recycling&lt;/strong&gt; tab - disable the check boxes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; tab - diable the check boxes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health &lt;/strong&gt;tab - uncheck "Enable rapid-fail protection"&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Positive Result&lt;/strong&gt;
&lt;br&gt;
Ran the test again and alakazam! No ThreadAbort exceptions.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Threading on ASP.NET&lt;/strong&gt;
&lt;br&gt;
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 &lt;a href="http://blogs.msdn.com/toub/"&gt;Stephen
Toub&lt;/a&gt; and this Application Pool thing have been among the trickiest.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;What are the dangers?&lt;/strong&gt;
&lt;br&gt;
I'm sure there are dangers in disabling the safety net around the&amp;nbsp;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.&amp;nbsp;If you have any advice
for me on the matter, I'd love to hear from you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=be9efc5f-5c3e-4b68-a833-e2e7b635acae" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,be9efc5f-5c3e-4b68-a833-e2e7b635acae.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=104fd654-3311-455b-abdf-282cb6065bce</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,104fd654-3311-455b-abdf-282cb6065bce.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,104fd654-3311-455b-abdf-282cb6065bce.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=104fd654-3311-455b-abdf-282cb6065bce</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
          <strong>All the Readers a Local Client</strong>
          <br />
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. 
</p>
        <p>
          <strong>Rolling My Own</strong>
          <br />
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 <a href="http://www.rssjam.com/">RSSJAM.COM</a> and
wrote a little file based ASP.NET app that would do what I wanted.
</p>
        <p>
          <strong>Daily Emails</strong>
          <br />
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.
</p>
        <p>
          <strong>Explosive Growth</strong>
          <br />
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.
</p>
        <p>
The link to email me is at the bottom of the left column here.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=104fd654-3311-455b-abdf-282cb6065bce" />
      </body>
      <title>RssJam.com - My Foray Into Feeds</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,104fd654-3311-455b-abdf-282cb6065bce.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/07/30/RssJamcom+My+Foray+Into+Feeds.aspx</link>
      <pubDate>Sun, 30 Jul 2006 16:01:47 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;All the Readers a Local Client&lt;/strong&gt;
&lt;br&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rolling My Own&lt;/strong&gt;
&lt;br&gt;
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 &lt;a href="http://www.rssjam.com/"&gt;RSSJAM.COM&lt;/a&gt; and
wrote a little file based ASP.NET app that would do what I wanted.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Daily Emails&lt;/strong&gt;
&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Explosive Growth&lt;/strong&gt;
&lt;br&gt;
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.
&lt;/p&gt;
&lt;p&gt;
The link to email me is&amp;nbsp;at the bottom of&amp;nbsp;the left column here.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=104fd654-3311-455b-abdf-282cb6065bce" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,104fd654-3311-455b-abdf-282cb6065bce.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=80d63024-520f-4e83-aca5-e5985ac7cc46</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,80d63024-520f-4e83-aca5-e5985ac7cc46.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,80d63024-520f-4e83-aca5-e5985ac7cc46.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=80d63024-520f-4e83-aca5-e5985ac7cc46</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>The Bug - Submitted June 5, 2006</strong>
          <br />
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.
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <font size="2">
            <p>
              <strong>Title: Long pattern string results in race condition on x64 system but not
x86 system</strong>
            </p>
          </font>
          <br />
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.
</blockquote>
        <p>
This happened after developing a pattern to remove unwanted words from text before
I run the keyword extraction algorithm I wrote based on <a href="http://www.ymatsuo.com/papers/ijait04.pdf">this
whitepaper</a> by a brilliant young researcher named <a href="http://www.ymatsuo.com/top_eng.htm">Yutaka
Matsuo</a> and the honorable professor <a href="http://www.miv.t.u-tokyo.ac.jp/ishizuka/eng.html">Mitsuru
Ishizuka</a> at the University of Tokyo.
</p>
        <p>
          <strong>Fixed - July 7, 2006</strong>
          <br />
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 <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96339">confirmed
and fixed</a>. 
</p>
        <p>
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 <a href="http://connect.microsoft.com/default.aspx">Connect
site</a> and see what happens.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=80d63024-520f-4e83-aca5-e5985ac7cc46" />
      </body>
      <title>.NET Regex Fixed on x64</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,80d63024-520f-4e83-aca5-e5985ac7cc46.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/07/30/NET+Regex+Fixed+On+X64.aspx</link>
      <pubDate>Sun, 30 Jul 2006 03:22:42 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;The Bug - Submitted June 5, 2006&lt;/strong&gt;
&lt;br&gt;
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.
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;font size=2&gt; 
&lt;p&gt;
&lt;strong&gt;Title: Long pattern string results in race condition on x64 system but not
x86 system&lt;/strong&gt;
&lt;/font&gt;
&lt;br&gt;
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.&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
This happened after developing a pattern to remove unwanted words from text before
I run the keyword extraction algorithm I wrote based on &lt;a href="http://www.ymatsuo.com/papers/ijait04.pdf"&gt;this
whitepaper&lt;/a&gt; by a brilliant young researcher named &lt;a href="http://www.ymatsuo.com/top_eng.htm"&gt;Yutaka
Matsuo&lt;/a&gt; and&amp;nbsp;the honorable professor&amp;nbsp;&lt;a href="http://www.miv.t.u-tokyo.ac.jp/ishizuka/eng.html"&gt;Mitsuru
Ishizuka&lt;/a&gt;&amp;nbsp;at the University of Tokyo.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Fixed - July 7, 2006&lt;/strong&gt;
&lt;br&gt;
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 &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96339"&gt;confirmed
and fixed&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://connect.microsoft.com/default.aspx"&gt;Connect
site&lt;/a&gt; and see what happens.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=80d63024-520f-4e83-aca5-e5985ac7cc46" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,80d63024-520f-4e83-aca5-e5985ac7cc46.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=b9c255d9-74b4-45ab-8fd0-c9a04784655a</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,b9c255d9-74b4-45ab-8fd0-c9a04784655a.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,b9c255d9-74b4-45ab-8fd0-c9a04784655a.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b9c255d9-74b4-45ab-8fd0-c9a04784655a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
          <strong>Bring on the Delegates</strong>
        </p>
        <p>
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 <a href="http://blogs.msdn.com/malarch/archive/2005/09/13/466664.aspx">found
this little gem</a> about 5 seconds before my friend suggested taking a look at the
HttpWebRequest's ServicePoint member and the ServicePoint's BindIPEndPointDelegate
member.
</p>
        <p>
          <strong>Glory Hallelujah!</strong>
        </p>
        <p>
One of my new best friends is someone I don't know: Malar Chinnusamy. Thanks a million,
Malar.
</p>
        <p>
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...
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span> IPEndPoint
BindIPEndPoint(ServicePoint servicePoint,<br />
  IPEndPoint remoteEndPoint, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> retryCount);<br /></span>
        </p>
        <p>
That little gem is a beautiful thing. It lead to this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span> IPEndPoint
BindIPEndPointCallback(ServicePoint servicePoint, 
<br />
  IPEndPoint remoteEndPoint, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> retryCount)<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>(retryCount
&lt; 3)<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> IPEndPoint(IPAddress.Parse(<span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New">"192.168.10.60"</span>),
0); 
<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> IPEndPoint(IPAddress.Any,
0);<br />
}<br /></span>
        </p>
        <p>
          <font size="2">and...</font>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font color="#008000">HttpWebRequest</font> req <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (<font color="#008000">HttpWebRequest</font>)<font color="#000000"><font color="#008000">WebRequest</font>.Create</font>(url);<br />
req.ServicePoint.BindIPEndPointDelegate <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><br />
  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><font color="#008000">BindIPEndPoint</font>(BindIPEndPointCallback);<br /></span>
        </p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=b9c255d9-74b4-45ab-8fd0-c9a04784655a" />
      </body>
      <title>HttpWebRequest, ServicePoint and BindIPEndPointDelegate</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,b9c255d9-74b4-45ab-8fd0-c9a04784655a.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/07/29/HttpWebRequest+ServicePoint+And+BindIPEndPointDelegate.aspx</link>
      <pubDate>Sat, 29 Jul 2006 19:43:49 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Bring on the Delegates&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="http://blogs.msdn.com/malarch/archive/2005/09/13/466664.aspx"&gt;found
this little gem&lt;/a&gt; about 5 seconds before my friend suggested taking a look at the
HttpWebRequest's ServicePoint member and the ServicePoint's BindIPEndPointDelegate
member.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Glory Hallelujah!&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
One of my new best friends is someone I don't know: Malar Chinnusamy. Thanks a million,
Malar.
&lt;/p&gt;
&lt;p&gt;
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...
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt; IPEndPoint
BindIPEndPoint(ServicePoint servicePoint,&lt;br&gt;
&amp;nbsp; IPEndPoint remoteEndPoint, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; retryCount);&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
That little gem is a beautiful thing. It lead to this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt;&amp;nbsp;IPEndPoint
BindIPEndPointCallback(ServicePoint servicePoint, 
&lt;br&gt;
&amp;nbsp; IPEndPoint remoteEndPoint, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; retryCount)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt;(retryCount
&amp;lt; 3)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; IPEndPoint(IPAddress.Parse(&lt;span style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New"&gt;"192.168.10.60"&lt;/span&gt;),
0); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; IPEndPoint(IPAddress.Any,
0);&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=2&gt;and...&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#008000&gt;HttpWebRequest&lt;/font&gt; req &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; (&lt;font color=#008000&gt;HttpWebRequest&lt;/font&gt;)&lt;font color=#000000&gt;&lt;font color=#008000&gt;WebRequest&lt;/font&gt;.Create&lt;/font&gt;(url);&lt;br&gt;
req.ServicePoint.BindIPEndPointDelegate &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;font color=#008000&gt;BindIPEndPoint&lt;/font&gt;(BindIPEndPointCallback);&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=b9c255d9-74b4-45ab-8fd0-c9a04784655a" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,b9c255d9-74b4-45ab-8fd0-c9a04784655a.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=2a528632-5861-4aca-933c-f045ae0f5e0b</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,2a528632-5861-4aca-933c-f045ae0f5e0b.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,2a528632-5861-4aca-933c-f045ae0f5e0b.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2a528632-5861-4aca-933c-f045ae0f5e0b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I ran across the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=22E69AE4-7E40-4807-8A86-B3D36FAB68D3&amp;displaylang=en">Consolas
font from Microsoft</a> 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 <a href="http://www.microsoft.com/typography/ClearTypeInfo.mspx">ClearType</a> in
my display settings. 
</p>
        <p>
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.
</p>
        <p>
How many other cool things have I missed? One can never really know. 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2a528632-5861-4aca-933c-f045ae0f5e0b" />
      </body>
      <title>Code Fonts and ClearType</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,2a528632-5861-4aca-933c-f045ae0f5e0b.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/07/07/Code+Fonts+And+ClearType.aspx</link>
      <pubDate>Fri, 07 Jul 2006 20:04:53 GMT</pubDate>
      <description>&lt;p&gt;
I ran across the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=22E69AE4-7E40-4807-8A86-B3D36FAB68D3&amp;amp;displaylang=en"&gt;Consolas
font from Microsoft&lt;/a&gt; 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 &lt;a href="http://www.microsoft.com/typography/ClearTypeInfo.mspx"&gt;ClearType&lt;/a&gt; in
my display settings. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
How many other cool things have I missed? One can never really know. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=2a528632-5861-4aca-933c-f045ae0f5e0b" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,2a528632-5861-4aca-933c-f045ae0f5e0b.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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."
</p>
        <p>
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:
</p>
        <p>
"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."
</p>
        <p>
Here's the simple code:
</p>
        <font color="#0000ff" size="1">
          <p>
            <font face="Courier New" size="2">using</font>
          </p>
        </font>
        <font face="Courier New" color="#000000"> System;<br /></font>
        <font color="#0000ff">
          <font face="Courier New">using</font>
        </font>
        <font face="Courier New" color="#000000"> System.Collections.Generic;<br /></font>
        <font color="#0000ff">
          <font face="Courier New">using</font>
        </font>
        <font face="Courier New" color="#000000"> System.Text;<br /></font>
        <font color="#0000ff">
          <font face="Courier New">
            <br />
namespace</font>
        </font>
        <font face="Courier New" color="#000000"> CrazyEmail<br /></font>
        <font face="Courier New">{<br /></font>
        <font face="Courier New">
          <font color="#0000ff">  class</font>
          <font color="#008080">Program<br /></font>
        </font>
        <font face="Courier New">  {<br /></font>
        <font face="Courier New">
          <font color="#0000ff">    static</font>
          <font color="#0000ff">void</font> Main(<font color="#0000ff">string</font></font>
        <font face="Courier New">[]
args)<br /></font>
        <font face="Courier New">    {<br /></font>
        <font face="Courier New">
          <font color="#0000ff">      
string</font> n = <font color="#008080">Environment</font></font>
        <font face="Courier New">.NewLine;<br /></font>
        <font face="Courier New" color="#0000ff">      
string</font>
        <font face="Courier New"> nn = n + n;<br /></font>
        <font face="Courier New">
          <font color="#0000ff">      
string</font> body = <font color="#800000">"Hello,"</font></font>
        <font face="Courier New"> +
nn<br /></font>
        <font face="Courier New">
          <font color="#0000ff">     
   </font>+ </font>
        <font face="Courier New" color="#800000">"I can think
of no other way..."</font>
        <font face="Courier New"> + nn<br /></font>
        <font face="Courier New">
          <font color="#0000ff">         </font>+ </font>
        <font face="Courier New" color="#800000">"Can
you please respond..."</font>
        <font face="Courier New"> + nn<br /></font>
        <font face="Courier New">
          <font color="#0000ff">         </font>+ </font>
        <font face="Courier New" color="#800000">"You
can either..."</font>
        <font face="Courier New"> + nn<br /></font>
        <font face="Courier New">
          <font color="#0000ff">         </font>+ </font>
        <font face="Courier New" color="#800000">"Thanks,"</font>
        <font face="Courier New"> +
nn<br /></font>
        <font face="Courier New">
          <font color="#0000ff">         </font>+ </font>
        <font face="Courier New" color="#800000">"-Tyler"</font>
        <font face="Courier New">;</font>
        <p>
          <font face="Courier New">
            <font color="#0000ff">       </font>System.Net.Mail.</font>
          <font face="Courier New">
            <font color="#008080">MailMessage</font> msg
= <br /><font color="#0000ff">         new</font> System.Net.Mail.<font color="#008080">MailMessage</font>(<font color="#800000">"myemail@address.com"</font>, <font color="#800000"><a href="mailto:customer@service.com">customer@service.com</a></font>, <br /><font color="#800000"><font color="#0000ff">         </font>"order
#xyz status inquiry"</font></font>
          <font face="Courier New">, body);</font>
        </p>
        <p>
          <font face="Courier New">
            <font color="#0000ff">       </font>System.Net.Mail.</font>
          <font face="Courier New">
            <font color="#008080">SmtpClient</font> client
= <br /><font color="#0000ff">         new</font> System.Net.Mail.<font color="#008080">SmtpClient</font>(<font color="#800000">"mail.myserver.com"</font></font>
          <font face="Courier New">);</font>
        </p>
        <p>
          <font face="Courier New">
            <font color="#0000ff">      
for</font> (<font color="#0000ff">int</font></font>
          <font face="Courier New"> i = 0;
i &lt; 100; i++)<br /></font>
          <font face="Courier New">
            <font color="#0000ff">       </font>{<br /></font>
          <font face="Courier New">
            <font color="#0000ff">       </font> 
client.Send(msg);<br /></font>
          <font face="Courier New" color="#008080">
            <font color="#0000ff">       </font> 
Console</font>
          <font face="Courier New">.WriteLine(i.ToString());<br /></font>
          <font face="Courier New">
            <font color="#0000ff">       </font>}</font>
        </p>
        <p>
          <font face="Courier New">
            <font color="#008080">
              <font color="#0000ff">       </font>Console</font>.WriteLine(<font color="#800000">"Done."</font></font>
          <font face="Courier New">);<br /></font>
          <font face="Courier New" color="#008080">
            <font color="#0000ff">       </font>Console</font>
          <font size="1">
            <font face="Courier New" size="2">.ReadLine();<br /></font>
            <font face="Courier New" size="2">
              <font color="#0000ff">     </font>}<br /></font>
            <font face="Courier New" size="2">  }<br /></font>
            <font face="Courier New" size="2">}</font>
          </font>
        </p>
        <p>
          <font size="1">
            <font face="Courier New" size="2">
            </font> 
</font>
        </p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9" />
      </body>
      <title>Automate Your Customer Service Complaints</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/06/16/Automate+Your+Customer+Service+Complaints.aspx</link>
      <pubDate>Fri, 16 Jun 2006 05:17:40 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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."
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
"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."
&lt;/p&gt;
&lt;p&gt;
Here's the simple code:
&lt;/p&gt;
&lt;font color=#0000ff size=1&gt; 
&lt;p&gt;
&lt;font face="Courier New" size=2&gt;using&lt;/font&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000&gt; System;&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color=#000000&gt; System.Collections.Generic;&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color=#000000&gt; System.Text;&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;
&lt;br&gt;
namespace&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color=#000000&gt; CrazyEmail&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp; class&lt;/font&gt; &lt;font color=#008080&gt;Program&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/font&gt; &lt;font color=#0000ff&gt;void&lt;/font&gt; Main(&lt;font color=#0000ff&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;[]
args)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
string&lt;/font&gt; n = &lt;font color=#008080&gt;Environment&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;.NewLine;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
string&lt;/font&gt;&lt;font face="Courier New"&gt; nn = n + n;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
string&lt;/font&gt; body = &lt;font color=#800000&gt;"Hello,"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; +
nn&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp; &lt;/font&gt;+ &lt;/font&gt;&lt;font face="Courier New" color=#800000&gt;"I can think of
no other way..."&lt;/font&gt;&lt;font face="Courier New"&gt; + nn&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;+ &lt;/font&gt;&lt;font face="Courier New" color=#800000&gt;"Can
you please respond..."&lt;/font&gt;&lt;font face="Courier New"&gt; + nn&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;+ &lt;/font&gt;&lt;font face="Courier New" color=#800000&gt;"You
can either..."&lt;/font&gt;&lt;font face="Courier New"&gt; + nn&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;+ &lt;/font&gt;&lt;font face="Courier New" color=#800000&gt;"Thanks,"&lt;/font&gt;&lt;font face="Courier New"&gt; +
nn&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;+ &lt;/font&gt;&lt;font face="Courier New" color=#800000&gt;"-Tyler"&lt;/font&gt;&lt;font face="Courier New"&gt;;&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;System.Net.Mail.&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#008080&gt;MailMessage&lt;/font&gt; msg
=&amp;nbsp;&lt;br&gt;
&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new&lt;/font&gt; System.Net.Mail.&lt;font color=#008080&gt;MailMessage&lt;/font&gt;(&lt;font color=#800000&gt;"myemail@address.com"&lt;/font&gt;, &lt;font color=#800000&gt;&lt;a href="mailto:customer@service.com"&gt;customer@service.com&lt;/a&gt;&lt;/font&gt;,&amp;nbsp;&lt;br&gt;
&lt;font color=#800000&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;"order
#xyz status inquiry"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;, body);&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;System.Net.Mail.&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#008080&gt;SmtpClient&lt;/font&gt; client
=&amp;nbsp;&lt;br&gt;
&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new&lt;/font&gt; System.Net.Mail.&lt;font color=#008080&gt;SmtpClient&lt;/font&gt;(&lt;font color=#800000&gt;"mail.myserver.com"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;);&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
for&lt;/font&gt; (&lt;font color=#0000ff&gt;int&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; i = 0;
i &amp;lt; 100; i++)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&amp;nbsp;
client.Send(msg);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#008080&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&amp;nbsp;
Console&lt;/font&gt;&lt;font face="Courier New"&gt;.WriteLine(i.ToString());&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#008080&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;Console&lt;/font&gt;.WriteLine(&lt;font color=#800000&gt;"Done."&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#008080&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;Console&lt;/font&gt;&lt;font size=1&gt;&lt;font face="Courier New" size=2&gt;.ReadLine();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;}&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;}&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=1&gt;&lt;font face="Courier New" size=2&gt;&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,dbaf3f95-ceeb-403e-8a2c-daa57f7e22c9.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=fac8f212-933e-414a-aa89-6f849aecbdac</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,fac8f212-933e-414a-aa89-6f849aecbdac.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,fac8f212-933e-414a-aa89-6f849aecbdac.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fac8f212-933e-414a-aa89-6f849aecbdac</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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&lt;T&gt; class ran away with all my machine's memory.
</p>
        <p>
So what to do?
</p>
        <p>
I didn't really want to change my code. I like the Queue&lt;T&gt; class. So I wrote
a class I call Hopper&lt;T&gt; which acts like Queue&lt;T&gt; 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&lt;T&gt;.
</p>
        <font color="#0000ff" size="1">
          <p>
            <font face="Courier New" size="2">public</font>
          </p>
        </font>
        <font face="Courier New">
          <font color="#000000"> Hopper(<br />
  </font>
          <font color="#0000ff">string</font>
          <font color="#000000"> cachePath, 
<br />
  </font>
          <font color="#0000ff">string</font>
          <font color="#000000"> uniqueFileExtension, 
<br />
  </font>
          <font color="#0000ff">int</font>
          <font color="#000000"> hopperCapacity, 
<br />
  </font>
          <font color="#0000ff">int</font>
          <font color="#000000"> reorderLevel)</font>
        </font>
        <p>
This class takes advantage of the System.Runtime.Serialization and the System.Runtime.Serialization.Formatters.Binary
namespaces.
</p>
        <p>
Download the code and give it a try. And be sure to let me know what you think.
</p>
        <a href="http://www.netbrick.net/blog/content/binary/Hopper.zip">Hopper.zip (2.74
KB)</a>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=fac8f212-933e-414a-aa89-6f849aecbdac" />
      </body>
      <title>Hopper&amp;lt;T&amp;gt;: Queue&amp;lt;T&amp;gt; Class in C# that Caches to Disk</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,fac8f212-933e-414a-aa89-6f849aecbdac.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/05/12/HopperltTgt+QueueltTgt+Class+In+C+That+Caches+To+Disk.aspx</link>
      <pubDate>Fri, 12 May 2006 16:59:20 GMT</pubDate>
      <description>&lt;p&gt;
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&amp;lt;T&amp;gt; class ran away with all my machine's memory.
&lt;/p&gt;
&lt;p&gt;
So what to do?
&lt;/p&gt;
&lt;p&gt;
I didn't really want to change my code. I like the Queue&amp;lt;T&amp;gt; class. So I wrote
a class I call Hopper&amp;lt;T&amp;gt; which acts like Queue&amp;lt;T&amp;gt; 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&amp;lt;T&amp;gt;.
&lt;/p&gt;
&lt;font color=#0000ff size=1&gt; 
&lt;p&gt;
&lt;font face="Courier New" size=2&gt;public&lt;/font&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000&gt; Hopper(&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff&gt;string&lt;/font&gt;&lt;font color=#000000&gt; cachePath, 
&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff&gt;string&lt;/font&gt;&lt;font color=#000000&gt; uniqueFileExtension, 
&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff&gt;int&lt;/font&gt;&lt;font color=#000000&gt; hopperCapacity, 
&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff&gt;int&lt;/font&gt;&lt;font color=#000000&gt; reorderLevel)&lt;/font&gt;&gt;
&lt;/font&gt; 
&lt;p&gt;
This class takes advantage of the System.Runtime.Serialization and the System.Runtime.Serialization.Formatters.Binary
namespaces.
&lt;/p&gt;
&lt;p&gt;
Download the code and give it a try. And be sure to let me know what you think.
&lt;/p&gt;
&lt;a href="http://www.netbrick.net/blog/content/binary/Hopper.zip"&gt;Hopper.zip (2.74
KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=fac8f212-933e-414a-aa89-6f849aecbdac" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,fac8f212-933e-414a-aa89-6f849aecbdac.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=835e0bb2-167a-4d21-8d1c-ad5a207dd674</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,835e0bb2-167a-4d21-8d1c-ad5a207dd674.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,835e0bb2-167a-4d21-8d1c-ad5a207dd674.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=835e0bb2-167a-4d21-8d1c-ad5a207dd674</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://www.w3.org/TR/html4/sgml/loosedtd.html">official
HTML DTD</a>.
</p>
        <p>
Re-remembering <a href="http://www.autisticcuckoo.net/archive.php?id=2005/05/01/art-of-reading-dtd">how
to read a DTD</a> 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.
</p>
        <p>
Here's an example of how to use it:
</p>
        <font color="#008000" size="1">
          <p>
            <font face="Courier New" color="#000000" size="2">
              <font color="#000000">HtmlDocument</font> doc
= new HtmlDocument(url, html);<br /></font>
            <font face="Courier New" color="#000000" size="2">StringBuilder sb = new StringBuilder();<br /></font>
            <font face="Courier New" color="#000000" size="2">Collection&lt;HtmlTag&gt;
pcdata = doc.GetList(DtdElement.A);<br /></font>
            <font face="Courier New" color="#000000" size="2">foreach (HtmlTag tag in pcdata)<br /></font>
            <font face="Courier New" color="#000000" size="2">{<br /></font>
            <font face="Courier New" color="#000000" size="2">  if (!tag.EndTag)<br /></font>
            <font face="Courier New" color="#000000" size="2">  {<br /></font>
            <font face="Courier New" color="#000000" size="2">    Dictionary&lt;string,
string&gt; attributes = doc.GetAttributes(tag);<br /></font>
            <font color="#000000">
              <font face="Courier New" size="2">   
sb.AppendLine("");<br /></font>
              <font face="Courier New" size="2">    sb.AppendLine("A: " +
doc.ReadSlice(tag.Slice));</font>
            </font>
          </p>
          <p>
            <font face="Courier New" color="#000000" size="2">    foreach (KeyValuePair&lt;string,
string&gt; pair in attributes)<br /></font>
            <font face="Courier New" color="#000000" size="2">    {<br /></font>
            <font face="Courier New" color="#000000" size="2">     
sb.AppendLine(" " + pair.Key + "=" + pair.Value);<br /></font>
            <font face="Courier New" color="#000000" size="2">    }<br /></font>
            <font color="#000000">
              <font face="Courier New" size="2">  }<br /></font>
              <font face="Courier New" size="2">}</font>
            </font>
          </p>
        </font>
        <p>
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.  
</p>
        <a href="http://www.netbrick.net/blog/content/binary/NetBrick.Net.OpenUtils1.zip">NetBrick.Net.OpenUtils1.zip
(35.31 KB)</a>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=835e0bb2-167a-4d21-8d1c-ad5a207dd674" />
      </body>
      <title>Parsing HTML with C# by the Book (DTD)</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,835e0bb2-167a-4d21-8d1c-ad5a207dd674.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/05/11/Parsing+HTML+With+C+By+The+Book+DTD.aspx</link>
      <pubDate>Thu, 11 May 2006 21:14:33 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;a href="http://www.w3.org/TR/html4/sgml/loosedtd.html"&gt;official
HTML DTD&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Re-remembering &lt;a href="http://www.autisticcuckoo.net/archive.php?id=2005/05/01/art-of-reading-dtd"&gt;how
to read a DTD&lt;/a&gt; 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&amp;nbsp;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&amp;nbsp;encapsulate
that in a usable object model.
&lt;/p&gt;
&lt;p&gt;
Here's an example of how to use it:
&lt;/p&gt;
&lt;font color=#008000 size=1&gt; 
&lt;p&gt;
&lt;font face="Courier New" color=#000000 size=2&gt;&lt;font color=#000000&gt;HtmlDocument&lt;/font&gt; doc
= new HtmlDocument(url, html);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;StringBuilder sb = new StringBuilder();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;Collection&amp;lt;HtmlTag&amp;gt; pcdata
= doc.GetList(DtdElement.A);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;foreach (HtmlTag tag in pcdata)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp; if (!tag.EndTag)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dictionary&amp;lt;string,
string&amp;gt; attributes = doc.GetAttributes(tag);&lt;br&gt;
&lt;/font&gt;&lt;font color=#000000&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.AppendLine("");&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.AppendLine("A: " + doc.ReadSlice(tag.Slice));&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (KeyValuePair&amp;lt;string,
string&amp;gt; pair in attributes)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
sb.AppendLine(" " + pair.Key + "=" + pair.Value);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color=#000000&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;}&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/font&gt; 
&lt;p&gt;
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.&amp;nbsp;&amp;nbsp;
&lt;/p&gt;
&lt;a href="http://www.netbrick.net/blog/content/binary/NetBrick.Net.OpenUtils1.zip"&gt;NetBrick.Net.OpenUtils1.zip
(35.31 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=835e0bb2-167a-4d21-8d1c-ad5a207dd674" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,835e0bb2-167a-4d21-8d1c-ad5a207dd674.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=03317c58-0dba-42d7-9091-19971f4f0582</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,03317c58-0dba-42d7-9091-19971f4f0582.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,03317c58-0dba-42d7-9091-19971f4f0582.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=03317c58-0dba-42d7-9091-19971f4f0582</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx">SharpZipLib
library</a>.
</p>
        <p>
Then I found <a href="http://www.mostlylucid.co.uk/archive/2004/04/06/958.aspx">Scott
Galloway's compression helper</a>. I highly recommend it. Anyway, here's the code
without the helper. Visit Scott's blog for that.
</p>
        <p>
          <font face="Courier New" color="#0000ff"> public class ResultSerializer<br />
 {<br />
  public static byte[] Serialize(ResultData data)<br />
  {<br />
   //convert to byte[]<br />
   IFormatter frm = new BinaryFormatter();<br />
   MemoryStream ms = new MemoryStream(8096);<br />
   frm.Serialize(ms, data);<br />
   byte[] serial = ms.ToArray();<br />
   ms.Close();<br />
   byte[] retval = ZipUtil.Compress(serial);<br />
   return retval;<br />
  }<br />
  public static ResultData Deserialize(byte[] zipData)<br />
  {<br />
   byte[] data = ZipUtil.DeCompress(zipData);<br />
   //now deserialize<br />
   IFormatter frm = new BinaryFormatter();<br />
   MemoryStream datams = new MemoryStream(data, 0, data.Length);<br />
   ResultData retval = (ResultData)frm.Deserialize(datams);<br />
   return retval;<br />
  }<br />
 }</font>
        </p>
        <p>
Note that I renamed Scott's helper "ZipUtil" for my own reasons. 
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=03317c58-0dba-42d7-9091-19971f4f0582" />
      </body>
      <title>SharpZipLib and Kudos to Scott Galloway</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,03317c58-0dba-42d7-9091-19971f4f0582.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/03/08/SharpZipLib+And+Kudos+To+Scott+Galloway.aspx</link>
      <pubDate>Wed, 08 Mar 2006 22:05:47 GMT</pubDate>
      <description>&lt;p&gt;
I had to get&amp;nbsp;an object serialized&amp;nbsp;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 &lt;a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx"&gt;SharpZipLib
library&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Then I found &lt;a href="http://www.mostlylucid.co.uk/archive/2004/04/06/958.aspx"&gt;Scott
Galloway's compression helper&lt;/a&gt;. I highly recommend it. Anyway, here's the code
without the helper. Visit Scott's blog for that.
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New" color=#0000ff&gt;&amp;nbsp;public class ResultSerializer&lt;br&gt;
&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;public static byte[] Serialize(ResultData data)&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;//convert to byte[]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;IFormatter frm = new BinaryFormatter();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;MemoryStream ms = new MemoryStream(8096);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;frm.Serialize(ms, data);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;byte[] serial = ms.ToArray();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;ms.Close();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;byte[] retval = ZipUtil.Compress(serial);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;return retval;&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;public static ResultData Deserialize(byte[] zipData)&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;byte[] data = ZipUtil.DeCompress(zipData);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;//now deserialize&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;IFormatter frm = new BinaryFormatter();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;MemoryStream datams = new MemoryStream(data, 0, data.Length);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;ResultData retval = (ResultData)frm.Deserialize(datams);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;return retval;&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Note that I renamed Scott's helper "ZipUtil" for my own reasons. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=03317c58-0dba-42d7-9091-19971f4f0582" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,03317c58-0dba-42d7-9091-19971f4f0582.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=0609dbda-a360-404a-804d-895b941384f2</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,0609dbda-a360-404a-804d-895b941384f2.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,0609dbda-a360-404a-804d-895b941384f2.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0609dbda-a360-404a-804d-895b941384f2</wfw:commentRss>
      <slash:comments>9</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
Failed to connect to an IPC port:  Access Denied
</p>
        <p>
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:
</p>
        <p>
        </p>
        <p>
          <span face="Courier">
            <font face="Courier New" color="#0000ff">Dictionary&lt;string,
string&gt; props = new Dictionary&lt;string, string&gt;();<br />
props.Add("authorizedGroup", "Everyone");<br />
props.Add("portName", "ServerPortName");<br />
serverChannel = new IpcServerChannel(props, null);<br />
ChannelServices.RegisterChannel(serverChannel, true);<br />
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalByRefObjectSubClass), 
<br />
   "ServerAppName", WellKnownObjectMode.SingleCall);<br />
serverChannel.StartListening(null);</font>
          </span>
        </p>
        <p>
With the client setup like this in the web service:
</p>
        <p>
          <span face="Courier">
            <p>
              <font face="Courier New" color="#0000ff">using System;<br />
using System.Data;<br />
using System.Configuration;<br />
using System.Threading;<br />
using System.Web;<br />
using System.Web.Security;<br />
using System.Web.UI;<br />
using System.Web.UI.WebControls;<br />
using System.Web.UI.WebControls.WebParts;<br />
using System.Web.UI.HtmlControls;<br />
using System.Runtime.Remoting;<br />
using System.Runtime.Remoting.Channels;<br />
using System.Runtime.Remoting.Channels.Ipc;<br />
using MyRemotingInterfaces;</font>
            </p>
            <p>
              <font face="Courier New" color="#0000ff">public class RemotingClientFactory<br />
{<br />
   private static Mutex mut = new Mutex();<br />
   private static WellKnownClientTypeEntry remoteEntry;<br />
   private static IpcClientChannel remoteChannel;<br />
   private static string remoteUrl = "ipc://RemoteExampleRemoteServer/RemoteExampleRemote";</font>
            </p>
            <p>
              <font face="Courier New" color="#0000ff">   static RemotingClientFactory()
{ }</font>
            </p>
            <p>
              <font face="Courier New" color="#0000ff">   public static IMyRemoteObject
CreateRemote()<br />
   {<br />
      if (remoteChannel == null || remoteEntry == null)<br />
      {<br />
         mut.WaitOne();<br />
         try<br />
         {<br />
            if (remoteChannel == null)<br />
            {<br />
               remoteChannel = new
IpcClientChannel();<br />
               ChannelServices.RegisterChannel(remoteChannel,
true);<br />
            }<br />
            if (remoteEntry == null)<br />
            {<br />
               remoteEntry = 
<br />
                
new WellKnownClientTypeEntry(typeof(MyRemotingInterfaces.IMyRemoteObject),<br />
                     
 remoteUrl);<br />
               RemotingConfiguration.RegisterWellKnownClientType(remoteEntry);<br />
            }<br />
         }<br />
         finally<br />
         {<br />
            mut.ReleaseMutex();<br />
         }<br />
      }<br />
      try<br />
      {<br />
         IMyRemoteObject obj = 
<br />
           </font>
              <font face="Courier New" color="#0000ff">(IRemoteExampleRemote)Activator.GetObject(remoteEntry.ObjectType,
remoteUrl);<br />
         return obj;<br />
      }<br />
      catch(Exception e)<br />
      {<br />
         //TODO log then rethrow<br />
         throw e;<br />
      }<br />
   }<br />
}</font>
            </p>
          </span>
        </p>
        <p>
        </p>
        <p>
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.
</p>
        <p>
Let me know if you find a better way or if this helps you. And good luck.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=0609dbda-a360-404a-804d-895b941384f2" />
      </body>
      <title>ASP.NET and IPC Remoting</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,0609dbda-a360-404a-804d-895b941384f2.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/02/22/ASPNET+And+IPC+Remoting.aspx</link>
      <pubDate>Wed, 22 Feb 2006 17:02:44 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Failed to connect to an IPC port:&amp;nbsp; Access Denied
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span face="Courier"&gt;&lt;font face="Courier New" color=#0000ff&gt;Dictionary&amp;lt;string,
string&amp;gt; props = new Dictionary&amp;lt;string, string&amp;gt;();&lt;br&gt;
props.Add("authorizedGroup", "Everyone");&lt;br&gt;
props.Add("portName", "ServerPortName");&lt;br&gt;
serverChannel = new IpcServerChannel(props, null);&lt;br&gt;
ChannelServices.RegisterChannel(serverChannel, true);&lt;br&gt;
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalByRefObjectSubClass), 
&lt;br&gt;
&amp;nbsp; &amp;nbsp;"ServerAppName", WellKnownObjectMode.SingleCall);&lt;br&gt;
serverChannel.StartListening(null);&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
With the client setup like this in the web service:
&lt;/p&gt;
&lt;p&gt;
&lt;span face="Courier"&gt; 
&lt;p&gt;
&lt;font face="Courier New" color=#0000ff&gt;using System;&lt;br&gt;
using System.Data;&lt;br&gt;
using System.Configuration;&lt;br&gt;
using System.Threading;&lt;br&gt;
using System.Web;&lt;br&gt;
using System.Web.Security;&lt;br&gt;
using System.Web.UI;&lt;br&gt;
using System.Web.UI.WebControls;&lt;br&gt;
using System.Web.UI.WebControls.WebParts;&lt;br&gt;
using System.Web.UI.HtmlControls;&lt;br&gt;
using System.Runtime.Remoting;&lt;br&gt;
using System.Runtime.Remoting.Channels;&lt;br&gt;
using System.Runtime.Remoting.Channels.Ipc;&lt;br&gt;
using MyRemotingInterfaces;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New" color=#0000ff&gt;public class RemotingClientFactory&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; &amp;nbsp;private static Mutex mut = new Mutex();&lt;br&gt;
&amp;nbsp; &amp;nbsp;private static WellKnownClientTypeEntry remoteEntry;&lt;br&gt;
&amp;nbsp; &amp;nbsp;private static IpcClientChannel remoteChannel;&lt;br&gt;
&amp;nbsp; &amp;nbsp;private static string remoteUrl = "ipc://RemoteExampleRemoteServer/RemoteExampleRemote";&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New" color=#0000ff&gt;&amp;nbsp; &amp;nbsp;static RemotingClientFactory()
{ }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New" color=#0000ff&gt;&amp;nbsp; &amp;nbsp;public static IMyRemoteObject
CreateRemote()&lt;br&gt;
&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if (remoteChannel == null || remoteEntry == null)&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;mut.WaitOne();&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;try&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if (remoteChannel == null)&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;remoteChannel = new
IpcClientChannel();&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;ChannelServices.RegisterChannel(remoteChannel,
true);&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;if (remoteEntry == null)&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;remoteEntry = 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
new WellKnownClientTypeEntry(typeof(MyRemotingInterfaces.IMyRemoteObject),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;remoteUrl);&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;RemotingConfiguration.RegisterWellKnownClientType(remoteEntry);&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;finally&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;mut.ReleaseMutex();&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;try&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;IMyRemoteObject obj = 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New" color=#0000ff&gt;(IRemoteExampleRemote)Activator.GetObject(remoteEntry.ObjectType,
remoteUrl);&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return obj;&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;catch(Exception e)&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;//TODO log then rethrow&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;throw e;&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;
&amp;nbsp; &amp;nbsp;}&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/span&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
Let me know if you find a better way or if this helps you. And good luck.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=0609dbda-a360-404a-804d-895b941384f2" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,0609dbda-a360-404a-804d-895b941384f2.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=809c90a1-a5b7-4102-b4b3-f78316082faf</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,809c90a1-a5b7-4102-b4b3-f78316082faf.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,809c90a1-a5b7-4102-b4b3-f78316082faf.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=809c90a1-a5b7-4102-b4b3-f78316082faf</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
          <strong>Step One</strong>
          <br />
Create the Windows Service project using the New Project wizard and the Windows Service
template.
</p>
        <p>
Step Two<br />
Modify the nicely created program.cs file as follows:
</p>
        <pre>using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
#if (DEBUG)
   class Program
#else
   static class Program
#endif
   {
      /// 
<SUMMARY></SUMMARY>
      /// 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       }
   } } </pre>
        <p>
          <strong>Step Three</strong>
          <br />
Modify the Service1.cs file as follows:
</p>
        <pre>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.
      }
   }
}
</pre>
        <p>
          <strong>Step Four</strong>
          <br />
Change the output type (in properties page of the project) to console application.
</p>
        <p>
Now debug away!
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=809c90a1-a5b7-4102-b4b3-f78316082faf" />
      </body>
      <title>Easy Debug Windows Service</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,809c90a1-a5b7-4102-b4b3-f78316082faf.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/02/14/Easy+Debug+Windows+Service.aspx</link>
      <pubDate>Tue, 14 Feb 2006 16:58:54 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step One&lt;/strong&gt;
&lt;br&gt;
Create the Windows Service project using the New Project wizard and the Windows Service
template.
&lt;/p&gt;
&lt;p&gt;
Step Two&lt;br&gt;
Modify the nicely created program.cs file as follows:
&lt;/p&gt;
&lt;pre&gt;using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
#if (DEBUG)
&amp;nbsp; &amp;nbsp;class Program
#else
&amp;nbsp; &amp;nbsp;static class Program
#endif
&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;/// 
&lt;SUMMARY&gt;
&lt;/SUMMARY&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;/// The main entry point for the application. &amp;nbsp; &amp;nbsp;&amp;nbsp;
&amp;nbsp;/// #if (DEBUG) &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;static void Main(string[] args) #else
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;static void Main() #endif &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{ #if
(DEBUG) &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;ServiceRunner sr = new ServiceRunner();
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;sr.Start(args); &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;
&amp;nbsp;Console.WriteLine("Started... Hit enter to stop..."); &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;
&amp;nbsp;Console.ReadLine(); &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;sr.Stop(); #else
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;ServiceBase[] ServicesToRun; &amp;nbsp; &amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp; &amp;nbsp;ServicesToRun = new ServiceBase[] { new Service1() }; &amp;nbsp; &amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp; &amp;nbsp;ServiceBase.Run(ServicesToRun); #endif &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}
&amp;nbsp; &amp;nbsp;} } &lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Step Three&lt;/strong&gt;
&lt;br&gt;
Modify the Service1.cs file as follows:
&lt;/p&gt;
&lt;pre&gt;using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace YourNameSpace
{
&amp;nbsp; &amp;nbsp;public partial class Service1 : ServiceBase
&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;private ServiceRunner serviceRunner = null;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;public Service1()
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;InitializeComponent();
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;serviceRunner = new ServiceRunner();
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}

&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;protected override void OnStart(string[] args)
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;serviceRunner.Start(args);
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}

&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;protected override void OnStop()
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;serviceRunner.Stop();
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}
&amp;nbsp; &amp;nbsp;}

&amp;nbsp; &amp;nbsp;internal class ServiceRunner
&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;public void Start(string[] args)
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;//TODO: Add code that will execute on start.
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;public void Stop()
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;//TODO: Add code that will execute on stop.
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}
&amp;nbsp; &amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Step Four&lt;/strong&gt;
&lt;br&gt;
Change the output type (in properties page of the project) to console application.
&lt;/p&gt;
&lt;p&gt;
Now debug away!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=809c90a1-a5b7-4102-b4b3-f78316082faf" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,809c90a1-a5b7-4102-b4b3-f78316082faf.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=a4522d5d-6547-4baa-81c2-08fb10f046de</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,a4522d5d-6547-4baa-81c2-08fb10f046de.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,a4522d5d-6547-4baa-81c2-08fb10f046de.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a4522d5d-6547-4baa-81c2-08fb10f046de</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I recently ran into Richard Northedge's excellent article and C# rendition of the
OpenNLP libraries as posted on <a href="http://www.codeproject.com/csharp/englishparsing.asp"><font color="#3f5d72">Code
Project</font></a>. 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.
</p>
        <p>
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.
</p>
        <p>
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).
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=a4522d5d-6547-4baa-81c2-08fb10f046de" />
      </body>
      <title>OpenNLP for .NET</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,a4522d5d-6547-4baa-81c2-08fb10f046de.aspx</guid>
      <link>http://www.tsjensen.com/blog/2006/02/10/OpenNLP+For+NET.aspx</link>
      <pubDate>Fri, 10 Feb 2006 16:56:25 GMT</pubDate>
      <description>&lt;p&gt;
I recently ran into Richard Northedge's excellent article and C# rendition of the
OpenNLP libraries as posted on &lt;a href="http://www.codeproject.com/csharp/englishparsing.asp"&gt;&lt;font color=#3f5d72&gt;Code
Project&lt;/font&gt;&lt;/a&gt;. 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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=a4522d5d-6547-4baa-81c2-08fb10f046de" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,a4522d5d-6547-4baa-81c2-08fb10f046de.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=b516e711-4853-47e9-9a65-996c121ad074</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,b516e711-4853-47e9-9a65-996c121ad074.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,b516e711-4853-47e9-9a65-996c121ad074.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b516e711-4853-47e9-9a65-996c121ad074</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <a href="http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl" target="_blank"><font color="#3f5d72">AWS
url</font></a>. 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):
</p>
        <p style="FONT-SIZE: 8pt">
------------------------------------------------------------------------------------------------------<br />
c:\&gt;wsdl /o:test.cs http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl<br />
Microsoft (R) Web Services Description Language Utility<br />
[Microsoft (R) .NET Framework, Version 2.0.50727.42]<br />
Copyright (C) Microsoft Corporation. All rights reserved.<br />
Error: There was an error processing 'http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl'.<br />
- The document at the url http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl
was not recognized as a known document type.<br /><br />
The error message from each known type may help you fix the problem:<br />
- Report from 'DISCO Document' is 'Discovery document at the URL http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl
could not be found.'.<br />
- The document format is not recognized.<br />
- Report from 'WSDL Document' is 'There is an error in XML document (140, 3).'.<br />
- The element was not expected in this context: 
<FOO xmlns="http://schemas.xmlsoap.org/wsdl/"></FOO>
... 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 
<SCHEMA></SCHEMA>
and its namespace should be 'http://www.w3.org/2001/XMLSchema'.'.<br /><br />
If you would like more help, please type "wsdl /?".<br />
------------------------------------------------------------------------------------------------------
</p>
        <p>
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:
</p>
        <p style="FONT-SIZE: 8pt">
------------------------------------------------------------------------------------------------------<br />
c:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin&gt;wsdl /o:test.cs
http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl<br />
Microsoft (R) Web Services Description Language Utility<br />
[Microsoft (R) .NET Framework, Version 1.1.4322.573]<br />
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.<br /><br />
Writing file 'test.cs'.<br />
------------------------------------------------------------------------------------------------------
</p>
        <p>
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 &lt;definitions&gt; and &lt;types&gt; now had a namespace
prefix &lt;wsdl:definitions&gt; and &lt;wsdl:types&gt; along with the namespace declaration
in the &lt;definitions&gt; node changed from <strong>xmlns="http://schemas.xmlsoap.org/wsdl/"</strong> to <strong>xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"</strong>.
</p>
        <p>
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 <strong>update web reference</strong> will not work.
</p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=b516e711-4853-47e9-9a65-996c121ad074" />
      </body>
      <title>WSDL.EXE Problem in .NET 2.0</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,b516e711-4853-47e9-9a65-996c121ad074.aspx</guid>
      <link>http://www.tsjensen.com/blog/2005/12/27/WSDLEXE+Problem+In+NET+20.aspx</link>
      <pubDate>Tue, 27 Dec 2005 16:55:32 GMT</pubDate>
      <description>&lt;p&gt;
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 &lt;a href="http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl" target=_blank&gt;&lt;font color=#3f5d72&gt;AWS
url&lt;/font&gt;&lt;/a&gt;. 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):
&lt;/p&gt;
&lt;p style="FONT-SIZE: 8pt"&gt;
------------------------------------------------------------------------------------------------------&lt;br&gt;
c:\&amp;gt;wsdl /o:test.cs http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl&lt;br&gt;
Microsoft (R) Web Services Description Language Utility&lt;br&gt;
[Microsoft (R) .NET Framework, Version 2.0.50727.42]&lt;br&gt;
Copyright (C) Microsoft Corporation. All rights reserved.&lt;br&gt;
Error: There was an error processing 'http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl'.&lt;br&gt;
- The document at the url http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl
was not recognized as a known document type.&lt;br&gt;
&lt;br&gt;
The error message from each known type may help you fix the problem:&lt;br&gt;
- Report from 'DISCO Document' is 'Discovery document at the URL http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl
could not be found.'.&lt;br&gt;
- The document format is not recognized.&lt;br&gt;
- Report from 'WSDL Document' is 'There is an error in XML document (140, 3).'.&lt;br&gt;
- The element was not expected in this context: 
&lt;FOO xmlns="http://schemas.xmlsoap.org/wsdl/"&gt;
&lt;/FOO&gt;
... 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 
&lt;SCHEMA&gt;
&lt;/SCHEMA&gt;
and its namespace should be 'http://www.w3.org/2001/XMLSchema'.'.&lt;br&gt;
&lt;br&gt;
If you would like more help, please type "wsdl /?".&lt;br&gt;
------------------------------------------------------------------------------------------------------
&lt;/p&gt;
&lt;p&gt;
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:
&lt;/p&gt;
&lt;p style="FONT-SIZE: 8pt"&gt;
------------------------------------------------------------------------------------------------------&lt;br&gt;
c:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin&amp;gt;wsdl /o:test.cs
http://awis.amazonaws.com/AlexaWebSearchPlatform/2005-12-01/AlexaWebSearchPlatform.wsdl&lt;br&gt;
Microsoft (R) Web Services Description Language Utility&lt;br&gt;
[Microsoft (R) .NET Framework, Version 1.1.4322.573]&lt;br&gt;
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.&lt;br&gt;
&lt;br&gt;
Writing file 'test.cs'.&lt;br&gt;
------------------------------------------------------------------------------------------------------
&lt;/p&gt;
&lt;p&gt;
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 &amp;lt;definitions&amp;gt; and &amp;lt;types&amp;gt; now had a namespace
prefix &amp;lt;wsdl:definitions&amp;gt; and &amp;lt;wsdl:types&amp;gt; along with the namespace declaration
in the &amp;lt;definitions&amp;gt; node changed from &lt;strong&gt;xmlns="http://schemas.xmlsoap.org/wsdl/"&lt;/strong&gt; to &lt;strong&gt;xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
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 &lt;strong&gt;update web reference&lt;/strong&gt; will not work.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=b516e711-4853-47e9-9a65-996c121ad074" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,b516e711-4853-47e9-9a65-996c121ad074.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=7db754eb-b5f1-4b9d-af95-c46ba4444c3b</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,7db754eb-b5f1-4b9d-af95-c46ba4444c3b.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,7db754eb-b5f1-4b9d-af95-c46ba4444c3b.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7db754eb-b5f1-4b9d-af95-c46ba4444c3b</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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...
</p>
        <p>
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. 
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=7db754eb-b5f1-4b9d-af95-c46ba4444c3b" />
      </body>
      <title>DotNetNuke 4.0 Go To Definition</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,7db754eb-b5f1-4b9d-af95-c46ba4444c3b.aspx</guid>
      <link>http://www.tsjensen.com/blog/2005/12/10/DotNetNuke+40+Go+To+Definition.aspx</link>
      <pubDate>Sat, 10 Dec 2005 16:53:54 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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...
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=7db754eb-b5f1-4b9d-af95-c46ba4444c3b" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,7db754eb-b5f1-4b9d-af95-c46ba4444c3b.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=500e56cd-e99d-4c25-a210-86b9c4e011f5</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,500e56cd-e99d-4c25-a210-86b9c4e011f5.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,500e56cd-e99d-4c25-a210-86b9c4e011f5.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=500e56cd-e99d-4c25-a210-86b9c4e011f5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="entry-body">
          <p>
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.
</p>
          <p>
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. 
</p>
          <p>
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.
</p>
          <p>
            <strong>ADO.NET </strong>
          </p>
          <ul>
            <li>
Bulk updates: 1,000,000 row insert for 1.1: 30 minutes; for 2.0: 45 seconds 
</li>
            <li>
Dataset binary serialization in remoting: faster DS over the wire (up to 6 times smaller) 
</li>
            <li>
DataTable now supports XML read, write, schema, merge, load 
</li>
            <li>
DataView.ToTable method allows creation of a new DataTable from a view</li>
          </ul>
          <p>
            <strong>C# 2.0</strong>
          </p>
          <ul>
            <li>
Generics: generic class later cast to a specific type. Collections are the best example:
a list of some type: List&lt;someType&gt; 
</li>
            <li>
Anonymous methods: allows code to be passed as a parameter rather than requiring a
delegate 
</li>
            <li>
Partial classes: allows a class to be defined and worked on in two or more files</li>
          </ul>
          <p>
            <strong>ASP.NET</strong>
          </p>
          <ul>
            <li>
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. 
</li>
            <li>
Master pages: allows visual inheritance or a base class page 
</li>
            <li>
DataSource &amp; ObjectDataSource allow easier binding to data aware controls</li>
          </ul>
          <p>
            <strong>Visual Studio .NET 2005</strong>
          </p>
          <ul>
            <li>
Click-Once deployment of smart client 
</li>
            <li>
Editor: improved color coding and intellisense 
</li>
            <li>
Debugger will suggest potential problem areas 
</li>
            <li>
Warnings suggesting specific replacements for code that uses deprecated or obsolete
framework objects 
</li>
            <li>
Debugger allows data visualization: view a dataset in a grid while debugging 
</li>
            <li>
Conversion of previous VS.NET projects easy, automated, informative reports</li>
          </ul>
          <p>
            <strong>SQL Server 2005</strong>
          </p>
          <ul>
            <li>
PIVOT/UNPIVOT allows rows and column rotation 
</li>
            <li>
APPLY allows use of a UDF in a FROM clause to create a result set with calculated
columns 
</li>
            <li>
TRY/CATCH allows more granular exception handling 
</li>
            <li>
CTE (Common Table Expressions) allow the creation of a recursive query to produce
a hierarchical resultset 
</li>
            <li>
CLR integration allows stored procedures to be written in C#</li>
          </ul>
        </div>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=500e56cd-e99d-4c25-a210-86b9c4e011f5" />
      </body>
      <title>Pick Up the Scissors and Run</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,500e56cd-e99d-4c25-a210-86b9c4e011f5.aspx</guid>
      <link>http://www.tsjensen.com/blog/2005/11/03/Pick+Up+The+Scissors+And+Run.aspx</link>
      <pubDate>Thu, 03 Nov 2005 16:51:53 GMT</pubDate>
      <description>&lt;div class=entry-body&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;ADO.NET &lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Bulk updates: 1,000,000 row insert for 1.1: 30 minutes; for 2.0: 45 seconds 
&lt;li&gt;
Dataset binary serialization in remoting: faster DS over the wire (up to 6 times smaller) 
&lt;li&gt;
DataTable now supports XML read, write, schema, merge, load 
&lt;li&gt;
DataView.ToTable method allows creation of a new DataTable from a view&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;C# 2.0&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Generics: generic class later cast to a specific type. Collections are the best example:
a list of some type: List&amp;lt;someType&amp;gt; 
&lt;li&gt;
Anonymous methods: allows code to be passed as a parameter rather than requiring a
delegate 
&lt;li&gt;
Partial classes: allows a class to be defined and worked on in two or more files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;ASP.NET&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
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. 
&lt;li&gt;
Master pages: allows visual inheritance or a base class page 
&lt;li&gt;
DataSource &amp;amp; ObjectDataSource allow easier binding to data aware controls&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Visual Studio .NET 2005&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Click-Once deployment of smart client 
&lt;li&gt;
Editor: improved color coding and intellisense 
&lt;li&gt;
Debugger will suggest potential problem areas 
&lt;li&gt;
Warnings suggesting specific replacements for code that uses deprecated or obsolete
framework objects 
&lt;li&gt;
Debugger allows data visualization: view a dataset in a grid while debugging 
&lt;li&gt;
Conversion of previous VS.NET projects easy, automated, informative reports&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;SQL Server 2005&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
PIVOT/UNPIVOT allows rows and column rotation 
&lt;li&gt;
APPLY allows use of a UDF in a FROM clause to create a result set with calculated
columns 
&lt;li&gt;
TRY/CATCH allows more granular exception handling 
&lt;li&gt;
CTE (Common Table Expressions) allow the creation of a recursive query to produce
a hierarchical resultset 
&lt;li&gt;
CLR integration allows stored procedures to be written in C#&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=500e56cd-e99d-4c25-a210-86b9c4e011f5" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,500e56cd-e99d-4c25-a210-86b9c4e011f5.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=e8289bd1-32dd-4746-b4e6-184a1aeb117e</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,e8289bd1-32dd-4746-b4e6-184a1aeb117e.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,e8289bd1-32dd-4746-b4e6-184a1aeb117e.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e8289bd1-32dd-4746-b4e6-184a1aeb117e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
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 &lt;% %&gt; tag markers. And just for the record, ASP 2.0 was a long time ago. 
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
And no, I'm not going to give you a link to the story. Like the byline suggested,
the story should go bye bye.
</p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=e8289bd1-32dd-4746-b4e6-184a1aeb117e" />
      </body>
      <title>ASP.NET is NOT ASP</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,e8289bd1-32dd-4746-b4e6-184a1aeb117e.aspx</guid>
      <link>http://www.tsjensen.com/blog/2005/10/27/ASPNET+Is+NOT+ASP.aspx</link>
      <pubDate>Thu, 27 Oct 2005 15:50:10 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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 &amp;lt;% %&amp;gt; tag markers. And just for the record, ASP 2.0 was a long time ago. 
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
And no, I'm not going to give you a link to the story. Like the byline suggested,
the story should go bye bye.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=e8289bd1-32dd-4746-b4e6-184a1aeb117e" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,e8289bd1-32dd-4746-b4e6-184a1aeb117e.aspx</comments>
      <category>Code</category>
    </item>
    <item>
      <trackback:ping>http://www.tsjensen.com/blog/Trackback.aspx?guid=f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6</trackback:ping>
      <pingback:server>http://www.tsjensen.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.tsjensen.com/blog/PermaLink,guid,f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6.aspx</pingback:target>
      <dc:creator>Tyler Jensen</dc:creator>
      <wfw:comment>http://www.tsjensen.com/blog/CommentView,guid,f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6.aspx</wfw:comment>
      <wfw:commentRss>http://www.tsjensen.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
"...there may have been an inaccurate reference on our website when you registered..."
</p>
        <p>
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.
</p>
        <p>
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 <a href="https://partner.microsoft.com/empower">Empower</a>.
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 <a href="https://partner.microsoft.com/empower">Microsoft
Empower for ISVs program</a>.
</p>
        <p>
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.
</p>
        <p>
ONLY $375
</p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
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.<br /></p>
        <img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6" />
      </body>
      <title>Absent, Still Here - Pro Now Standard</title>
      <guid isPermaLink="false">http://www.tsjensen.com/blog/PermaLink,guid,f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6.aspx</guid>
      <link>http://www.tsjensen.com/blog/2005/10/22/Absent+Still+Here+Pro+Now+Standard.aspx</link>
      <pubDate>Sat, 22 Oct 2005 15:44:17 GMT</pubDate>
      <description>&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
"...there may have been an inaccurate reference on our website when you registered..."
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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 &lt;a href="https://partner.microsoft.com/empower"&gt;Empower&lt;/a&gt;.
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 &lt;a href="https://partner.microsoft.com/empower"&gt;Microsoft
Empower for ISVs program&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
ONLY $375
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;p&gt;
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.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.tsjensen.com/blog/aggbug.ashx?id=f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6" /&gt;</description>
      <comments>http://www.tsjensen.com/blog/CommentView,guid,f0ae5b3c-dd8a-453a-9fc8-6c3c42f652b6.aspx</comments>
      <category>Code</category>
    </item>
  </channel>
</rss>