<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TheCodeMonk</title>
	<atom:link href="http://thecodemonk.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thecodemonk.com</link>
	<description>Random Thoughts of a Software Development Professional</description>
	<lastBuildDate>Tue, 08 Dec 2009 23:15:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Wrap your ASP.Net session state into a more meaningful object.</title>
		<link>http://thecodemonk.com/2009/12/08/wrap-your-asp-net-session-state-into-a-more-meaningful-object/</link>
		<comments>http://thecodemonk.com/2009/12/08/wrap-your-asp-net-session-state-into-a-more-meaningful-object/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 23:15:25 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[.Net Code]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=51</guid>
		<description><![CDATA[I&#8217;ve tried to eliminate as much session state as possible as I know that it can cause some issues, especially in a server farm environment. However, there are quite a few times that I just need to have it, and I really doubt this small application is going to be hosted in a farm environment. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve tried to eliminate as much session state as possible as I know that it can cause some issues, especially in a server farm environment. However, there are quite a few times that I just need to have it, and I really doubt this small application is going to be hosted in a farm environment. This application is connected to a WCF service, and I really needed to eliminate round trips without using caching since some of this data is somewhat time sensitive, but it still needs to be available across a few page views. Instead of hitting the WCF service numerous times, I save the data in session state.</p>
<p>The way most people seem to have done session state (at least in just random searches on the internet and in sample code), you see this:</p>
<pre name="code" class="C#:nogutter">
  HttpContext.Current.Session["SomeData"] = myData;
</pre>
<p>There is nothing wrong with this. It works. Is it maintainable? Sort. Is it a potential problem? YES! What happens if you do this somewhere:</p>
<pre name="code" class="C#:nogutter">
  myData = HttpContext.Current.Session["SomData"];
</pre>
<p>Obviously you are going to get a null object back and possibly an error depending on other factors. You will probably find the problem during your automated tests (you do have automated tests right?) or at minimum find it during your own testing. The problem is, sometimes things like this will slip past if they are in infrequently used parts of a system that no one bothers to check for 3 or 4 versions that pass.</p>
<p>So in searching around I found various posts on how to wrap your session state into a more manageable object so that typos don&#8217;t creep up and bite you on the backside. Some of the examples went way over what I needed to do and some were way too simple to make sense for me.</p>
<p>So here is what I did (if I happened to have stolen your code, sorry, but it happens in software).</p>
<p>First I created my Current Session class to store everything and I made it static since Session itself is a static object.</p>
<pre name="code" class="C#:nogutter">
  public static class CurrentSession
  {
    private static HttpSessionState LiveSession
    {
      get { return HttpContext.Current.Session; }
    }
  }
</pre>
<p>This simple gives me a class that has access to the current session through a private variable called LiveSession.</p>
<p>Inside this class, I created another class for the CurrentUser since I needed to track the current logged in user (this user has data from the web service, so I&#8217;m not using asp.net authentication methods).</p>
<pre name="code" class="C#:nogutter">
    public static class CurrentUser
    {
      public static bool IsLoggedIn
      {
        get
        {
          bool? logIn = GetUserItem<bool?>(UserData.LoginState);
          if (!logIn.HasValue) logIn = false;
          return (logIn.Value);
        }
        set { SetUserItem<bool>(UserData.LoginState, value); }
      }

      public static FamilyData CurrentFamily
      {
        get { return (GetUserItem<FamilyData>(UserData.Family)); }
        set { SetUserItem<FamilyData>(UserData.FamilyInfo, value); }
      }

      private static T GetUserItem<T>(UserData key)
      {
        T data = (T)LiveSession[Enum.GetName(typeof(UserData), key)];
        return (data);
      }

      private static void SetUserItem<T>(UserData key, T data)
      {
        if (data == null)
          LiveSession.Remove(Enum.GetName(typeof(UserData), key));
        else
          LiveSession[Enum.GetName(typeof(UserData), key)] = data;
      }

      public enum UserData
      {
        Family,
        LoginState
      }
    }
</pre>
<p>Now, some explanation and why I did it the way I did. I could have just made my public variable have the getter and setter access the Session object directly. My typo chances would have been minimized by the fact that it&#8217;s only in two spots that I need to type it, but there is still a chance. So I created myself an enum that I can use to specify which sets of data I am saving or retrieving. I use the enum&#8217;s string value as the session object name, so all I have to do is make sure my enums never use the same name. In my RLC (Real Life Code) I use much longer enums, like CalendarFilterMonth or CalendarFilterDay, for example. In the above example, I use LoggedInUserFamily in place of just Family. While it may be long, intellisense always gets it right for me with just a few keystrokes.</p>
<p>The GetUserItem and SetUserItem simple save and retrieve from the LiveSession object. I use Type generics to tell the functions what type I am saving and retrieving for ease of use. My type casting never has to be done now. I tell it what I want and that&#8217;s what I will get in return.</p>
<p>The best part about this, is to add more, all I need to do is copy and paste a property and change a few of the options, maybe add an enum, and now I&#8217;m done. I don&#8217;t have to worry about typo&#8217;s and I can organize my session object however I want.</p>
<p>To use it, I just do this anywhere in my application:</p>
<pre name="code" class="C#:nogutter">
  if (!CurrentSession.CurrentUser.IsLoggedIn)
     RedirectToLogin();
  else
     if (CurrentSession.CurrentUser.CurrentFamily.NeedsProfileUpdate)
        RedirectToUpdate();
</pre>
<p>Since NeedsProfileUpdate is part of my FamilyData class, I can access that directly!</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/12/08/wrap-your-asp-net-session-state-into-a-more-meaningful-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WCF in an ASP.Net Application</title>
		<link>http://thecodemonk.com/2009/05/22/wcf-in-an-aspnet-application/</link>
		<comments>http://thecodemonk.com/2009/05/22/wcf-in-an-aspnet-application/#comments</comments>
		<pubDate>Fri, 22 May 2009 21:50:36 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=46</guid>
		<description><![CDATA[I posted a question on Stackoverflow.com today because I am experiancing some issues in production with a web application that is using WCF. To make a long story short, see this post.
My solution was actually quite simple and easy for me to implement. I can&#8217;t post actual code here since it&#8217;s a production project and [...]]]></description>
			<content:encoded><![CDATA[<p>I posted a question on Stackoverflow.com today because I am experiancing some issues in production with a web application that is using WCF. To make a long story short, see this <a href="http://stackoverflow.com/questions/899674/using-wcf-in-an-asp-net-application-and-best-practices">post</a>.</p>
<p>My solution was actually quite simple and easy for me to implement. I can&#8217;t post actual code here since it&#8217;s a production project and I didn&#8217;t have time to write up a proof of concept. This is the short of it, however:</p>
<p>My ServiceClient object was already wrapped up in a another class where the client was created and disposed off properly. Each function call also had a prefunction and postfunction call. For example:</p>
<pre name="code" class="C#:nogutter">
public string GetData()
{
   Open();
   string ret = GetData();
   Close();
   return ret;
}
</pre>
<p>Open and Close do not actually open and close the service client. Some of my functions require back to back calls so I didn&#8217;t want to be closing and opening connections repeatedly. I put these functions in, however, so that I could insert code before and after data calls, just in case I needed it. They were both empty until today. I have about 50 function calls in this WCF service, so it was a good thing I put those function calls in ahead of time!</p>
<p>I added 2 member variables to my class. A busy bool variable and a last used datetime. In the open function I now set busy to true and in the close I reset it back to false and also update the last used time. I then created some member properties to get how long it&#8217;s been idle (since last used time), if it&#8217;s busy, and what the communication state is (in cause of fault, but I also have fault checking inserted into Open, but let&#8217;s not go there right now).</p>
<p>I then created a connection pool class that simply holds a generic list of these client classes. Initially on application start, this list is blank. I created a function to get the next free client. This simply goes through this generic list and checks the communication state (has to be opened) and if it&#8217;s busy. If it&#8217;s open and not busy, I just return that client, otherwise I create a new one, add it to the pool and then return it. I also added some functions to get the state of each client and idle time, etc. For cleanup purposes, I just added a timer that executes every minute and checks to see if the idle time is over 5 minutes. If it is, it disposes that client and removes it from the pool.</p>
<p>My application always calls one single function to get the data client, so inserting the ability to get it from the pool was trivial. I just changed that function to get the pool object out of the Application state and then called the get next free client function and returned that.</p>
<p>All in all, this took less than 20 minutes to build and test. I installed it on the client&#8217;s production server since it was just crawling and a crash would be better than it&#8217;s current state anyway. I&#8217;m happy to report that things are moving quite well now. I would even venture to say that it&#8217;s running faster now than it did when I had web services set up instead of WCF.</p>
<p>If anyone sees a problem with this set up, or has a better way to do it, or just wants to tell me I&#8217;m dumb, go for it. I&#8217;m completely new to WCF and I will always take helpful advice.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/05/22/wcf-in-an-aspnet-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First usage of WCF and specified fields.</title>
		<link>http://thecodemonk.com/2009/04/27/first-usage-of-wcf-and-specified-fields/</link>
		<comments>http://thecodemonk.com/2009/04/27/first-usage-of-wcf-and-specified-fields/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 19:33:52 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[.Net Code]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=37</guid>
		<description><![CDATA[I hadn&#8217;t done much in the past with WCF. We had built our web service with the classes .Net 2.0 form of web services and it worked well. Then one day I realized that we had no built in security other than SSL. Since we had added a lot more things to it that could [...]]]></description>
			<content:encoded><![CDATA[<p>I hadn&#8217;t done much in the past with WCF. We had built our web service with the classes .Net 2.0 form of web services and it worked well. Then one day I realized that we had no built in security other than SSL. Since we had added a lot more things to it that could do some damage if a hacker found the service address, I decided to add some basic security. Needless to say, it&#8217;s not as easy as it looks with straight web services.</p>
<p>After doing some searching, I found a few examples of using WCF and implementing custom username authentication, which is exactly what I wanted to do. </p>
<p>Getting WCF set up and running was quite easy. Porting over our web service code just meant creating my ServiceContract and DataContracts and then recompiling. I also had to set my SQL to Linq datacontext serialization mode to Unidirectional. After coding up my custom username authentication and testing it, things were going along quite smoothly.</p>
<p>Everything I had experienced with Linq to SQL serialization still applied to WCF. Relationships had to have the parent set to internal access instead of public. I did also find that the relationships seemed to need a One-To-Many in order to work right. If it was a Many-To-One or a Many-To-Many, it wasn&#8217;t being sent from the WCF service to the client. Since I was in a hurry, I left that issue on the back burner and worked around it. If I five more into it, I will post about it here.</p>
<p>The one thing I had not counted on, was the fact that if you have any fields (properties) marked as being nullable, the Add Service wizard in Visual Studio 2008 will also add a boolean field called fieldSpecified. So if you have a nullable field for, say, PhoneNumber, you will have that and PhoneNumberSpecified. If you fill in the PhoneNumber field, but do not set PhoneNumberSpecified to true, the field will not be sent to the WCF service.</p>
<p>From my little bit of research, if that Specified field is set to false, the property will not be included in the XML document sent to the WCF service. If it is set to true, it will send it whether it&#8217;s null or not. </p>
<p>Since some of our classes have quite a few fields and we have quite a bit of code to set those fields, I did not want to go through and set every one of these stupid properties to true when I set a field. I&#8217;m actually quite surprised that we even need to do this.</p>
<p>In searching for an answer, I found the long way around of writing a program to parse your service.cs (or .vb) file and inserting this code:</p>
<pre name="code" class="C#:nogutter">
  [System.Xml.Serialization.XmlElementAttribute(Order = 0)]
  public string PhoneNumber
  {
    get
    {
      return this.PhoneNumber;
    }
    set
    {
      this.PhoneNumber = value;
      PhoneNumberSpecified = true; // Line Added
    }
  }
</pre>
<p>So, we have to add one line to each property that has a corresponding Specified field. Now I know why people wrote a utility to do this. That file will get overwritten each time you update your service reference.</p>
<p>I wasn&#8217;t too pleased I had to do this so I tried to find a better way. I finally settled on using the PropertyChanged events and some reflection to go and fill that field in.</p>
<p>To make things simple, my Linq to SQL classes all have a base class called BaseBusiness where I do validation and hold some original values so we can use the disconnected nature of the web with Linq to SQL entities. Since I did this, I can only derive my classes on the client side from the same base class. So I created my BaseBusiness class and included my PropertyChange event in there like this:</p>
<pre name="code" class="C#:nogutter">
  public partial class BaseBusiness
  {
    public void InternalPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
      if (!e.PropertyName.Contains("Specified"))
      {
        string prop = String.Format("{0}Specified", e.PropertyName);
        PropertyInfo target = this.GetType().GetProperty(prop);
        if (target != null)
        {
          PropertyInfo src = this.GetType().GetProperty(e.PropertyName);
          bool currentValue = (bool)target.GetValue(sender, null);
          bool hasValue = (src.GetValue(sender, null) == null ? false : true);
          if (currentValue != hasValue)
            target.SetValue(sender, hasValue, null);
        }
      }
    }
  }
</pre>
<p>This is pretty straight forward so far. I check to see if the field is already set to what it should be so I don&#8217;t make any unneccesary calls. Note that I use sender as the object I am using the GetValue and SetValue on. This is because the event is in a base class and wouldn&#8217;t be the right object to use for reflection since the properties would be one level up (or down, depending of where you stand).</p>
<p>Now the only step left is to write it up in the data classes. Which is nothing more than this:</p>
<pre name="code" class="C#:nogutter">
public partial class MyDataClass : BaseBusiness
{
  public MyDataClass()
  {
    this.PropertyChanged += InternalPropertyChanged;
  }

  ~MyDataClass()
  {
    this.PropertyChanged -= InternalPropertyChanged;
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/04/27/first-usage-of-wcf-and-specified-fields/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why excellent vendor support matters.</title>
		<link>http://thecodemonk.com/2009/03/20/why-excellent-vendor-support-matters/</link>
		<comments>http://thecodemonk.com/2009/03/20/why-excellent-vendor-support-matters/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 17:29:20 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Windows Development]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=31</guid>
		<description><![CDATA[We have been having some strange problems on production installs. Things like screens clearing when they shouldn&#8217;t, applications slowing down when they didn&#8217;t before, and people&#8217;s computers running slower and slower until they close our application. When I was finally informed of this, I knew it had to be memory leaks.
So I fired up the [...]]]></description>
			<content:encoded><![CDATA[<p>We have been having some strange problems on production installs. Things like screens clearing when they shouldn&#8217;t, applications slowing down when they didn&#8217;t before, and people&#8217;s computers running slower and slower until they close our application. When I was finally informed of this, I knew it had to be memory leaks.</p>
<p>So I fired up the excellent <a href="http://memprofiler.com">MemProfiler</a>, I started digging into the issues. Aside from some of the other stupidity I was doing, I found a problem with a vendor&#8217;s component. We use <a href="http://devexpress.com/">Developers Express</a> controls for EVERYTHING and we love them, not just the controls, but the company. When I found this issue with XtraReports not being GC&#8217;d after a dispose, I immediately created a small sample for them and submitted a ticket.</p>
<p>Less than 2 days later, they already have it fixed and ready to rock in the latest version. Not only am I impressed, but I am put at ease knowing that if a problem comes up, they are there to not only fix it, but fix it quickly and get it out to people.</p>
<p>This also happened a few months ago when their ASPxThemeDeployer wouldn&#8217;t work on my x64 Vista machine. I peeked at their code and saw why. Reported it and the VERY NEXT DAY they had a solution to the problem and pushed out an update.</p>
<p>I don&#8217;t have to worry. I know I am taken care of.</p>
<p>Thanks guys!</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/03/20/why-excellent-vendor-support-matters/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How VB.Net can screw up a newbie without them knowing it.</title>
		<link>http://thecodemonk.com/2009/03/17/how-vbnet-can-screw-up-a-newbie-without-them-knowing-it/</link>
		<comments>http://thecodemonk.com/2009/03/17/how-vbnet-can-screw-up-a-newbie-without-them-knowing-it/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 17:20:10 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=28</guid>
		<description><![CDATA[Let me preface this by saying I have no hate for VB.Net. When used properly, it is just as good as C#. However, VB as a whole has gotten a bad rep because generally the people that flock to it are the ones with no formal programming experience. Thus, they don&#8217;t really always know what [...]]]></description>
			<content:encoded><![CDATA[<p>Let me preface this by saying I have no hate for VB.Net. When used properly, it is just as good as C#. However, VB as a whole has gotten a bad rep because generally the people that flock to it are the ones with no formal programming experience. Thus, they don&#8217;t really always know what they are doing. I&#8217;ve seen it a lot. I will also admit that I have done a lot of these horrendous things that I should have never done. In fact, this post is about something I did that turned out way bad when we fast forward a few years later (yes, it took that long for me to find this problem.)</p>
<p>Here is the problem and the solution I came up with over two years ago. We have a very large MDI application that has a lot of different forms. We didn&#8217;t want users opening up multiple copies of those forms, plus we wanted a neat way to bring certain forms to the foreground if they were already open.</p>
<p>My simple and what I thought was ingenious solution was to create a few functions that just check to see if the form is open&#8230; Something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;">  <span style="color: #000080;">Public</span> <span style="color: #000080;">Function</span> IsFormOpen(<span style="color: #000080;">ByVal</span> oFormName <span style="color: #000080;">As</span> Form) <span style="color: #000080;">As</span> <span style="color: #000080;">Boolean</span>
    <span style="color: #000080;">Dim</span> bAlreadyShown <span style="color: #000080;">As</span> <span style="color: #000080;">Boolean</span> = <span style="color: #000080;">False</span>
    <span style="color: #000080;">Dim</span> obj <span style="color: #000080;">As</span> Form
    <span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> obj <span style="color: #000080;">In</span> Me.MdiChildren
      <span style="color: #000080;">If</span> obj.Name = oFormName.Name <span style="color: #000080;">Then</span>
        bAlreadyShown = <span style="color: #000080;">True</span>
      <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
    <span style="color: #000080;">Next</span>
    Return bAlreadyShown
  <span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>When I wrote that and it worked, it made sense to me that it would just pass in the type and I could get the name of the type and it would match and the world would be happy&#8230; </p>
<p>Now fast forward 2 years and we are getting some complaints of the application/whole computer being slow after running for a while. This smelled of memory leaks (which we have had lots of in the past). So I started doing my memory leak testing and now I am seeing all of our forms still being held open when they should be closed!</p>
<p>So turning off just my code debugging and putting a breakpoint in InitializeComponent() told me a big huge story. A story of how VB &#8220;helps&#8221; a developer by just doing things for them without them knowing. It seems that before going into the IsFormOpen function call, VB creates an object of that form type and passes in that object. That object never gets destroyed, either. Dispose on that object only gets called when the application exits. Nice, huh? So every time we open a form, we actually are creating two and only opening one. One simple change fixed it:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;">  <span style="color: #000080;">Public</span> <span style="color: #000080;">Function</span> IsFormOpen(<span style="color: #000080;">ByVal</span> oFormName <span style="color: #000080;">As</span> System.<span style="color: #000080;">Type</span>) <span style="color: #000080;">As</span> <span style="color: #000080;">Boolean</span>
    <span style="color: #000080;">Dim</span> bAlreadyShown <span style="color: #000080;">As</span> <span style="color: #000080;">Boolean</span> = <span style="color: #000080;">False</span>
    <span style="color: #000080;">Dim</span> obj <span style="color: #000080;">As</span> Form
    <span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> obj <span style="color: #000080;">In</span> Me.MdiChildren
      <span style="color: #000080;">If</span> obj.Name = oFormName.Name <span style="color: #000080;">Then</span>
        bAlreadyShown = <span style="color: #000080;">True</span>
      <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
    <span style="color: #000080;">Next</span>
    Return bAlreadyShown
  <span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>Incidentally, C# wouldn&#8217;t allow the first function to happen. It won&#8217;t even compile in any way, shape, or form (at least in the way I was trying to use it). It tells me the obvious, I was trying to use a Type as a variable. VB &#8220;helps&#8221; you with that&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/03/17/how-vbnet-can-screw-up-a-newbie-without-them-knowing-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linq to SQL in web services</title>
		<link>http://thecodemonk.com/2009/03/02/linq-to-sql-in-web-services/</link>
		<comments>http://thecodemonk.com/2009/03/02/linq-to-sql-in-web-services/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 23:26:20 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[.Net Code]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[linq]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=23</guid>
		<description><![CDATA[Quite a while ago, I investigated the use of Linq to SQL in our one web service component that feeds a CMS that we package with out software. In my initial investigations, every time I would send an entity through the web service, I would get a circular reference error. This made sense since each [...]]]></description>
			<content:encoded><![CDATA[<p>Quite a while ago, I investigated the use of Linq to SQL in our one web service component that feeds a CMS that we package with out software. In my initial investigations, every time I would send an entity through the web service, I would get a circular reference error. This made sense since each relationship is bidirectional. If I have a family entity that has a relationship to a person entity, that person entity also has a reference to the family entity. This goes on infinitely. Those relationships are nice because you can grab one single person and then get data out of the family entity without having to do any joins or write a separate query. So what do you do? </p>
<p>There are a couple of options. </p>
<p>1. Make the data context serialization unidirectional. This will turn off all relationships. You will have to manually do your joins using Linq when the data reaches the other side of the transaction.</p>
<p>2. Change the parent access modifier of the relationship to Friend (VB) or Internal (C#). This leaves the child relationships intact but removes the parent relationships. There would no longer be a family relationship in the person entity. </p>
<p>I prefer option 2 simply because then I don&#8217;t have to rejoin my data every time I fetch it. I don&#8217;t need those child to parent relationships because I can build around it by making my web service functions return the family instead of just returning a person, even if I just request the person.</p>
<p>The next issue that I ran into was the updating existing records. Since adding new records takes a detached object and just inserts it as new, that isn&#8217;t an issue. The problem comes in the concurrency tracking that Linq to SQL uses. You either time stamp your record, or you allow it to check previous fields for concurrency. We don&#8217;t use the time stamp method. The way that most things work in the SQL world is that when you save, you either overwrite what is currently in the table, or you get an concurrency error that makes you input everything over again after getting a refresh from the database. This is not the way we like it. We like a merge scenario where I can make a couple changes to the record and someone else can make some other changes and we the save is made, both our changes make it to the database.</p>
<p>So, how do you fix this? It&#8217;s easy with Linq to SQL. It already has the merge saving built in, unlike ADO.Net. (The Entity Framework will do this as well if you set it up right.) Even though Linq to SQL already supports the saving, this won&#8217;t work in web services. The problem is that during serialization, the entity loses it&#8217;s data context. It&#8217;s the data context that actually tracks the changes in the record, not the entity itself. So once the data context loses it&#8217;s entity (gets detached), it has to be reattached in order to do the save. The problem with this is that the data context no longer knows what has changed in this entity, so it cannot do any concurrency validation. The key is to use the Attach method and fill in two of it&#8217;s parameters, one for current entity and one for the original entity. There are a couple ways you can do this, but I choose to add a base class where I could store the serialized entity (complete with children) and ship it back and forth.</p>
<p>No matter how you slice it, you are going to have the overhead of change tracking eating up bandwidth to and from the web service to the calling application. This can either be incredibly apparent by holding your original values in the session state and just passing it back to the web service, or you can serialize it in the entity object and just pull it out later. I use this method for simplicity. I actually just make a business class (actually, I already had one because all my validation is stored there in a generic, fun sort of way that allows it to just interact with IDataError) and in that business class, I just add a object holder and some functions to set the original value.</p>
<p>Here is a small sample of the base business class:</p>
<pre name="code" class="vb.net:nogutter">
Imports System.Xml.Serialization

Public Class BaseBusiness

  Private original As Object

  Public Sub SetOriginalValue(ByVal _OriginalValue As Object, ByVal originalType As System.Type)
    Dim sb As New StringBuilder()
    Using strw As New System.IO.StringWriter(sb)
      Dim SXO As New XmlSerializer(originalType)
      SXO.Serialize(strw, _OriginalValue)
      original = sb.ToString()
    End Using
  End Sub

  Public Function HasOriginalValue() As Boolean
    Dim bOriginal As Boolean = False
    If original IsNot Nothing Then
      bOriginal = True
    End If
    Return bOriginal
  End Function

  Public Function GetOriginalValue(ByVal originalType As System.Type) As Object
    If HasOriginalValue() Then
      Dim sXml As String = CStr(original)
      Dim fam As Object
      Using strr As New System.IO.StringReader(sXml)
        Dim SXO As New XmlSerializer(originalType)
        fam = SXO.Deserialize(strr)
        Return (fam)
      End Using
    Else
      Return (Nothing)
    End If
  End Function
End Class
</pre>
<p>Notice the use of System.Type, this allows me to pass in any data type and serialize it on the fly without having to have special code in my entity class. This makes it appropriate for any class I need to track changes in, even in the entity framework if I so desire.</p>
<p>Here is the top level entity class where I use it:</p>
<pre name="code" class="vb.net:nogutter">
Imports System.Xml.Serialization

Partial Class Family
  Inherits BaseBusiness

  Private Sub OnLoaded()
    OriginalValue = Me
  End Sub

  Public Property OriginalValue() As Family
    Get
      Return CType((Me.GetOriginalValue(GetType(Family))), Family)
    End Get
    Set(ByVal value As Family)
      Me.SetOriginalValue(value, GetType(Family))
    End Set
  End Property
End Class
</pre>
<p>That is the only code that will need to be in the entity class in order for it to work. The best part of this is when the data gets shipped back and forth, it&#8217;s always accessible as the original entity, not a serialized XML string.</p>
<p>This was just a quick test I did when investigating this stuff today. Eventually, I am going to try to minimize the code in both classes some more and see if I can even strip out the XML Serialization to string and just store it as binary data. </p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/03/02/linq-to-sql-in-web-services/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ASP.Net MVC versus Web Forms</title>
		<link>http://thecodemonk.com/2009/02/05/aspnet-mvc-versus-web-forms/</link>
		<comments>http://thecodemonk.com/2009/02/05/aspnet-mvc-versus-web-forms/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 03:53:08 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/?p=20</guid>
		<description><![CDATA[ASP.Net MVC is an awesome concept, and works great. It just has a little way to go in the UI department.]]></description>
			<content:encoded><![CDATA[<p>We are going to be converting a fairly good sized project over to ASP.Net soon. The process of planning has already started. I have been investigating our options and trying to decide what would work best for us.</p>
<p>I checked out ASP.Net MVC first because that seems to be all the rage right now. I can definitely see why people are excited. I had a fully functioning site up and running in no time. It&#8217;s definitely a great framework and introduces a lot of very nice features. I love the testability it introduces into the whole equation, even the view.</p>
<p>What I don&#8217;t like, is the fact that it doesn&#8217;t support 3rd party controls. With the exception of Telerik and possibly Infragistics, others are SOL right now until the component vendors get their components up to speed. I know Jeff Handley had posted a few articles about extending the base controls, but I&#8217;m talking about some serious controls, like Dev Express&#8217;s grids and asp editors. I know there are options, but we will never ditch Dev Express. They have been too good to us. When I can e-mail the CTO with an off the wall management question and have him respond within 8 hours, and submit a message to a general e-mail with some questions about their plans and get a phone call from them within 8 hours, that&#8217;s not only a company that makes a great product, but a company that cares (shameless plug for you guys Julian and Mehul).</p>
<p>So I started to investigate other options. When searching for some silverlight info, one of my dudes discovered Visual WebGui. Visual WebGui was pretty slick. You drag and drop onto what looks like a Windows Form and where you drop it is where it renders when viewed through IE or Firefox. They also had a small tutorial on how to take a regular Windows forms application and quickly convert it to a full blown ASP.Net web application. This would have been awesome, except we don&#8217;t use Windows Forms controls for anything, not even our forms. Everything is from Dev Express, so it doesn&#8217;t convert so hotly. I did some more research and you can get those 3rd party controls to work, but it&#8217;s not the greatest or easiest to work with. Their quick solution would eventually turn into a code nightmare. So much for that.</p>
<p>Looks like it&#8217;s time to dig out the new routing engine in ASP.Net and start wiring up some of my own code. I really wanted to use MVC, but if the UI is going to suck, our users will absolutely hate us.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/02/05/aspnet-mvc-versus-web-forms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wix</title>
		<link>http://thecodemonk.com/2009/01/09/wix/</link>
		<comments>http://thecodemonk.com/2009/01/09/wix/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 22:02:05 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[.Net Code]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[Windows Deployment]]></category>
		<category><![CDATA[Wix]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[setup]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/2009/01/09/wix/</guid>
		<description><![CDATA[In finally get CruiseControl.Net set up to not only automate our build process, but notify us of any breaking changes on checkin, I discovered some issues in using the standard setup and deployment projects. Not wanting to spend a lot of time on it, I decided to look into Wix and see how it could [...]]]></description>
			<content:encoded><![CDATA[<p>In finally get CruiseControl.Net set up to not only automate our build process, but notify us of any breaking changes on checkin, I discovered some issues in using the standard setup and deployment projects. Not wanting to spend a lot of time on it, I decided to look into Wix and see how it could help me streamline things.</p>
<p>It turns out Wix is a whole lot more work. Instead of a simple point and click interface, I&#8217;m presented with hand editing the XML file. Boo.</p>
<p>There are a few decent open source projects to give me a GUI interface so I can get my point and click back, but they turned out to either be for Wix 2 or they had some serious bugs in them.</p>
<p>In the end I used Dark to script my MSI file. While this worked out ok, Wix 3 wouldn&#8217;t compile the script without me making some changes. I dug through the script it created and I started to wonder how I was going to automate this. The trick is really not to automate it. The trick is to set up your script once and then leave it alone. Modifications are only made when things change in your build. That&#8217;s fine, but what about setting it up for the first time? You have to create a GUID for each component (read, every file if you want the files updateable) that gets installed. This can be time consuming if you have quite a few ancilary files that need to be shipped with the release.</p>
<p>Well, I automated that part. I created myself a small console application that will take a folder and a output file name as arguments. The program will traverse this folder and create an include script. It treats every file, directory, and directory of files as individual components. </p>
<p>In case anyone wants to do this but doesn&#8217;t want to take the time to write all the code, here it is.</p>
<pre name="code" class="csharp:nogutter">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Reflection;

namespace CreateIncludeScript
{
    class Program
    {
        static int Main(string[] args)
        {
            if (args.Length < 2 || args.Length > 2)
            {
                return (-1);
            }
            string folder = args[0];
            string outputfile = args[1];
            XmlDocument xmlDoc = new XmlDocument();
            XmlNode root = xmlDoc.AppendChild(xmlDoc.CreateElement("Include", "http://schemas.microsoft.com/wix/2006/wi"));

            XmlNode dir = root.AppendChild(xmlDoc.CreateElement("Directory", "http://schemas.microsoft.com/wix/2006/wi"));
            SetAttr(xmlDoc, dir, "Id", "TARGETDIR");
            SetAttr(xmlDoc, dir, "Name", "SourceDir");

            ProcessDirectory(xmlDoc, dir, folder);

            XmlNode feat = root.AppendChild(xmlDoc.CreateElement("Feature", "http://schemas.microsoft.com/wix/2006/wi"));
            SetAttr(xmlDoc, feat, "Id", "DefaultFeature");
            SetAttr(xmlDoc, feat, "Level", "1");
            SetAttr(xmlDoc, feat, "ConfigurableDirectory", "TARGETDIR");
            ProcessFeatures(xmlDoc, feat, dir);

            xmlDoc.Save(outputfile);
            return (0);
        }

        static void SetAttr(XmlDocument doc, XmlNode node, string name, string value)
        {
            XmlAttribute attr = node.Attributes.Append(doc.CreateAttribute(name));
            attr.Value = value;
        }

        static void ProcessDirectory(XmlDocument xmlDoc, XmlNode target, string directory)
        {
            string[] files = Directory.GetFiles(directory);
            string[] dirs = Directory.GetDirectories(directory);

            foreach (string file in files)
            {
                FileInfo finfo = new FileInfo(file);

                XmlNode comp = target.AppendChild(xmlDoc.CreateElement("Component", "http://schemas.microsoft.com/wix/2006/wi"));
                string guid = System.Guid.NewGuid().ToString().ToUpper();
                string id = "C_" + guid.Replace("-", "");
                SetAttr(xmlDoc, comp, "Id", id);
                SetAttr(xmlDoc, comp, "Guid", "{" + guid + "}");

                XmlNode fnode = comp.AppendChild(xmlDoc.CreateElement("File", "http://schemas.microsoft.com/wix/2006/wi"));
                SetAttr(xmlDoc, fnode, "Id", "F_" + guid.Replace("-",""));
                SetAttr(xmlDoc, fnode, "Name", finfo.Name);
                SetAttr(xmlDoc, fnode, "KeyPath", "yes");
                SetAttr(xmlDoc, fnode, "DiskId", "1");
                SetAttr(xmlDoc, fnode, "Source", finfo.FullName);

                if (finfo.Extension.ToLower() == ".dll" || finfo.Extension.ToLower() == ".exe")
                {
                    if (IsDotNetAssembly(finfo.FullName))
                    {
                        SetAttr(xmlDoc, fnode, "Assembly", ".net");
                        SetAttr(xmlDoc, fnode, "AssemblyManifest", "F_" + guid.Replace("-", ""));
                        SetAttr(xmlDoc, fnode, "AssemblyApplication", "F_" + guid.Replace("-", ""));
                    }
                }
            }

            foreach (string dir in dirs)
            {
                DirectoryInfo dinfo = new DirectoryInfo(dir);

                XmlNode dnode = target.AppendChild(xmlDoc.CreateElement("Directory", "http://schemas.microsoft.com/wix/2006/wi"));
                SetAttr(xmlDoc, dnode, "Id", dinfo.Name.Replace("-",""));
                SetAttr(xmlDoc, dnode, "Name", dinfo.Name);

                ProcessDirectory(xmlDoc, dnode, dinfo.FullName);
            }
        }

        static void ProcessFeatures(XmlDocument xmlDoc, XmlNode target, XmlNode root)
        {
            XmlNamespaceManager xmlmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            xmlmgr.AddNamespace("wi", "http://schemas.microsoft.com/wix/2006/wi");
            XmlNodeList comps = root.SelectNodes("descendant::wi:Component", xmlmgr);

            foreach (XmlNode node in comps)
            {
                XmlNode compfeat = target.AppendChild(xmlDoc.CreateElement("ComponentRef", "http://schemas.microsoft.com/wix/2006/wi"));
                SetAttr(xmlDoc, compfeat, "Id", node.Attributes.GetNamedItem("Id").Value);
                XmlNode file = node.SelectSingleNode("wi:File", xmlmgr);
                if (file.Attributes.GetNamedItem("Assembly") != null)
                {
                    SetAttr(xmlDoc, compfeat, "Primary", "yes");
                }
            }
        }

        static bool IsDotNetAssembly(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                try
                {
                    using (BinaryReader binReader = new BinaryReader(fs))
                    {
                        try
                        {
                            fs.Position = 0x3C; //PE Header start offset
                            uint headerOffset = binReader.ReadUInt32();
                                                         fs.Position = headerOffset + 0x18;
                            UInt16 magicNumber = binReader.ReadUInt16();
                                                         int dictionaryOffset;
                            switch (magicNumber)
                            {
                                case 0x010B: dictionaryOffset = 0x60; break;
                                case 0x020B: dictionaryOffset = 0x70; break;
                                default:
                                    throw new Exception("Invalid Image Format");
                            }

                            //position to RVA 15
                            fs.Position = headerOffset + 0x18 + dictionaryOffset + 0x70;

                            //Read the value
                            uint rva15value = binReader.ReadUInt32();
                            return (rva15value != 0);
                        }
                        finally
                        {
                            binReader.Close();
                        }
                    }
                }
                finally
                {
                    fs.Close();
                }
            }
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2009/01/09/wix/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Make it easy for the IT department.</title>
		<link>http://thecodemonk.com/2008/06/23/make-it-easy-for-the-it-department/</link>
		<comments>http://thecodemonk.com/2008/06/23/make-it-easy-for-the-it-department/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 14:50:37 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[Windows Deployment]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/2008/06/23/make-it-easy-for-the-it-department/</guid>
		<description><![CDATA[For quite a while I have noticed that there seems to be this huge divide between IT departments and the software developers. I say IT meaning the hardware/software support department and the programmers that write software. In my organization, we are only software developers. Any hardware support is done by me because I have had [...]]]></description>
			<content:encoded><![CDATA[<p>For quite a while I have noticed that there seems to be this huge divide between IT departments and the software developers. I say IT meaning the hardware/software support department and the programmers that write software. In my organization, we are only software developers. Any hardware support is done by me because I have had the most experience with it. Everyone else handles their own software issues. If they have an issue with Word or with their virus scanner of choice, they have to fix it themselves or ask questions to find out who knows what to do. Whenever I have had to call someone in IT at our customer&#8217;s location, we constantly are met with resistance and multitudes of questions that point to a certain mistrust of software developers. They almost treat us like we are Microsoft and are out to install a patch that will bring their entire system down for two days.</p>
<p>I start to gain a little insight on why it&#8217;s like this the other day. When we install our server components, which is solely SQL Server 2005 Express with a database including stored procedures and triggers, we have an <a href="http://thecodemonk.com/2007/10/25/windows-installer-sql-server-installation-issues-and-a-solution/">installation package</a> where you just have to click on setup.exe and let it do its thing. When I called the main contact at the IT department, I heard the hesitancy in his voice. I assured him he could do the installation if he preferred not giving me remote access to the server, but he insisted that I do it for him. No problem. Since we are customer focused, we always try to do the client and server installs of our software, anyway. I downloaded the files I needed and clicked on the setup program and just sat there while it went through the entire process. We chit-chatted about servers and Microsoft and had a few laughs over the new security requirements. He then described multiple instances where servers were down for a day or two because of patches that didn&#8217;t apply right and how he has had to call Microsoft dozens of times to get hotfixes or special patches because the combination of hardware and software they use is not normal. I usually do not get concerned when I hear this because we don&#8217;t usually care what they use, as long as Exchange Server is not on the same server as SQL Server.</p>
<p>After 15 minutes and clicking next a few times, our install was done. He said, &#8220;Ok, so what do we do now?&#8221; My response was simple, &#8220;Nothing. It&#8217;s all ready.&#8221; He was disbelieving and ran the client software and tried a few things to check. The next 10 minutes was eye opening. He described how this was the best install he has had to watch in a long time and was very pleased that we were so IT friendly. He described a situation that made me, as a software developer, cringe. They had purchased a brand new accounting system that cost their organization almost a hundred thousand dollars (US funds) and the installation took about 3 days. It took 3 days because they gave him the CDs and said to install it, but never gave him any instructions on how. Being used to installing software, he put in the CD marked #1 and ran the setup. It half way installed and then gave a half dozen error messages that consisted of things like &#8220;Error Occurs&#8221; and &#8220;Cannot Continue.&#8221; He tried called technical support and all he got was voice mails. He left messages but never received any phone calls in return.</p>
<p>He spent the next 3 days trying to solve the all problems himself, but with no documentation on requirements or procedures. When technical support finally called him back, the solution was to install the third CD first and then try the first CD. Why would you install a CD marked #3 before the CD marked #1? He told me that now he is highly concerned that they made the right choice because it&#8217;s their accounting system and how can they trust the vendor&#8217;s technical support department if he can&#8217;t get an answer in less than 3 days? What if they need to do payroll and &#8220;error occurs&#8221; and technical support doesn&#8217;t return phone calls?</p>
<p>This is why there is animosity between IT and software developers. Make it easy for them. Give descriptive error messages and most certainly answer your phone if it rings! Even if you know it&#8217;s a stupid problem they should be able to solve just by reading the screen, at least that phone call will keep their confidence that you will be there where there is a problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2008/06/23/make-it-easy-for-the-it-department/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I </title>
		<link>http://thecodemonk.com/2008/06/03/i/</link>
		<comments>http://thecodemonk.com/2008/06/03/i/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 18:17:20 +0000</pubDate>
		<dc:creator>TheCodeMonk</dc:creator>
				<category><![CDATA[linq]]></category>

		<guid isPermaLink="false">http://thecodemonk.com/2008/06/03/i/</guid>
		<description><![CDATA[One of the latest technologies to hit .Net recently is Linq. Language Integrated Query allows you to perform a more SQL like syntax on object collections in code. It has been out for quite some time, but I just recently was able to use it in a project. It&#8217;s pretty cool stuff and has already [...]]]></description>
			<content:encoded><![CDATA[<p>One of the latest technologies to hit .Net recently is <a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx">Linq</a>. Language Integrated Query allows you to perform a more SQL like syntax on object collections in code. It has been out for quite some time, but I just recently was able to use it in a project. It&#8217;s pretty cool stuff and has already saved me a few lines of code. Places where loops would have been neccessary have easily been replaced with a simple where.</p>
<p>One of the concerns most developers had, especially when working with Linq to SQL data classes, was the relative speed at retrieving data from the SQL server. They were pretty right about that. It&#8217;s slow. Much slower than even using datasets with table adapters. However, using <a href="http://www.jdconley.com/blog/archive/2007/11/28/linq-to-sql-surprise-performance-hit.aspx">compiled queries</a> can help.</p>
<p>One thing some people never took into consideration was the relative ease that Developer&#8217;s Express users can now use server mode without having to use the proprietary XPO classes. Their XtraGrid&#8217;s now support ServerMode which will page SQL queries in windows forms applications. One issue we had were slow VPN clients trying to use a windows form application installed locally and connecting to a remote SQL Server. Until recently we have had to tell users to use terminal services instead. Some forms have to show a relatively large amount of data in a single grid (finding customers, paging through certain data, etc). Over a VPN connection it was just painfully slow. Now combining <a href="http://www.devexpress.com/Products/NET/LinqEnabledGrids.xml">XtraGrid&#8217;s and the Linq Server Mode</a>, everything works as expected over a slow (1.5 MB DSL even) VPN connection.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodemonk.com/2008/06/03/i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
