<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4498520272665916853</id><updated>2012-03-19T10:23:53.775-07:00</updated><category term='wcf'/><category term='repositories'/><category term='cryptography'/><category term='fluent nhibernate'/><category term='javascript'/><category term='cookies'/><category term='trading'/><category term='development'/><category term='culture'/><category term='localization'/><category term='deployment'/><category term='visualsvn'/><category term='streams'/><category term='tradingblox'/><category term='syntax'/><category term='general'/><category term='mapreduce'/><category term='batch'/><category term='t-sql'/><category term='mvc'/><category term='c#'/><category term='jquery'/><category term='blogger'/><category term='sql'/><category term='python'/><category term='builds'/><category term='financial engineering'/><category term='spark'/><category term='coding'/><category term='asp.net'/><category term='tdd'/><category term='source control'/><category term='checkout'/><category term='helper methods'/><category term='services'/><category term='code'/><category term='testing'/><category term='plugins'/><category term='new initial'/><category term='scripts'/><category term='rant'/><category term='structuremap'/><category term='svn'/><title type='text'>Encoding Kockerbeck</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-4219512800543318028</id><published>2012-02-17T23:37:00.000-08:00</published><updated>2012-02-18T01:04:38.372-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='wcf'/><title type='text'>Applying WebInvoke without an Attribute</title><content type='html'>Haven't posted in a long time but thought I'd post this bit of WCF extensibility I was working on at home.  There is nothing on the Internet about how to do this &amp; I felt I should figure something out.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;Scenario:&lt;/u&gt; You have legacy WCF services that you want to switch to a WebHttpBinding w/ JSON but don't want to update 1,337 service contracts to include a WebInvoke attribute, UriTemplates and Request/Response Body Types&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In this scenario I'll be assuming use of IIS and Windows Process Activation Services to host your service.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webinvokeattribute.aspx"&gt;WebInvokeAttribute&lt;/a&gt; implements IOperationBehavior.  So what we need to do is somewhere in the WCF stack apply this operation behavior programmatically to our Endpoint's Contract.Operations.  Let's start from the bottom up &amp; take a look at an extension method that does this.&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Automatically applies the Web Invoke behavior to all operations in the collection&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;/// &amp;lt;param name="operations"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;public static void ApplyWebInvoke(this System.ServiceModel.Description.OperationDescriptionCollection operations)&lt;br /&gt;{&lt;br /&gt;    foreach (var operation in operations)&lt;br /&gt;    {&lt;br /&gt;        var webInvoke = new System.ServiceModel.Web.WebInvokeAttribute&lt;br /&gt;        {&lt;br /&gt;            BodyStyle = System.ServiceModel.Web.WebMessageBodyStyle.Wrapped,&lt;br /&gt;            Method = "POST",&lt;br /&gt;            RequestFormat = System.ServiceModel.Web.WebMessageFormat.Json,&lt;br /&gt;            ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json,&lt;br /&gt;            UriTemplate = operation.Name&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        operation.Behaviors.Add(webInvoke);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the above extension method I'm forcing everything to be a POST, everything to use JSON and keeping the UriTemplates simply as the Operation name.  Now where do we call this method?  Personally, I'm a fan of having custom ServiceHosts + ServiceHostFactories rather than BehaviorExtensions.  Chances are it's OK for me to touch the code &amp; hosting portion of the application that I don't need to rely solely on configuration to extend WCF.  If I have to extend a service that I don't have access to the ServiceHost -- behavior extensions are the only way.  But given the choice -- custom ServiceHostFactory every time.  The biggest reason is that I find other developers can follow the stack easier.  It's less confusing.  "Oh this SVC file has a custom factory?  Oh this custom factory applies this behavior! "&lt;br /&gt;&lt;br /&gt;Now take a look at the Factory and the custom Service Host:&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;public class WebInvokeServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory&lt;br /&gt;{&lt;br /&gt;    protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)&lt;br /&gt;    {&lt;br /&gt;        return new WebInvokeServiceHost(serviceType, baseAddresses).ApplyWebInvoke();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class WebInvokeServiceHost : System.ServiceModel.Web.WebServiceHost&lt;br /&gt;{&lt;br /&gt;    public WebInvokeServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }&lt;br /&gt;        &lt;br /&gt;    internal WebInvokeServiceHost ApplyWebInvoke()&lt;br /&gt;    {&lt;br /&gt;        foreach(var endpoint in Description.Endpoints)&lt;br /&gt;        {&lt;br /&gt;            endpoint.Contract.Operations.ApplyWebInvoke();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I'm applying the WebInvoke behavior after the ServiceHost has been instantiated.  Now just update the .svc file to use the new Factory:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;%@ ServiceHost Service="MySite.Services.TestService" Factory="MySite.ServiceModel.WebInvokeServiceHostFactory" %&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;As for the client...&lt;/strong&gt; &lt;br /&gt;Given our scenario of working with a legacy application, I'll start by assuming we aren't auto-generating Service References.  So we just need to apply the same IOperationBehavior to the &lt;strong&gt;Client Endpoint's&lt;/strong&gt; Contract.Operations just like the Service.  Below is a sample client base.&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;public class SampleClientBase : ClientBase&amp;lt;ITestService&amp;gt;, ITestService&lt;br /&gt;{&lt;br /&gt;    public SampleClientBase(string config) : base(config) { }&lt;br /&gt;&lt;br /&gt;    public SampleClientBase() : this("TestService")&lt;br /&gt;    {&lt;br /&gt;        ChannelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());&lt;br /&gt;&lt;br /&gt;        ChannelFactory.Endpoint.Contract.Operations.ApplyWebInvoke();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public SomeObject BasicTest(SomeObject someObject)&lt;br /&gt;    {&lt;br /&gt;        return Channel.BasicTest(someObject);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's all there is to it!  Hopefully now you see why that loop is an extension method and just how easy it really is to switch over to WebHttp from NetTcp without having to update your contracts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-4219512800543318028?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/4219512800543318028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=4219512800543318028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/4219512800543318028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/4219512800543318028'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2012/02/applying-webinvoke-without-attribute.html' title='Applying WebInvoke without an Attribute'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-3455448715885831577</id><published>2010-09-27T09:47:00.000-07:00</published><updated>2010-09-27T16:41:40.337-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mapreduce'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>MapReduce in C# using Task Parallel Library</title><content type='html'>Back in August I starting playing with a C# implementation of Google's &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt; algorithm.  The implementation was based on something &lt;a href="http://www.stephan-brenner.com/?p=59"&gt;Stephan Brenner&lt;/a&gt; did, although I completely refactored it.&lt;br /&gt;&lt;br /&gt;Today I added a little bit of logic to split up the actual execution of Map &amp; Reduce in this implementation using the &lt;a href="http://msdn.microsoft.com/en-us/library/dd460717.aspx"&gt;Task Parallel Library&lt;/a&gt; in .NET 4.0.  Check out the source code for &lt;a href="http://github.com/xeb/mapreduce-csharp"&gt;MapReduce in C#&lt;/a&gt; on GitHub.  Below is an excerpt from the Tests on how to implement the library.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Counting Words in Files&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;public static List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt; Map(FileInfo document, string text)&lt;br /&gt;{&lt;br /&gt;    var items = text.Split('\n', ' ', '.', ',','\r');&lt;br /&gt;    return items.Select(item =&amp;gt; new KeyValuePair&amp;lt;string, int&amp;gt;(item, 1)).ToList();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public static List&amp;lt;int&amp;gt; Reduce(string word, List&amp;lt;int&amp;gt; wordCounts)&lt;br /&gt;{&lt;br /&gt;    if (wordCounts == null) return null;&lt;br /&gt;&lt;br /&gt;    var result = new List&amp;lt;int&amp;gt; { 0 };&lt;br /&gt;            &lt;br /&gt;    foreach (var value in wordCounts)&lt;br /&gt;    {&lt;br /&gt;        result[0] += value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void Main()&lt;br /&gt;{&lt;br /&gt;    var fileSearchData = new Dictionary&amp;lt;FileInfo, string&amp;gt;();&lt;br /&gt;    di.GetFiles().ToList().ForEach(f =&amp;gt; fileSearchData.Add(f, File.ReadAllText(f.FullName)));&lt;br /&gt;&lt;br /&gt;    var output = MapReduce.Execute(Map, Reduce, fileSearchData);&lt;br /&gt;&lt;br /&gt;    Console.WriteLine(output["needle"][0]);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let me know if you have any questions or want to share any implementation concerns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-3455448715885831577?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/3455448715885831577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=3455448715885831577' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3455448715885831577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3455448715885831577'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/09/mapreduce-in-c-using-task-parallel.html' title='MapReduce in C# using Task Parallel Library'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-5883608980403267450</id><published>2010-08-05T15:34:00.000-07:00</published><updated>2010-08-05T16:25:42.660-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='batch'/><category scheme='http://www.blogger.com/atom/ns#' term='visualsvn'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Require comment / message on all SVN commits for Visual SVN Server</title><content type='html'>(I've been posting a lot the last few days!)&lt;br /&gt;&lt;br /&gt;Something that drives me nuts is not having a comment or message when looking at SVN history.  It's impossible to know what went on.  Even a bad comment is better than no comment.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.petefreitag.com/item/244.cfm"&gt;SVN hooks&lt;/a&gt; are a great way to solve this.  If we make a pre-commit.bat file that checks the commit data for a comment, returns an error code of 1 if it wasn't found (with some text) or returns 0 if the comment is there.&lt;br /&gt;&lt;br /&gt;Check out the &lt;a href="http://www.anujgakhar.com/2008/02/14/how-to-force-comments-on-svn-commit/"&gt;pre-commit hook&lt;/a&gt; that I found online (thanks, Anuj Gakhar!) or check out the hook below.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;@echo off&lt;br /&gt;setlocal&lt;br /&gt;&lt;br /&gt;rem Subversion sends through the path to the repository and transaction id&lt;br /&gt;set REPOS=%1&lt;br /&gt;set TXN=%2&lt;br /&gt;&lt;br /&gt;rem check for an empty log message&lt;br /&gt;svnlook log %REPOS% -t %TXN% | findstr . &amp;gt; nul&lt;br /&gt;if %errorlevel% gtr 0 (goto err) else exit 0&lt;br /&gt;&lt;br /&gt;:err&lt;br /&gt;echo. 1&amp;gt;&amp;2&lt;br /&gt;echo A log message or comment is required to commit 1&amp;gt;&amp;2&lt;br /&gt;exit 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This works perfectly except for 1 downfall -- &lt;strong&gt;you have to distribute it in every freaking repository!&lt;/strong&gt;  Below is the windows batch solution I came up with to solve that problem.  Pretty straight forward, but thought I'd share for those less inclined to dig through archaic windows batch programming references.&lt;br /&gt;&lt;br /&gt;Just create a batch file of the following &amp; schedule it to run however often you want.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;@ECHO OFF&lt;br /&gt;:: ------ SVN Deploy Hooks ------&lt;br /&gt;:: ----- by Mark Kockerbeck  ----&lt;br /&gt;&lt;br /&gt;:: ------ Configuration ---------&lt;br /&gt;SET HookDirectory=C:\CommonHooks&lt;br /&gt;SET RepositoryDirectory=C:\Repositories&lt;br /&gt;:: ------ /Configuration --------&lt;br /&gt;&lt;br /&gt;pushd %HookDirectory%&lt;br /&gt;for /r %%i in (*) do (&lt;br /&gt; for /D %%j in (%RepositoryDirectory%\*) do (&lt;br /&gt;  echo Copying %%i to %%j\hooks\&lt;br /&gt;  copy %%i %%j\hooks\&lt;br /&gt; )&lt;br /&gt;)&lt;br /&gt;popd&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-5883608980403267450?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/5883608980403267450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=5883608980403267450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/5883608980403267450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/5883608980403267450'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/08/require-comment-message-on-all-svn.html' title='Require comment / message on all SVN commits for Visual SVN Server'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-5760915447072625129</id><published>2010-08-05T08:30:00.001-07:00</published><updated>2010-08-05T08:59:40.627-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Using ref Keyword with Reference Types in C#</title><content type='html'>One of our developers was using the &lt;a href="http://msdn.microsoft.com/en-us/library/14akc2c7(VS.71).aspx"&gt;ref&lt;/a&gt; keyword in a method that needed to replace the value of a property of the method's parameter.  &lt;br /&gt;&lt;br /&gt;In other words...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;  public class Person&lt;br /&gt;  {&lt;br /&gt;    public int ID { get; set; }&lt;br /&gt;    public string Name { get; set; }&lt;br /&gt;    public string Email { get; set; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static class ReferenceExample&lt;br /&gt;  {&lt;br /&gt;    public static void Main()&lt;br /&gt;    {&lt;br /&gt;      var person = new Person&lt;br /&gt;      {&lt;br /&gt;        Name = "Mark",&lt;br /&gt;        Email = "none@none.com",&lt;br /&gt;      };&lt;br /&gt;&lt;br /&gt;      Save(ref person);&lt;br /&gt;&lt;br /&gt;      Console.WriteLine(person.ID);&lt;br /&gt;      Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public static void Save(ref Person person)&lt;br /&gt;    {&lt;br /&gt;      person.ID = 1; // Pretend this saves to a database or something&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The thinking is correct.  Person needs to be passed by reference.  So why not use the ref keyword, right?  Well...Person is already a &lt;a href="http://msdn.microsoft.com/en-us/library/490f96s2.aspx"&gt;reference type&lt;/a&gt;.  So if we are just replacing properties, we don't need the &lt;strong&gt;ref&lt;/strong&gt; keyword.  Removing it changes nothing with our code.  The program still outputs 1.&lt;br /&gt;&lt;br /&gt;This begs the question -- &lt;strong&gt;Why even have the &lt;u&gt;ref&lt;/u&gt; keyword?&lt;/strong&gt;  The reason for it is to pass the &lt;strong&gt;&lt;i&gt;entire&lt;/i&gt;&lt;/strong&gt; parameter by reference.  This means that we can redefine a newly instantiated &lt;strong&gt;person&lt;/strong&gt;.  &lt;br /&gt;&lt;br /&gt;In other words...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;&lt;br /&gt;  public static class ReferenceExample&lt;br /&gt;  {&lt;br /&gt;    public static void Main()&lt;br /&gt;    {&lt;br /&gt;      var person = new Person&lt;br /&gt;      {&lt;br /&gt;        Name = "Mark",&lt;br /&gt;        Email = "none@none.com",&lt;br /&gt;      };&lt;br /&gt;&lt;br /&gt;      Save(ref person);&lt;br /&gt;&lt;br /&gt;      Console.WriteLine(person.ID);&lt;br /&gt;      Console.WriteLine(person.Name);&lt;br /&gt;      Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public static void Save(ref Person person)&lt;br /&gt;    {&lt;br /&gt;      person = new Person&lt;br /&gt;      {&lt;br /&gt;        Name = "Bill",&lt;br /&gt;        Email = "adventures@phonebooth.com",&lt;br /&gt;        ID = 2,&lt;br /&gt;      };&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Try running the above with and without the ref keyword.  If you use it with the ref keyword, the Person will be "Bill".  If you use it without, the person will be "Mark".&lt;br /&gt;&lt;br /&gt;Seems simple enough but I'm surprised how many developers don't (or didn't!) realize this difference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-5760915447072625129?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/5760915447072625129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=5760915447072625129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/5760915447072625129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/5760915447072625129'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/08/using-ref-keyword-with-reference-types.html' title='Using ref Keyword with Reference Types in C#'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-6838154321892070656</id><published>2010-08-04T13:13:00.000-07:00</published><updated>2010-08-04T20:08:03.135-07:00</updated><title type='text'>Get the name of a property as a string in C#</title><content type='html'>Another developer showed me something very useful with &lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;Expression Trees&lt;/a&gt; in C# (thanks, Pierre!  Full credit goes to you).  To show you the awesomeness of it all, let's start with a class called &lt;strong&gt;Person&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;public class Person&lt;br /&gt;{&lt;br /&gt;  public string Name { get; set; }&lt;br /&gt;  public string Email { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now let's say I have an instance of Person&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;var person = new Person&lt;br /&gt;{&lt;br /&gt;  Name = "mark kockerbeck",&lt;br /&gt;  Email = "noneofyourbusiness@face.com",&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Imagine creating a &lt;strong&gt;Dictionary&amp;lt;string,string&amp;gt;&lt;/strong&gt; of this particular Person's properties (e.g. "Name" and "Email") and the corresponding property values.&lt;br /&gt;&lt;br /&gt;We could easily do something like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;var dictionary = new Dictionary&amp;lt;string, string&amp;gt;&lt;br /&gt;{&lt;br /&gt;  { "Name", person.Name },&lt;br /&gt;  { "Email", person.Email },&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But there is unnecessary redundancy and repetition in this.  We have to say the property twice (and as a messy string no less!).&lt;br /&gt;&lt;br /&gt;Well, we could use reflection...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;var dictionary = new Dictionary&amp;lt;string, string&amp;gt;();&lt;br /&gt;typeof(Person).GetProperties().ToList().ForEach(p =&gt; dictionary.Add(p.Name, p.GetValue(person, null).ToString()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...but a lot of developers seem scared by Reflection &amp; especially a concise statement like the above.&lt;br /&gt;&lt;br /&gt;Below is a way to get the Property name &amp; value in one small statement while keeping a strong typed non-reflective code base.&lt;br /&gt;&lt;br /&gt;We just need to create a new Method...&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;public static void AddField&amp;lt;T&amp;gt;(Dictionary&amp;lt;string,T&amp;gt; dictionary, Expression&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt; expression)&lt;br /&gt;{&lt;br /&gt;  var name = ((MemberExpression)expression.Body).Member.Name;&lt;br /&gt;  dictionary.Add(name, expression.Compile()());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And now just call each property as a Func&amp;lt;T&amp;gt;...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;var dictionary = new Dictionary&amp;lt;string, string&amp;gt;();&lt;br /&gt;AddField(dictionary, () =&gt; person.Name);&lt;br /&gt;AddField(dictionary, () =&gt; person.Email);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Personally, I like the reflective way but I thought this was a very good use case for an Expression Tree&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-6838154321892070656?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/6838154321892070656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=6838154321892070656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6838154321892070656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6838154321892070656'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/08/get-name-of-property-as-string-in-c.html' title='Get the name of a property as a string in C#'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-9196853902433914938</id><published>2010-08-03T13:18:00.000-07:00</published><updated>2010-08-03T18:39:14.440-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='services'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='wcf'/><title type='text'>Service Cloud - dynamic calls to a cloud of WCF services</title><content type='html'>For awhile, myself and another developer have been trying to build a working prototype of an idea he proposed for a Service Cloud.  Essentially the Service Cloud is a collection of WCF services hosted on a number of servers and environments that can all communicate with one another via a common interface.  An "application" would then be built by orchestrating these services together.  &lt;br /&gt;&lt;br /&gt;Instead of the application adding service references for each of the services it needs -- it would simply send a request to the "Gateway" service and it would figure out the rest.  It would call the other services.&lt;br /&gt;&lt;br /&gt;Finally, when the execution is complete and your request has bounced all over the cloud, you get a response that many services have built together.&lt;br /&gt;&lt;br /&gt;I finally was able to create a working prototype (albeit completely contrived).  &lt;br /&gt;&lt;br /&gt;The Service Cloud prototype is available on GitHub, see: &lt;a href="http://github.com/xeb/ServiceCloud"&gt;http://github.com/xeb/ServiceCloud&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;Client&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;The client is simple.  The client adds a WCF Service Reference to the Gateway service and calls the Gateway's service Execute method.  The prototype requires that the full Endpoint Address of each service in the cloud be specified -- but this could easily be added to the Host (or better yet -- a service in the Host!).&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;// Start up the Cloud Gateway!&lt;br /&gt;var cloud = new CloudServiceClient();&lt;br /&gt;&lt;br /&gt;// Formulate our Request and get a Response from the Gateway&lt;br /&gt;var response = cloud.Execute(new Request&lt;br /&gt;{&lt;br /&gt; Argument = 15,&lt;br /&gt; Services = new[]&lt;br /&gt; {&lt;br /&gt;  new ServiceCall { Name = "Decrementer", &lt;br /&gt;   Address = "http://localhost:8731/Design_Time_Addresses/ServiceCloud.Services/Decrementer/" },&lt;br /&gt;  new ServiceCall { Name = "Incrementer", &lt;br /&gt;   Address = "http://localhost:8731/Design_Time_Addresses/ServiceCloud.Services/Incrementer/" },&lt;br /&gt;  new ServiceCall { Name = "Incrementer", &lt;br /&gt;   Address = "http://localhost:8731/Design_Time_Addresses/ServiceCloud.Services/Incrementer/" },&lt;br /&gt; },&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;cloud.Close();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now the Response we get back has a &lt;strong&gt;ReturnObject&lt;/strong&gt; property that will be the result of our 3 service calls.  Can you guess what the result will be? &lt;br /&gt;&lt;br /&gt;&lt;img src="http://axxess.gunthers.net/images/kockerbeck/Client-Result.png" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Pretty straight forward huh?  Check out the &lt;br /&gt; &lt;a href="http://github.com/xeb/ServiceCloud/tree/master/Host/"&gt;Service Cloud Host&lt;/a&gt; at github for more details on how to make the magic happen.&lt;br /&gt;&lt;br /&gt;Now imagine a Request to the Cloud with something like the following &amp; I think you will see the potential.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;// Formulate our Request and get a Response from the Gateway&lt;br /&gt;var response = cloud.Execute(new Request&lt;br /&gt;{&lt;br /&gt; Argument = new Person("Mark Kockerbeck") { Message = "I see you" },&lt;br /&gt; Services = new[]&lt;br /&gt; {&lt;br /&gt;  new ServiceCall { Name = "FindAddress", &lt;br /&gt;   Address = "http://epicapp.com/findaddress" },&lt;br /&gt;&lt;br /&gt;  new ServiceCall { Name = "FindEmail", &lt;br /&gt;   Address = "http://epicapp.com/findemail" },&lt;br /&gt;&lt;br /&gt;  new ServiceCall { Name = "FindTwitter", &lt;br /&gt;   Address = "http://epicapp.com/findtwitter" },&lt;br /&gt;&lt;br /&gt;  new ServiceCall { Name = "SendTwitterMessage", &lt;br /&gt;   Address = "http://epicapp.com/sendmessage/" },&lt;br /&gt;&lt;br /&gt;  new ServiceCall { Name = "SendEmail", &lt;br /&gt;   Address = "http://epicapp.com/sendmessage/" },&lt;br /&gt;&lt;br /&gt;  new ServiceCall { Name = "SendDirectMail", &lt;br /&gt;   Address = "http://epicapp.com/sendmessage/" },&lt;br /&gt; },&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A scary example but the potential for many applications exists.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-9196853902433914938?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/9196853902433914938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=9196853902433914938' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/9196853902433914938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/9196853902433914938'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/08/service-cloud-dynamic-calls-to-cloud-of.html' title='Service Cloud - dynamic calls to a cloud of WCF services'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-3370351293093971194</id><published>2010-07-14T17:30:00.000-07:00</published><updated>2010-07-14T18:26:47.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='culture'/><category scheme='http://www.blogger.com/atom/ns#' term='general'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>New &amp; Fun vs. Tried &amp; True</title><content type='html'>I love new technology -- .NET 4.0 and the &lt;a href="http://en.wikipedia.org/wiki/Dynamic_Language_Runtime"&gt;DLR&lt;/a&gt; are a dream come true.  I cannot wait to convince other developers of the awesomeness of having IronPython for middleware supported by compiled C# on the backend.  &lt;br /&gt;&lt;br /&gt;But before I go upgrading existing client sites to 4.0, I need to be &lt;strong&gt;sure&lt;/strong&gt; it will work.  I just want to see it be successful from start to finish.  I am skeptical by nature and want results before jumping in bed with any new tech.  Not that I don't think Microsoft did an amazing job with the latest framework -- its just that I'm not as familiar with the "workarounds" that I need to learn for things.  And yes, &lt;strong&gt;there will be&lt;/strong&gt; workarounds --  I have yet to see perfection in software (&lt;a href="http://www.gnu.org/software/coreutils/"&gt;only a few things&lt;/a&gt; come close).&lt;br /&gt;&lt;br /&gt;From my experience it seems that developers fall into two general categories when faced with new technology decisions.  Hopefully they change from one category to another.  If you're like me, you change on a project by project basis.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;New &amp; Fun&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Pros&lt;/strong&gt;: You are constantly ahead of the curve; some problems can be solved with minimal effort.  Faster than ever before.  Chances are you have more job security &amp; probably enjoy what you are doing everyday.  Your mind is constantly expanding.&lt;br /&gt;&lt;strong&gt;Cons&lt;/strong&gt;: You need a new library, a new pattern, a new framework or even a new language all the time.  If it isn't new, it's boring &amp; therefore must be shit.  You are constantly fighting with bugs and constantly discovering new things.  Nothing ever feels stable.  When it is stable -- it's time to move on or try something else.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;Tried &amp; True&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Pros&lt;/strong&gt;: You get to say "that's done, what else do you have for me?".  You don't spend as much time debugging.  You are great at estimating and meeting deadlines.  Your days are predictable.&lt;br /&gt;&lt;strong&gt;Cons&lt;/strong&gt;: You're probably old.  You may still write perl scripts (even COBOL or awk) when you need to.  You're falling behind the curve and have a constant fear of being left behind.  You may grow bitter as the world changes around you.&lt;br /&gt;&lt;br /&gt;These categories are completely independent of skill level.  I've seen Tried &amp; True programmers who are brilliant and New &amp; Fun programmers who can't get anything working.&lt;br /&gt;&lt;br /&gt;The most important thing anyone of us can hope to learn is &lt;strong&gt;when&lt;/strong&gt; do we use each technique.  There are times when New &amp; Fun is required.  This project demands perfection &amp; bleeding edge technology.  Other times (usually tight deadlines, emergencies or low budgets), you must not deviate from the norm.  Venturing into the unknown means suicide here.&lt;br /&gt;&lt;br /&gt;What will really drive you insane is when a project or team's culture &lt;strong&gt;changes&lt;/strong&gt; as time goes on.  People quickly abandon New &amp; Fun when the sky is falling (has fallen).  Or what is the most frustrating: when something starts off tight, you go Tried &amp; True only to find out that the client / owner / project manager demands new &amp; flashy.  "Can you add some cool new HTML 5 canvas animation to my Classic ASP site coded in VB"?  &lt;br /&gt;&lt;br /&gt;What I desire from any software I write is below.  (Depending on the application 3 &amp; 4 can switch).&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;1) Working&lt;/li&gt;&lt;br /&gt;&lt;li&gt;2) Stable&lt;/li&gt;&lt;br /&gt;&lt;li&gt;3) Readable&lt;/li&gt;&lt;br /&gt;&lt;li&gt;4) Fast&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Anything else...is just prototyping.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-3370351293093971194?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/3370351293093971194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=3370351293093971194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3370351293093971194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3370351293093971194'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/07/new-fun-vs-tried-true.html' title='New &amp; Fun vs. Tried &amp; True'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-8937280357603699175</id><published>2010-07-11T21:48:00.000-07:00</published><updated>2010-07-11T22:18:27.193-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>TwoRingBinder - a Custom ASP.NET MVC Model Binder</title><content type='html'>I haven't posted in a few months.  Been busy at work and starting playing WoW (I know -- its awful but its fun).  But a few weeks ago I made a Custom ModelBinder -- called &lt;a href="http://github.com/xeb/TwoRingBinder"&gt;TwoRingBinder&lt;/a&gt; -- for ASP.NET MVC.  Ok, it's not an implementation but rather a class inheriting from DataAnnotationsModelBinder that allows for easier custom Binding methods.  I put it on github but will explain how to use it below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/xeb/TwoRingBinder"&gt;Download&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;or check out the &lt;a href="http://github.com/xeb/TwoRingBinder"&gt;meat&lt;/a&gt; of the code.&lt;br /&gt;&lt;br /&gt;Essentially, TwoRingBinder allows you to write Binding Extensions instead of writing your own Custom Model Binder every time you want to do something tricky or different with Model Binding.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Example:&lt;/strong&gt; We have a model called &lt;a href="http://github.com/xeb/TwoRingBinder/blob/master/Tests/TwoRingBinder.Sample.WebUI/Models/SignUp.cs"&gt;SignUp&lt;/a&gt;.  SignUp has FirstName, LastName, Origin, IsFemale and FromRoot properties.  Only the FirstName and LastName properties will be bound from a form via a ValueProvider; however, we need IsFemale to have a value (assume for a service of some type).  Now, we don't want a checkbox on the site for people to select if they are female -- we want to just guess it based on their name (an arbitrary example to say the least).  With TwoRingBinder we can do this two ways (get it?!?!).  &lt;br /&gt;&lt;br /&gt;&lt;u&gt;Ring One:&lt;/u&gt; we can implement a method (or two) on our model -- the method(s) must be named &lt;strong&gt;OnBound&lt;/strong&gt; or &lt;strong&gt;OnBinding&lt;/strong&gt;.  &lt;br /&gt;&lt;br /&gt;&lt;u&gt;Ring Two:&lt;/u&gt; we can implement a IBindModelExtension -- which is a generic of our Model, SignUp.  The extension can have one or two methods, &lt;strong&gt;PreBindModel&lt;/strong&gt; and &lt;strong&gt;PostBindModel&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Let's set a value for IsFemale automatically using TwoRingBinder, see:&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;&lt;br /&gt;private readonly string[] _girlsNames = new[] { "Elaine", "Stephanie", "Jennifer" };&lt;br /&gt;&lt;br /&gt;public void PostBindModel(SignUp boundModel, ControllerContext controllerContext, &lt;br /&gt;                               ModelBindingContext bindingContext)&lt;br /&gt;{&lt;br /&gt;   boundModel.IsFemale = _girlsNames.Contains(boundModel.FirstName);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's not that much code but I've found TwoRingBinder super useful for those types of situations where a Custom Model Binder isn't appropriate.  Plus the IBindModelExtensions can be organized &amp; clean -- separate from your Controllers and Models (which they are neither).  Or if you so desire, the logic can be a part of the Model itself.  I think where you place the OnBind / OnBound logic depends entirely upon what you are doing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-8937280357603699175?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/8937280357603699175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=8937280357603699175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8937280357603699175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8937280357603699175'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/07/tworingbinder-custom-aspnet-mvc-model.html' title='TwoRingBinder - a Custom ASP.NET MVC Model Binder'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-8888092062211408183</id><published>2010-05-18T21:32:00.000-07:00</published><updated>2010-05-18T21:33:49.759-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='builds'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>ASP.NET MVC and MSBuild via Command-Line</title><content type='html'>I struggled with this one for a couple hours &amp; wanted to post some help.  I'm trying to move towards better deployment processes.  I'd like to use &lt;a href="http://www.jetbrains.com/teamcity/"&gt;TeamCity&lt;/a&gt; but until then, command-line will do.  It's how I roll anyways.&lt;br /&gt;&lt;br /&gt;When I first ran MSBuild on my ASP.NET MVC CSPROJ file I got the following error:&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;C:\Projects\MvcApplication.WebUI&gt;msbuild /p:Configuration=Debug MvcApplication.csproj&lt;br /&gt;Microsoft (R) Build Engine Version 2.0.50727.3053&lt;br /&gt;[Microsoft .NET Framework, Version 2.0.50727.3603]&lt;br /&gt;Copyright (C) Microsoft Corporation 2005. All rights reserved.&lt;br /&gt;&lt;br /&gt;Build started 5/18/2010 9:27:29 PM.&lt;br /&gt;__________________________________________________&lt;br /&gt;Project "C:\Projects\MvcApplication.WebUI\MvcApplication.csproj" (default targets):&lt;br /&gt;&lt;br /&gt;Target ResolveProjectReferences:&lt;br /&gt;    C:\Projects\Assembly.csproj(200,11): error MSB4019: The imported project "C:\Microsoft&lt;br /&gt;.CSharp.targets" was not found. Confirm that the path in the &lt;Import&gt; declaration is correct, and that the file exists on disk.&lt;br /&gt;Done building target "ResolveProjectReferences" in project "Spinsix.Lincs.WebUI.csproj" -- FAILED.&lt;br /&gt;&lt;br /&gt;Done building project "MvcApplication.WebUI.csproj" -- FAILED.&lt;br /&gt;&lt;br /&gt;Build FAILED.&lt;br /&gt;C:\Projects\Assembly.csproj(200,11): error MSB4019: The imported project "C:\Microsoft.CSh&lt;br /&gt;arp.targets" was not found. Confirm that the path in the &lt;Import&gt; declaration is correct, and that the file exists on disk.&lt;br /&gt;    0 Warning(s)&lt;br /&gt;    1 Error(s)&lt;br /&gt;&lt;br /&gt;Time Elapsed 00:00:00.12&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The trick here is the Environment Variables that Visual Studio sets up for you.  So you need to run the following in order to get them setup:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat&lt;br /&gt;or&lt;br /&gt;C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or if you are writing a Build Script / Batch file, simply do:&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;cd  C:\Program Files\Microsoft Visual Studio 9.0\VC\&lt;br /&gt;call vcvarsall.bat &gt;NUL &lt;br /&gt;cd C:\Projects\MyProject\&lt;br /&gt;msbuild /p:Configuration=Debug MvcApplication.csproj&lt;br /&gt;xcopy /a /e (whatever other options) *.* x:\SomeDestination&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hope that helps someone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-8888092062211408183?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/8888092062211408183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=8888092062211408183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8888092062211408183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8888092062211408183'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/05/aspnet-mvc-and-msbuild-via-command-line.html' title='ASP.NET MVC and MSBuild via Command-Line'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-2143846446634309499</id><published>2010-03-17T23:09:00.000-07:00</published><updated>2010-03-17T23:59:11.454-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trading'/><category scheme='http://www.blogger.com/atom/ns#' term='tradingblox'/><category scheme='http://www.blogger.com/atom/ns#' term='financial engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Why TradingBlox is so Awesome</title><content type='html'>&lt;a href="http://www.tradingblox.com"&gt;TradingBlox&lt;/a&gt; is a relatively expensive piece of software that you've (probably) never heard of.  You may never use it.  But I still think you should know about it.&lt;br /&gt;&lt;br /&gt;I've been passionate about the financial markets for years.  Later I'll explain this month why you should at least &lt;strong&gt;know&lt;/strong&gt; something about them.  I had the pleasure of working at &lt;a href="http://www.carmichaelandco.com/" target="_blank"&gt;Carmichael and Company LLC&lt;/a&gt; and learned a great deal about trading from Ralph Carmichael.  It excited a passion in me.  This passion was fueled by books like: Market Wizards, Reminisces of a Stock Operator and The Way of the Turtle.  Also this little PDF about the &lt;a href="http://bigpicture.typepad.com/comments/files/turtlerules.pdf"&gt;original Turtle trading rules&lt;/a&gt; really helped.&lt;br /&gt;&lt;br /&gt;After trying to program my own recreation of the Turtle rules, I stumbled upon TradingBox.  It did everything I wanted and more.  It has an amazing community.  It supports trading &amp; optimizing multiple markets with the same system (which was a pain -- if not impossible -- using TradeStation).&lt;br /&gt;&lt;br /&gt;TradingBlox lets you program trading rules to buy &amp; sell Futures (or Forex / Stocks).  Below is my own brief outline on the TradingBlox structure.&lt;br /&gt;&lt;br /&gt;"Blox" are simply snippets of code that are broken into various categories, including:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Entry and Exit&lt;/strong&gt; -- signals when to enter or exit&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Entry Only&lt;/strong&gt; -- signals when to enter &lt;br /&gt;&lt;li&gt;&lt;strong&gt;Exit Only&lt;/strong&gt; -- signals when to exit&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Entry, Exit and Money [Manager]&lt;/strong&gt; -- signals when to enter, exit &amp; how much to trade&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Money Manager&lt;/strong&gt; -- determines how much to trade&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Portfolio Manager&lt;/strong&gt; -- determines which markets you should trade&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Risk Manager&lt;/strong&gt; -- adjusts / monitors your overall risk of existing positions&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Auxiliary&lt;/strong&gt; -- for miscellaneous &amp; reusable code&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Right now, I want to just focus on an Entry &amp; Exit Block.  Let's take a look at a very simple one that uses 2 Moving Averages to determine when to buy &amp; sell.  We buy at the exact day that short moving average crosses over the long moving average.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;VARIABLES: currentclose, stopPrice TYPE: Price&lt;br /&gt;&lt;br /&gt;' Get the current close.&lt;br /&gt;currentClose = instrument.close&lt;br /&gt;&lt;br /&gt;' If we are not long and the faster moving averages are above the slower one.&lt;br /&gt;IF instrument.position &lt;&gt; LONG AND&lt;br /&gt; shortMovingAverage &gt; longMovingAverage THEN&lt;br /&gt;&lt;br /&gt;  ' Enter a long on the open with no stop.&lt;br /&gt;  broker.EnterLongOnOpen&lt;br /&gt;ENDIF&lt;br /&gt;&lt;br /&gt;' If we are not short and the faster moving averages are below the slower one.&lt;br /&gt;IF instrument.position &lt;&gt; SHORT AND&lt;br /&gt; shortMovingAverage &lt; longMovingAverage THEN&lt;br /&gt;&lt;br /&gt;  ' Enter a short on the open with no stop.&lt;br /&gt;  broker.EnterShortOnOpen&lt;br /&gt;ENDIF&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Makes sense, right?  TradingBlox is extremely powerful &amp; I'm going to be sharing more about Trading, Mechanical Systems &amp; the Markets in general in the near future.  It's what I &lt;i&gt;really&lt;/i&gt; get excited about &amp; its what I really love.  &lt;br /&gt;&lt;br /&gt;In the meantime, check out: &lt;a href="http://www.tradingblox.com/"&gt;TradingBlox&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-2143846446634309499?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/2143846446634309499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=2143846446634309499' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/2143846446634309499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/2143846446634309499'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/09/why-tradingblox-is-so-awesome.html' title='Why TradingBlox is so Awesome'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-3550303470072309151</id><published>2010-02-05T19:14:00.000-08:00</published><updated>2010-02-05T19:19:53.251-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='spark'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Spark - Optional Parameters in Partials</title><content type='html'>While on the topic of the &lt;a href="http://sparkviewengine.com"&gt;Spark View Engine&lt;/a&gt;, there is an easy way to make a parameter of a partial &lt;strong&gt;optional&lt;/strong&gt; so you don't always need to pass a value when calling the partial.&lt;br /&gt;&lt;br /&gt;Simply define the variable as part of the &lt;strong&gt;viewdata&lt;/strong&gt; property.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;!-- samplePartial.spark --&amp;gt;&lt;br /&gt;&amp;lt;viewdata optionalParameter="string" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;a class="active?{optionalParameter == "home"}"&amp;gt;Home&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it.  Now you can call the partial by itself...&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;samplePartial /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... or with the &lt;strong&gt;optionalParameter&lt;/strong&gt;...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;samplePartial optionalParameter="home" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A helpful trick that I couldn't find a lot about online.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-3550303470072309151?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/3550303470072309151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=3550303470072309151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3550303470072309151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3550303470072309151'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/02/spark-optional-parameters-in-partials.html' title='Spark - Optional Parameters in Partials'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-1736566073796902720</id><published>2010-02-04T15:06:00.001-08:00</published><updated>2010-07-15T11:46:03.597-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='spark'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Spark - Recursive rendering of partial files not possible (but it is!)</title><content type='html'>We've been using the &lt;a href="http://sparkviewengine.com"&gt;Spark View Engine&lt;/a&gt; a lot at work.  I absolutely love it.  Our front end developers love it (they don't need to re-learn something like we had to for &lt;a href="http://code.google.com/p/nhaml/"&gt;NHaml&lt;/a&gt;) and if they don't want to use Spark's features, standard HTML works without problems.&lt;br /&gt;&lt;br /&gt;During one project, I was making some contextual menus.  I wanted to call a Spark partial recursively in order to not repeat myself &amp; keep things flexible for the future.  Unfortunately Spark specifically disallows this.  If you try it, you will get an Exception that states &lt;strong&gt;"Recursive rendering of partial files not possible"&lt;/strong&gt;.  &lt;br /&gt;&lt;br /&gt;Well that just sucks.  I understand the limitation in the View Engine itself but there is a way around it.  Not super elegant but definitely functional without sacrificing anything other than &lt;i&gt;style&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;I posted &lt;a href="http://groups.google.com/group/spark-dev/browse_thread/thread/80eb8924d4f1d29f/e9cb33b08bd6762e?show_docid=e9cb33b08bd6762e&amp;fwc=1"&gt;the following example&lt;/a&gt; in the Spark project itself.  The trick is using the &lt;strong&gt;HtmlHelper&lt;/strong&gt;'s &lt;strong&gt;RenderPartial&lt;/strong&gt; method.&lt;br /&gt;&lt;br /&gt;Let's say we have a partial called: &lt;strong&gt;navigation.spark&lt;/strong&gt;.&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt; --- Contents of: navigation.spark --- &amp;gt;&lt;br /&gt;&amp;lt;viewdata navItem="Models.NavigationItem" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a if="navItem != null" href="${navItem.Url}"&gt;${navItem.Name}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;ul if="navItem.Children.Count &gt; 0" &amp;gt;&lt;br /&gt;  &amp;lt;for each="var child in navItem.Children" &amp;gt;&lt;br /&gt;    #{Html.RenderPartial("_navigation.spark", new { child })&lt;strong&gt;;&lt;/strong&gt;}&lt;br /&gt;  &amp;lt;/for&amp;gt;&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the page that you want to list navigation items, simply do:&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;viewdata navigationItems="List&amp;lt;Models.Navigation&amp;gt;" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;navigation for="var nav in navigationItems" navItem="nav" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you can call the Partial recursively without issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-1736566073796902720?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/1736566073796902720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=1736566073796902720' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/1736566073796902720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/1736566073796902720'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/02/spark-recursive-rendering-of-partial.html' title='Spark - Recursive rendering of partial files not possible (but it is!)'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-2499917041177289025</id><published>2010-01-19T15:02:00.000-08:00</published><updated>2010-02-05T17:33:36.929-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>How to Troubleshoot a Problem</title><content type='html'>Building computers early on in life was an invaluable experience.  Fighting with mobos &amp; hunting for drivers taught me more about software development (&amp; customer support) than hardware.  I've been trying to summarize those lessons into an easy framework for debugging, troubleshooting and fighting most problems.  Below is just what I have so far.  Hopefully it's useful in some way.&lt;br /&gt;&lt;br /&gt;1) &lt;strong&gt;Don't Panic&lt;/strong&gt; - if this sounds familiar, congrats, you're a geek.  You have to be calm &amp; stop freaking out to be of any use.  Someone going ape shit in your face is the fastest way to stop your brain from working.  So take a moment, read &lt;a href="http://zenhabits.net/"&gt;Zen Habits&lt;/a&gt; and just chill for a second.&lt;br /&gt;&lt;br /&gt;2) &lt;strong&gt;Identify the Problem&lt;/strong&gt; - before doing anything, ANYTHING, you must figure out what's going wrong.  Is the page not displaying?  Is an error appearing?  What's in the stack trace?  What is happening that shouldn't be?  3/10 times you will stop here because nothing is wrong at all.  Someone was just going crazy.  If it's not one of those times, be thankful that you figured out what was going on &amp; are closer to fixing it.&lt;br /&gt;&lt;br /&gt;3) &lt;strong&gt;Stop the Bleeding&lt;/strong&gt; - if your server is not responding, your website is down or a database is just hung, stop thinking about why its happening &amp; get it back up &amp; running!  Seriously.  Stop reading!  Go do it!  It's easier to explain what went wrong after things are working than trying to explain why the Apocalypse is inevitably happening RIGHT NOW.&lt;br /&gt;&lt;br /&gt;4) &lt;strong&gt;Document the Symptoms&lt;/strong&gt; - ok, you don't actually have to write anything down, but at least understand what is going on.  Get out a whiteboard.  List it out in front of your face.  You may recognize something.&lt;br /&gt;&lt;br /&gt;5) &lt;strong&gt;Diagnose the Disease with Peers&lt;/strong&gt; - come up with some kind of diagnose and ask your buddies and/or co-workers.  Start talking about it.  Someone may say something that triggers a memory that helps you identify the root problem.  Or someone may already know what's wrong but just hasn't shared it yet.&lt;br /&gt;&lt;br /&gt;6) &lt;strong&gt;Start Treatment&lt;/strong&gt; - make forward progress.  Come up with a regiment of patched, upgraded, caching, mapreducin', memory-managed, leak-destroying updates.  Throw them at the problem &amp; see what happens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-2499917041177289025?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/2499917041177289025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=2499917041177289025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/2499917041177289025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/2499917041177289025'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2010/01/how-to-troubleshoot-problem.html' title='How to Troubleshoot a Problem'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-923882185514709386</id><published>2009-10-18T22:50:00.001-07:00</published><updated>2009-10-19T22:44:46.613-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>TrustButVerify - simple jQuery validation powered by LiveValidation</title><content type='html'>I really like the way &lt;a href="http://www.livevalidation.com"&gt;LiveValidation&lt;/a&gt; runs; however, I REALLY LOVE jQuery selectors &amp; chaining.  Unfortunately the LiveValidation approach to validation doesn't feel right when looking at a lot of field-specific validators surrounded by super terse jQuery syntax.&lt;br /&gt;&lt;br /&gt;So I decided to make a small 79-line wrapper-type of plugin that is powered by LiveValidation but comes with all the power of jQuery's selectors, chaining and... well, jQuery.&lt;br /&gt;&lt;br /&gt;I called the plugin, &lt;a href="http://epicapp.com/trustbutverify"&gt;TrustButVerify&lt;/a&gt;.  Check it out &amp; let me know your thoughts or if there is room for improvement (which there definitely is).&lt;br /&gt;&lt;br /&gt;I have NOT exposed all of the LiveValidation methods; just the ones I found useful &amp; necessary :-p&lt;br /&gt;&lt;br /&gt;Here's a sample of some validation:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;$(document).ready(function(){&lt;br /&gt;  $('#form .required').required();&lt;br /&gt;  $('#email').validEmail();&lt;br /&gt;  $('#zip').matches(/^\d{5}$/);&lt;br /&gt;  $('input.address').required().validate(someCustomFunction, 'your address is out of our area ');&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-923882185514709386?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/923882185514709386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=923882185514709386' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/923882185514709386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/923882185514709386'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/10/trustbutverify-simple-jquery-validation.html' title='TrustButVerify - simple jQuery validation powered by LiveValidation'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-1306909021670182577</id><published>2009-09-25T15:30:00.001-07:00</published><updated>2009-09-25T15:34:54.972-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Convert SQL types in destination to SQL type in source</title><content type='html'>Another little script I needed for today.  Feel free to expand on the CASE statement for your own types (which I will do should I need to run this again).&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; Will transform destination table's column types to match the source database's  &lt;br /&gt; (when column names match)&lt;br /&gt; codesnippet:83d07e82-3866-4877-849f-0ae06322b9fb&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;declare @destination varchar(50)&lt;br /&gt;declare @source varchar(50)&lt;br /&gt;&lt;br /&gt;---- Configuration -----&lt;br /&gt;set @destination = 'PlanImport'&lt;br /&gt;set @source = 'Plan'&lt;br /&gt;------------------------&lt;br /&gt;&lt;br /&gt;declare @i int&lt;br /&gt;declare @count int&lt;br /&gt;declare @sql varchar(8000)&lt;br /&gt;declare @columnName varchar(8000)&lt;br /&gt;declare @columnType varchar(8000)&lt;br /&gt;declare @columns table (id int identity(1,1), columnName varchar(50), columnType varchar(50) )&lt;br /&gt;&lt;br /&gt;-- insert source columns that are in destination&lt;br /&gt;insert into @columns&lt;br /&gt;select source.[Name], &lt;br /&gt; (CASE source_types.[Name]&lt;br /&gt; WHEN 'decimal' THEN&lt;br /&gt;  source_types.[Name] + '(' + cast(source.[precision] as varchar(50)) + ',' + cast(source.[scale] as varchar(50)) + ')' &lt;br /&gt; WHEN 'int' THEN&lt;br /&gt;  source_types.[Name]&lt;br /&gt; WHEN 'varchar' THEN&lt;br /&gt;  source_types.[Name] + '(' + cast(source.[max_length] as varchar(50)) + ')' &lt;br /&gt; ELSE &lt;br /&gt;  source_types.[Name]&lt;br /&gt; END) as [Name]&lt;br /&gt;from sys.columns as source&lt;br /&gt;join sys.columns as destination on destination.[name] = source.[name]&lt;br /&gt;join sys.types source_types on source_types.system_type_id = source.system_type_id&lt;br /&gt;where source.object_id = object_id(@source) and destination.object_id = object_id(@destination) &lt;br /&gt;&lt;br /&gt;set @i = 1&lt;br /&gt;set @count = (select max(id) from @columns)&lt;br /&gt;&lt;br /&gt;while(@i &lt;= @count)&lt;br /&gt;begin&lt;br /&gt; set @columnName = (SELECT [columnName] FROM @columns WHERE [ID] = @i)&lt;br /&gt; set @columnType = (SELECT [columnType] FROM @columns WHERE [ID] = @i)&lt;br /&gt; &lt;br /&gt; --select @columnName&lt;br /&gt; set @sql = 'ALTER TABLE ' + @destination + ' ALTER COLUMN ' + @columnName + ' ' + @columnType&lt;br /&gt;&lt;br /&gt; execute(@sql)&lt;br /&gt;&lt;br /&gt; set @i = @i + 1&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;select 'Done!'&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-1306909021670182577?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/1306909021670182577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=1306909021670182577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/1306909021670182577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/1306909021670182577'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/09/convert-sql-types-in-destination-to-sql.html' title='Convert SQL types in destination to SQL type in source'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-1537300366991494532</id><published>2009-09-25T14:56:00.000-07:00</published><updated>2009-09-25T14:59:48.383-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Convert literal SQL 'NULL' to real NULL</title><content type='html'>Pretty straight forward.  Had to do this today &amp; thought I'd share the solution I came up with.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;/*&lt;br /&gt; Will turn literal "NULL" into SQL NULL in any table (for all columns)&lt;br /&gt; codesnippet:25616582-ced6-4e59-ab4c-25d2128cc4b6&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;declare @tableName varchar(50)&lt;br /&gt;&lt;br /&gt;---- Configuration -----&lt;br /&gt;set @tableName = 'PlanImport'&lt;br /&gt;------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;declare @i int&lt;br /&gt;declare @count int&lt;br /&gt;declare @sql varchar(8000)&lt;br /&gt;declare @columnName varchar(8000)&lt;br /&gt;declare @columns table (id int identity(1,1), columnName varchar(50))&lt;br /&gt;&lt;br /&gt;insert into @columns&lt;br /&gt;select [Name] from sys.columns where object_id = object_id(@tableName) &lt;br /&gt;and system_type_id in (select system_type_id from sys.types where [name] like '%varchar%' or [name] like '%text%' )&lt;br /&gt;&lt;br /&gt;set @i = 1&lt;br /&gt;set @count = (select max(id) from @columns)&lt;br /&gt;&lt;br /&gt;while(@i &lt;= @count)&lt;br /&gt;begin&lt;br /&gt; set @columnName = (SELECT [columnName] FROM @columns WHERE [ID] = @i)&lt;br /&gt; set @sql = 'UPDATE [' + @tableName + '] SET [' + @columnName + '] = NULL WHERE [' + @columnName + '] = ''NULL'''&lt;br /&gt;&lt;br /&gt; EXECUTE(@sql)&lt;br /&gt;&lt;br /&gt; set @i = @i + 1&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-1537300366991494532?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/1537300366991494532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=1537300366991494532' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/1537300366991494532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/1537300366991494532'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/09/convert-literal-sql-null-to-real-null.html' title='Convert literal SQL &apos;NULL&apos; to real NULL'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-6869486625765818927</id><published>2009-09-16T20:21:00.000-07:00</published><updated>2009-09-16T20:30:02.116-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='fluent nhibernate'/><title type='text'>Fluent NHibernate - Incorrect syntax near the keyword 'Group'</title><content type='html'>I have to share this.  I spent a good amount of time searching around Fluent NHibernate for a way to escape columns in the generated SQL while still using AutoMapping.  &lt;br /&gt;&lt;br /&gt;My initial configuration looked like:&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;Fluently.Configure()&lt;br /&gt;.Database(MsSqlConfiguration.MsSql2005.ConnectionString(&lt;br /&gt;  c =&gt; c.Is(ConfigurationManager.ConnectionStrings["Something"].ConnectionString)))&lt;br /&gt; .Mappings(x =&gt; x.AutoMappings.Add(AutoPersistenceModel.MapEntitiesFromAssemblyOf&lt;SomeType&gt;()&lt;br /&gt;   .WithSetup(convention =&gt;&lt;br /&gt;     {&lt;br /&gt;       convention.FindIdentity = p =&gt; p.Name == p.DeclaringType.Name + "Id";&lt;br /&gt;       convention.GetComponentColumnPrefix = type =&gt; type.Name + "Id";&lt;br /&gt;     } )&lt;br /&gt; .BuildSessionFactory()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This works great, but I had a property in my class (SomeType) that is called Group.  This was causing the SqlException: &lt;strong&gt;Incorrect syntax near the keyword 'Group'&lt;/strong&gt; (others would be like: &lt;strong&gt;Incorrect syntax near the keyword 'User'&lt;/strong&gt; or &lt;strong&gt;Incorrect syntax near the keyword 'Table'&lt;/strong&gt;).&lt;br /&gt;&lt;br /&gt;The solution I found was to use the Fluent NHibernate ConventionDiscovery + ConvensionBuilder to always add a column name possibility (to use in SQL) which would be escaped by [] for every property.  Why not?  This is SQL 2005 I'm working with, right?&lt;br /&gt;&lt;br /&gt;So the final solution looked like:&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;Fluently.Configure()&lt;br /&gt;.Database(MsSqlConfiguration.MsSql2005.ConnectionString(&lt;br /&gt;  c =&gt; c.Is(ConfigurationManager.ConnectionStrings["Something"].ConnectionString)))&lt;br /&gt; .Mappings(x =&gt; x.AutoMappings.Add(AutoPersistenceModel.MapEntitiesFromAssemblyOf&lt;SomeType&gt;()&lt;br /&gt;   .WithSetup(convention =&gt;&lt;br /&gt;     {&lt;br /&gt;       convention.FindIdentity = p =&gt; p.Name == p.DeclaringType.Name + "Id";&lt;br /&gt;       convention.GetComponentColumnPrefix = type =&gt; type.Name + "Id";&lt;br /&gt;     } )&lt;br /&gt;   .ConventionDiscovery.Setup(c =&gt; c.Add(ConventionBuilder.Property.Always(&lt;br /&gt;      s =&gt; s.ColumnNames.Add("[" + s.Property.Name + "]"))))))&lt;br /&gt; .BuildSessionFactory()&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-6869486625765818927?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/6869486625765818927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=6869486625765818927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6869486625765818927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6869486625765818927'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/09/fluent-nhibernate-incorrect-syntax-near.html' title='Fluent NHibernate - Incorrect syntax near the keyword &apos;Group&apos;'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-4369013915966633147</id><published>2009-08-27T23:06:00.001-07:00</published><updated>2009-08-27T23:21:14.560-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='helper methods'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Strongly typed AppSettings with defaults</title><content type='html'>Very often I want configurable options for miscellaneous settings; but I hate to shift my focus from the code I'm working on to add a new AppSetting.  Sometimes these settings are essential but more often than they are just options that I &lt;i&gt;may&lt;/i&gt; need.  &lt;br /&gt;&lt;br /&gt;So the solution I like to use is to make default values for such AppSettings.  If the service you are writing needs to retry a database or web service call a few times, why not make that option configurable but use a default of 5.  The method below will grab an AppSetting &amp; try to convert it.  If it fails, it uses the default.  Plus the generic T can be a value or reference type.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;public static T GetAppSetting&amp;lt;T&amp;gt;(string key, T defaultValue)&lt;br /&gt;{&lt;br /&gt; if (String.IsNullOrEmpty(ConfigurationManager.AppSettings[key])) return defaultValue;&lt;br /&gt;&lt;br /&gt; try&lt;br /&gt; { &lt;br /&gt;  return (T)Convert.ChangeType(ConfigurationManager.AppSettings[key], typeof(T));&lt;br /&gt; }&lt;br /&gt; catch&lt;br /&gt; {&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return defaultValue;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Sample Usage&lt;br /&gt;public void DoSomething()&lt;br /&gt;{&lt;br /&gt; if(GetAppSetting("ShouldRun", true))&lt;br /&gt; {&lt;br /&gt;  for(int i = 0; i &lt; GetAppSetting("NumberOfTries", 5); i++)&lt;br /&gt;  {&lt;br /&gt;   if(SomeMethodSucceeds()) break;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-4369013915966633147?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/4369013915966633147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=4369013915966633147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/4369013915966633147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/4369013915966633147'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/08/strongly-typed-appsettings-with.html' title='Strongly typed AppSettings with defaults'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-3203448860044507830</id><published>2009-08-14T08:50:00.000-07:00</published><updated>2009-08-14T09:11:30.999-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='streams'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Stream was not readable</title><content type='html'>I recently started writing some tests (in xUnit using Moq + StructureMap) for a service that calls a class -- let's call it LogWriter -- that simply writes formatted logging data to a Stream.  After creating an interface for the logging class, ILogWriter, I wanted to write some tests on LogWriter to see if it was working as expected (before testing out my service which depends on ILogWriter).&lt;br /&gt;&lt;br /&gt;After the ILogWriter was done, I used StreamReader to check out it's input.  The Stream I told it to write to was a MemoryStream (this &lt;i&gt;is&lt;/i&gt; unit testing).&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt; public class LogWriterTests&lt;br /&gt; {&lt;br /&gt;  [Fact]&lt;br /&gt;  public void BaseStream_Is_Not_Empty()&lt;br /&gt;  {&lt;br /&gt;   MemoryStream stream = new MemoryStream();&lt;br /&gt;   LogWriter logWriter = new LogWriter(stream);&lt;br /&gt;   logWriter.WriteLine(new[] { DateTime.Now.ToString("yyyy-MM-dd"), "Log data" });&lt;br /&gt;&lt;br /&gt;   using (StreamReader sr = new StreamReader(stream))&lt;br /&gt;   {&lt;br /&gt;    Assert.NotEmpty(sr.ReadToEnd());&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// A basic example&lt;br /&gt;public class LogWriter&lt;br /&gt;{&lt;br /&gt; public LogWriter(Stream stream)&lt;br /&gt; {&lt;br /&gt;  BaseStream = new StreamWriter(stream);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public StreamWriter BaseStream { get; set; }&lt;br /&gt;&lt;br /&gt; public void WriteLine(params object[] logObjects)&lt;br /&gt; {&lt;br /&gt;  BaseStream.WriteLine(DoSomeFormatting(logObjects));&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The "BaseStream_Is_Not_Empty" test always failed.  The Stream was always empty.  Hmmm...how about if we try closing the Stream?&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;[Fact]&lt;br /&gt;public void BaseStream_Is_Not_Empty()&lt;br /&gt;{&lt;br /&gt; MemoryStream stream = new MemoryStream();&lt;br /&gt; LogWriter logWriter = new LogWriter(stream);&lt;br /&gt; logWriter.WriteLine(new[] { DateTime.Now.ToString("yyyy-MM-dd"), "Log data" });&lt;br /&gt; logWriter.BaseStream.Close();&lt;br /&gt;&lt;br /&gt; using (StreamReader sr = new StreamReader(stream))&lt;br /&gt; {&lt;br /&gt;  Assert.NotEmpty(sr.ReadToEnd());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we would expect to get: &lt;strong&gt;Stream was not readable&lt;/strong&gt;.  The Stream has been closed -- you can't read from it.  The trick now is to reset the position of the Stream and set the BaseStream of LogWriter to AutoFlush.&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;[Fact]&lt;br /&gt;public void BaseStream_Is_Not_Empty()&lt;br /&gt;{&lt;br /&gt; MemoryStream stream = new MemoryStream();&lt;br /&gt; LogWriter logWriter = new LogWriter(stream);&lt;br /&gt; logWriter.WriteLine(new[] { DateTime.Now.ToString("yyyy-MM-dd"), "Log data" });&lt;br /&gt; logWriter.BaseStream.AutoFlush = true;&lt;br /&gt; stream.Seek(0, SeekOrigin.Begin);&lt;br /&gt;&lt;br /&gt; using (StreamReader sr = new StreamReader(stream))&lt;br /&gt; {&lt;br /&gt;  Assert.NotEmpty(sr.ReadToEnd());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And now our test passes.  Moving on...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-3203448860044507830?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/3203448860044507830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=3203448860044507830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3203448860044507830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/3203448860044507830'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/08/stream-was-not-readable.html' title='Stream was not readable'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-5543626356666286042</id><published>2009-08-03T17:07:00.000-07:00</published><updated>2009-08-25T14:27:35.735-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cryptography'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='structuremap'/><category scheme='http://www.blogger.com/atom/ns#' term='fluent nhibernate'/><title type='text'>Fluent NHibernate + Encrypting Values</title><content type='html'>I recently created two CLR User Defined Functions for SQL Server 2005 (written in C#) to decrypt &amp; encrypt a given string (based on a hard-coded key).&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;&lt;br /&gt;select dbo.EncryptString('Testing')&lt;br /&gt;-- Returns: Fjfds243qcm43fsdj2343==&lt;br /&gt;&lt;br /&gt;select dbo.DecryptString('Fjfds243qcm43fsdj2343==')&lt;br /&gt;-- Returns: Testing&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty simple stuff.  This will allow the user with enough access to pull encrypted data out of the database and provide the ability to restrict decryption to other SQL users.&lt;br /&gt;&lt;br /&gt;Now to implement this in code...&lt;br /&gt;&lt;br /&gt;Because it's awesome, Fluent NHibernate has a method called FormulasIs that assists in building out values using SQL.  &lt;br /&gt;&lt;br /&gt;&lt;pre id="encryption-sample" name="code" class="c-sharp"&gt;&lt;br /&gt;&lt;br /&gt;public class User&lt;br /&gt;{&lt;br /&gt;   public virtual int Id { get; set; }&lt;br /&gt;   public virtual DateTime DateOfBirth { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public sealed class UserMap : ClassMap&lt;User&gt;&lt;br /&gt;{&lt;br /&gt;  public UserMap()&lt;br /&gt;  {&lt;br /&gt;    WithTable("dbo.[User]");&lt;br /&gt;    Id(x =&gt; x.Id, "[ID]");&lt;br /&gt;    Map(x =&gt; x.DateOfBirth, "DOB").FormulaIs("dbo.DecryptString(DOB)");&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is perfect.  Exactly what I needed...until I needed to save the value.  Fluent NHibernate will not pass any value to the database for the DateOfBirth property -- it is being set as NULL.&lt;br /&gt;&lt;br /&gt;A solution I came up with was to use 2 Properties in the entity.  1 for the developer to use, and 1 for NHibernate to use.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;&lt;br /&gt;public class User&lt;br /&gt;{&lt;br /&gt;   // Get the default instance using StructureMap&lt;br /&gt;   private readonly IEncryptionService _encryptionService =&lt;br /&gt;                   ObjectFactory.GetInstance&amp;lt;IEncryptionService&amp;gt;();&lt;br /&gt;   public virtual int Id { get; set; }&lt;br /&gt;   public virtual DateTime? DateOfBirth&lt;br /&gt;   {&lt;br /&gt;     get&lt;br /&gt;     {&lt;br /&gt;       return _encryptionService.DecryptObject&amp;lt;DateTime?&amp;gt;(DateOfBirthEncrypted);&lt;br /&gt;     }&lt;br /&gt;     set&lt;br /&gt;     {&lt;br /&gt;       DateOfBirthEncrypted= _encryptionService.EncryptString(value.Value&lt;br /&gt;                                   .ToString("yyyy-MM-dd HH:mm:ss"));&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;   [Obsolete("Use the 'DateOfBirth' property -- this property is only to be used by NHibernate")]&lt;br /&gt;   public virtual string DateOfBirthEncrypted { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public sealed class UserMap : ClassMap&amp;lt;User&amp;gt;&lt;br /&gt;{&lt;br /&gt;  public UserMap()&lt;br /&gt;  {&lt;br /&gt;    WithTable("dbo.[User]");&lt;br /&gt;    Id(x =&gt; x.Id, "[ID]");&lt;br /&gt;    Map(x =&gt; x.DateOfBirthEncrypted, "DOB");&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And a sample EncryptionService is below:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Security.Cryptography;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace Services&lt;br /&gt;{&lt;br /&gt; public class EncryptionService : IEncryptionService &lt;br /&gt; {&lt;br /&gt;  /// &amp;lt;summary&amp;gt;&lt;br /&gt;  /// Decrypts a string &lt;br /&gt;  /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  /// &amp;lt;param name="encryptedString"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;  /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;  public String DecryptString(string encryptedString)&lt;br /&gt;  {&lt;br /&gt;   if (String.IsNullOrEmpty(encryptedString)) return String.Empty;&lt;br /&gt;&lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;    using (TripleDESCryptoServiceProvider cypher = new TripleDESCryptoServiceProvider())&lt;br /&gt;    {&lt;br /&gt;     PasswordDeriveBytes pdb = new PasswordDeriveBytes("ENTERAKEYHERE", new byte[0]);&lt;br /&gt;     cypher.Key = pdb.GetBytes(16);&lt;br /&gt;     cypher.IV = pdb.GetBytes(8);&lt;br /&gt;&lt;br /&gt;     using (MemoryStream ms = new MemoryStream())&lt;br /&gt;     {&lt;br /&gt;      using (CryptoStream cs = new CryptoStream(ms, cypher.CreateDecryptor(), CryptoStreamMode.Write))&lt;br /&gt;      {&lt;br /&gt;       byte[] data = Convert.FromBase64String(encryptedString);&lt;br /&gt;       cs.Write(data, 0, data.Length);&lt;br /&gt;       cs.Close();&lt;br /&gt;&lt;br /&gt;       return Encoding.Unicode.GetString(ms.ToArray());&lt;br /&gt;      }&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;   catch&lt;br /&gt;   {&lt;br /&gt;    return String.Empty;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /// &amp;lt;summary&amp;gt;&lt;br /&gt;  /// Encrypts a string&lt;br /&gt;  /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  /// &amp;lt;param name="decryptedString"&lt;br /&gt;  /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;  public String EncryptString(string decryptedString)&lt;br /&gt;  {&lt;br /&gt;   if (String.IsNullOrEmpty(decryptedString)) return String.Empty;&lt;br /&gt;&lt;br /&gt;   using (TripleDESCryptoServiceProvider cypher = new TripleDESCryptoServiceProvider())&lt;br /&gt;   {&lt;br /&gt;    PasswordDeriveBytes pdb = new PasswordDeriveBytes("ENTERAKEYHERE", new byte[0]);&lt;br /&gt;&lt;br /&gt;    cypher.Key = pdb.GetBytes(16);&lt;br /&gt;    cypher.IV = pdb.GetBytes(8);&lt;br /&gt;&lt;br /&gt;    using (MemoryStream ms = new MemoryStream())&lt;br /&gt;    {&lt;br /&gt;     using (CryptoStream cs = new CryptoStream(ms, cypher.CreateEncryptor(), CryptoStreamMode.Write))&lt;br /&gt;     {&lt;br /&gt;      byte[] data = Encoding.Unicode.GetBytes(decryptedString);&lt;br /&gt;&lt;br /&gt;      cs.Write(data, 0, data.Length);&lt;br /&gt;      cs.Close();&lt;br /&gt;&lt;br /&gt;      return Convert.ToBase64String(ms.ToArray());&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /// &amp;lt;summary&amp;gt;&lt;br /&gt;  /// Decrypts a given value as type of T, if unsuccessful the defaultValue is used&lt;br /&gt;  /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;br /&gt;  /// &amp;lt;param name="value"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;  /// &amp;lt;param name="defaultValue"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;  /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;  public T DecryptObject&amp;lt;T&amp;gt;(object value, T defaultValue)&lt;br /&gt;  {&lt;br /&gt;   if (value == null) return defaultValue;&lt;br /&gt;&lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;     Type conversionType = typeof(T);&lt;br /&gt;&lt;br /&gt;     // Some trickery for Nullable Types&lt;br /&gt;     if (conversionType.IsGenericType &amp;&amp; conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable&lt;&gt;)))&lt;br /&gt;     {&lt;br /&gt;          conversionType = new NullableConverter(conversionType).UnderlyingType;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     return (T)Convert.ChangeType(DecryptString(Convert.ToString(value)), conversionType);&lt;br /&gt;   }&lt;br /&gt;   catch &lt;br /&gt;   {&lt;br /&gt;    // Do nothing&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return defaultValue;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will allow the developer to set the property as normal but NHibernate will only access the Encrytped property.  The developer never has to worry about knowing which values are encrypted on the database.  And better yet, our encryption can all be done in code &amp; we can just delete those CLR UDFs if we don't need them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-5543626356666286042?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/5543626356666286042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=5543626356666286042' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/5543626356666286042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/5543626356666286042'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/08/fluent-nhibernate-encrypting-values.html' title='Fluent NHibernate + Encrypting Values'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-8320393994420643459</id><published>2009-07-31T14:52:00.000-07:00</published><updated>2009-08-08T12:02:36.398-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='localization'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Simple ASP.NET Localization</title><content type='html'>I've seen a lot of solutions for localization in ASP.NET -- many of which use a database to store the localized content.  The problem with this approach is that you have to recreate the tools that you are already using.  Specifically: text editors (now you need an admin site to update the database content), source control (now you need revision history), content uploading (now you need an SSIS or custom Windows Service to deploy content).  It's a bigger project than you want.&lt;br /&gt;&lt;br /&gt;Generally, whenever HTML goes into a database (apart from a Forum), I question the need.  The reason being that HTML is code and code belongs in Source Control.  If Developers are the only ones updating the content (we're &lt;strong&gt;not&lt;/strong&gt; talking about CMSs here) then why force them to use tools they aren't familiar with to do the same job they do all day long?&lt;br /&gt;&lt;br /&gt;A solution that I've found that works well is to use an HTTP Module and a Localized directory of files.  First, let's go over the HTTP Module.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Rewrites URLs to Custom Pages if they exist&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public class LocalizationModule : IHttpModule&lt;br /&gt;{&lt;br /&gt; public void Init(HttpApplication app)&lt;br /&gt; {&lt;br /&gt;  app.BeginRequest += OnBeginRequest;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void OnBeginRequest(object src, EventArgs e)&lt;br /&gt; {&lt;br /&gt;  // Replace the below with a way to determine culture however you'd like&lt;br /&gt;  string culture = SomeService.GetCulture();&lt;br /&gt;  if (String.IsNullOrEmpty(culture)) return;&lt;br /&gt;  &lt;br /&gt;  HttpApplication app = src as HttpApplication;&lt;br /&gt;  if (app == null) return;&lt;br /&gt;&lt;br /&gt;  string fullPath = app.Request.Path;&lt;br /&gt;  string possiblePath = app.Context.Server.MapPath("/" + ConfigurationManager.AppSettings["LocalizationDirectory"]) + "\\" + culture + fullPath.Replace("/", "\\");&lt;br /&gt;&lt;br /&gt;  if (File.Exists(possiblePath.ToLower()))&lt;br /&gt;  {&lt;br /&gt;   string virtualPath = "/" + ConfigurationManager.AppSettings["LocalizationDirectory"] + "/" + culture + fullPath;&lt;br /&gt;&lt;br /&gt;   app.Context.RewritePath(virtualPath);&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void Dispose()&lt;br /&gt; {&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The "SomeService.GetCulture()" can be anything.  I've made GetCulture return the culture code using Cookies (with a value of say "fr-FR"), the URL (i.e. "http://www.somesite.com/en-US/page.aspx") or even based on a drop down selection.&lt;br /&gt;&lt;br /&gt;The content of your site can live within a specified folder, see:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://kockerbeck.com/img/httpmodule_example.jpg" alt="Localization Module Example" /&gt;&lt;br /&gt;&lt;br /&gt;The HTTP module will then serve up the corresponding page in the localization directory.  &lt;br /&gt;&lt;br /&gt;Pretty simple stuff.  It's a LOT easier to manage than some database localization solutions.  I highly recommend using flat files for content that is only going to be touched by developers -- after all -- we're used to it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-8320393994420643459?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/8320393994420643459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=8320393994420643459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8320393994420643459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8320393994420643459'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/07/simple-aspnet-localization.html' title='Simple ASP.NET Localization'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-6124216507616144513</id><published>2009-07-27T10:20:00.000-07:00</published><updated>2009-08-21T09:50:25.015-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='repositories'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='checkout'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><category scheme='http://www.blogger.com/atom/ns#' term='source control'/><title type='text'>Unsvn - a way to un-checkout an svn repository</title><content type='html'>Sometimes other developers push up .svn directories to production.  This drives me nuts.  Not only does it create clutter but the directory contains sensitive information about where your SVN repository is located and who the user is.&lt;br /&gt;&lt;br /&gt;Removing these directories is a pain to do manually, so why bother?  The C# code below will remove all .svn directories &amp; all the files beneath them for any given path.  See the source below or just download the &lt;a href="http://www.kockerbeck.com/unsvn/binary/unsvn.zip"&gt;Windows Binary&lt;/a&gt;.&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace UnSvn&lt;br /&gt;{&lt;br /&gt; class Program&lt;br /&gt; {&lt;br /&gt;  static void Main(string[] args)&lt;br /&gt;  {&lt;br /&gt;   if (args == null || args.Length != 1)&lt;br /&gt;   {&lt;br /&gt;    Usage();&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   DirectoryInfo root = new DirectoryInfo(args[0]);&lt;br /&gt;   &lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;    if(!Process(root))&lt;br /&gt;    {&lt;br /&gt;     Console.WriteLine("Nothing to do");&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;   catch (Exception ex)&lt;br /&gt;   {&lt;br /&gt;    Console.WriteLine(ex.Message);&lt;br /&gt;    Console.WriteLine(ex.StackTrace);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static void Usage()&lt;br /&gt;  {&lt;br /&gt;   Console.WriteLine("usage: unsvn [/path/to/directory]");&lt;br /&gt;   Console.WriteLine("unsvn will remove all \".svn\" directories and files from the given path");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static bool Process(DirectoryInfo di)&lt;br /&gt;  {&lt;br /&gt;   bool removed = false;&lt;br /&gt;&lt;br /&gt;   if (String.Equals(di.Name, ".svn", StringComparison.OrdinalIgnoreCase))&lt;br /&gt;   {&lt;br /&gt;    SetNormal(di);&lt;br /&gt;    Console.WriteLine(String.Format("Removed: {0}", di.FullName));&lt;br /&gt;    Directory.Delete(di.FullName, true);&lt;br /&gt;    removed = true;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    foreach (DirectoryInfo di2 in di.GetDirectories())&lt;br /&gt;    {&lt;br /&gt;     removed = removed | Process(di2);&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return removed;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static void SetNormal(DirectoryInfo di)&lt;br /&gt;  {&lt;br /&gt;   foreach (FileInfo fi in di.GetFiles())&lt;br /&gt;   {&lt;br /&gt;    File.SetAttributes(fi.FullName, FileAttributes.Normal);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   foreach (DirectoryInfo di2 in di.GetDirectories())&lt;br /&gt;   {&lt;br /&gt;    SetNormal(di2);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And for those on Macs, below is a Python implementation (that has not been fully tested, but works well enough for me).&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;#!/usr/bin/python&lt;br /&gt;import os, sys&lt;br /&gt;&lt;br /&gt;def main():&lt;br /&gt;  if len(sys.argv) != 2: usage()&lt;br /&gt;  elif unsvn(sys.argv[1]) == False:&lt;br /&gt;    print "Nothing to do"&lt;br /&gt;  print&lt;br /&gt;&lt;br /&gt;def usage():&lt;br /&gt;    print "usage: unsvn [/path/to/directory]"&lt;br /&gt;    print "unsvn will remove all \".svn\" directories and files from the given path"&lt;br /&gt;&lt;br /&gt;def unsvn(path):&lt;br /&gt;  removed = False&lt;br /&gt;  for file in os.listdir(path):&lt;br /&gt;    subpath = os.path.join(path, file)&lt;br /&gt;    if file == ".svn":&lt;br /&gt;        removeDir(subpath)&lt;br /&gt;        removed = True&lt;br /&gt;        print "Removed: " + subpath&lt;br /&gt;    elif os.path.isdir(subpath):&lt;br /&gt;        removed = removed or unsvn(subpath)&lt;br /&gt;  return removed&lt;br /&gt;&lt;br /&gt;def removeDir(path):&lt;br /&gt;  if os.path.isdir(path) == False:&lt;br /&gt;    os.unlink(path)&lt;br /&gt;    return&lt;br /&gt;  for file in os.listdir(path):&lt;br /&gt;    removeDir(os.path.join(path, file))&lt;br /&gt;  os.rmdir(path)&lt;br /&gt;&lt;br /&gt;main()&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-6124216507616144513?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/6124216507616144513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=6124216507616144513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6124216507616144513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6124216507616144513'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/07/unsvn-way-to-un-checkout-svn-repository.html' title='Unsvn - a way to un-checkout an svn repository'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-6965933747743316068</id><published>2009-07-24T14:25:00.000-07:00</published><updated>2009-07-29T16:37:24.297-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax'/><title type='text'>Syntax Highlighting in Blogger -- with jQuery &amp; SyntaxHighlighter</title><content type='html'>There are a few reasons I decided to go with Blogger over other blogging options.  1) I want to spend time writing not setting things up, 2) BlogEngine.NET didn't seem to look right no matter what theme I used and I didn't like the admin and 3) Wordpress is all MySQL.&lt;br /&gt;&lt;br /&gt;That being said I wanted to get &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt; working.  After reading &lt;a href="http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html"&gt;Guogang Hu's post&lt;/a&gt; about how to get it working (&amp; not likely a lot of code), I decided to do it with jQuery.  The real issue with SyntaxHighligher and Blogger is the line breaks.  Posts have line breaks replaced by &amp;lt;br /&amp;gt; tags -- which SyntaxHighlighter will faithful display.&lt;br /&gt;&lt;br /&gt;Using the &lt;a href="http://docs.jquery.com/Manipulation/replaceWith#content"&gt;replaceWith&lt;/a&gt; method in jQuery makes this a snap.  Check out the code below.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;&amp;lt;link href='/syntaxhighlighter/styles/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' type='text/javascript'&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src='/syntaxhighlighter/scripts/shCore.js' type='text/javascript'&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src='/syntaxhighlighter/scripts/shBrushCSharp.js' type='text/javascript'&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src='/syntaxhighlighter/scripts/shBrushXml.js' type='text/javascript'&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src='/syntaxhighlighter/scripts/shBrushJScript.js' type='text/javascript'&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src='/syntaxhighlighter/scripts/shBrushSql.js' type='text/javascript'&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type='text/javascript'&amp;gt;&lt;br /&gt;$('pre br').replaceWith('\n');&lt;br /&gt;dp.SyntaxHighlighter.HighlightAll("code");&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-6965933747743316068?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/6965933747743316068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=6965933747743316068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6965933747743316068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6965933747743316068'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/07/syntax-highlighting-in-blogger-with.html' title='Syntax Highlighting in Blogger -- with jQuery &amp; SyntaxHighlighter'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-4110989512062358839</id><published>2009-07-22T12:47:00.000-07:00</published><updated>2009-07-29T16:37:41.641-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cookies'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Deleting Cookies (or Managing Cookie Domains) in ASP.NET</title><content type='html'>&lt;p&gt;I just spent a good few hours wrestling with writing authentication cookies in ASP.NET across different sub-domains.  I've done enough SSO installations to know how it should work &amp;amp; what the hiccups are.  Today I was reminded of a good lesson.  I was writing a Cookie out via Response.Cookies.Add() in 2 sites.  The problem was the second site was not overwriting the value from the first.  So I tried to delete the cookie.  I set the expiration to the past, I removed it from the collection, I tried using &lt;a href="http://plugins.jquery.com/project/Cookie"&gt;Klaus Hartl's jQuery plugin&lt;/a&gt;.  Nothing was deleting this cookie. &lt;/p&gt; &lt;p&gt;Then I realized what I was doing wrong -- I was setting the &lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;Domain &lt;/strong&gt;&lt;/span&gt;in the first instance but NOT in the second.  ASP.NET was using different domains in the cookie.  What I learned was that the more general, top-level domain was taking priority over the default domain.  &lt;br /&gt;&lt;br /&gt;Another issue to consider is the fact that Visual Studio 2008 and IIS will read the Cookie values different depending upon their Domain.  Let's say we set 3 cookies (with the same name, but different values) with 3 different domains: the top-level domain, a subdomain and the default domain.&lt;br /&gt;&lt;br /&gt;Or...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;&lt;br /&gt;HttpCookie tldCookie = new HttpCookie("Name", "TLD Value")&lt;br /&gt;{&lt;br /&gt; Domain = "topdomain.com"&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;HttpCookie subDomainCookie = new HttpCookie("Name", "Subdomain Value")&lt;br /&gt;{&lt;br /&gt; Domain = "subdomain.topdomain.com"&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;HttpCookie defaultCookie = new HttpCookie("Name", "Default (No-Domain) Value");&lt;br /&gt;&lt;br /&gt;Response.Cookies.Add(tldCookie);&lt;br /&gt;Response.Cookies.Add(subDomainCookie);&lt;br /&gt;Response.Cookies.Add(defaultCookie);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we read the "Name" cookie on another page using the ASP.NET Development Server -- what should the value be?&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;&lt;br /&gt;HttpCookie cookie = Request.Cookies["Name"];&lt;br /&gt;if (cookie == null) return;&lt;br /&gt;Response.Write(cookie.Value);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...this will write &lt;strong&gt;Default (No-Domain) Value&lt;/strong&gt; as the value while running locally.  If you run the &lt;u&gt;same page&lt;/u&gt; on subdomain.topdomain.com it will return &lt;strong&gt;TLD Value&lt;/strong&gt;.  &lt;br /&gt;&lt;br /&gt;Top-Level Domains will take precedence over other domains.  Moreover, the subdomain cookie will be there (if you use the WebDev toolbar + View Cookies); however, it is not readable within the &lt;strong&gt;Response.Cookies&lt;/strong&gt; collection.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-4110989512062358839?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/4110989512062358839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=4110989512062358839' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/4110989512062358839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/4110989512062358839'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/07/deleting-cookies-in-aspnet.html' title='Deleting Cookies (or Managing Cookie Domains) in ASP.NET'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-6551339511377541249</id><published>2009-04-04T15:53:00.000-07:00</published><updated>2009-07-29T16:38:10.855-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='t-sql'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Dynamic SQL Pivot with no Aggregate</title><content type='html'>Imagine a Survey database.  The layout of the database is meant to be reusable, DRY-conforming and fast.  Meaning it's not very user-friendly.  A data dump would be a PITA for any user to interpret.&lt;br /&gt;&lt;br /&gt;A database diagram is below.&lt;br /&gt;&lt;br /&gt;&lt;a class="fancy" href="#survey"&gt;&lt;img src="http://kockerbeck.com/img/survey_small.jpg" border="0" alt="Survey" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div id="survey" style="display:none;"&gt;&lt;br /&gt; &lt;img src="http://kockerbeck.com/img/survey.jpg" border="0" alt="Survey" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;One thing that I could not find out how to do online was how to write a PIVOT query &lt;strong&gt;without&lt;/strong&gt; using an aggregate function.  The reason is that you cannot.  You have to aggregate the data.  So the trick is to write your query with only one column of results being pivoted -- making the aggregate meaningless.&lt;br /&gt;&lt;br /&gt;Another issue I have with PIVOTs is that you need to know something about your DataSet in order to pivot it.  That is lame.  So the following TSQL query will get a list of all users, their answers to the survey &amp; the questions as columns.  It does this by &lt;strong&gt;building&lt;/strong&gt; the PIVOT statement in SQL and then executing it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;/*****************************************&lt;br /&gt;*&lt;br /&gt;* WARNING&lt;br /&gt;* If you receive the following error: &lt;br /&gt;* Msg 102, Level 15, State 1, Line 4 Incorrect syntax near '('.&lt;br /&gt;* THEN your database is NOT configured with SQL Server 2005 &lt;br /&gt;* Compatibility-Level and PIVOT is not recognized&lt;br /&gt;* &lt;br /&gt;******************************************/&lt;br /&gt;&lt;br /&gt;if object_id('tempdb..#pivotdata') is not null&lt;br /&gt;begin&lt;br /&gt; drop table #pivotdata&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;declare @questions table( id int identity(1,1), question varchar(500) )&lt;br /&gt;declare @i int&lt;br /&gt;declare @cmd varchar(8000)&lt;br /&gt;&lt;br /&gt;select&lt;br /&gt;u.Reference, u.Email, FirstName, Question, Answer&lt;br /&gt;into #pivotdata&lt;br /&gt;from surveyresult r&lt;br /&gt;join surveyuser u on u.[id] = r.surveyuserid&lt;br /&gt;join surveyanswer a on a.[id] = r.answerid &lt;br /&gt;join surveyquestion q on q.[id] = a.questionid &lt;br /&gt;order by FirstName&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;insert into @questions&lt;br /&gt;select distinct question from #pivotdata&lt;br /&gt;&lt;br /&gt;set @i = 1&lt;br /&gt;set @cmd = '&lt;br /&gt;   select *&lt;br /&gt;   from #pivotdata&lt;br /&gt;   pivot ( MAX(answer) FOR question IN &lt;br /&gt;   ('&lt;br /&gt;&lt;br /&gt;while @i &lt; (select max(id) from @questions) + 1&lt;br /&gt;begin&lt;br /&gt; set @cmd = @cmd + '[' + (select question from @questions where id = @i) + '],'&lt;br /&gt; set @i = @i + 1&lt;br /&gt;end&lt;br /&gt;set @cmd = substring(@cmd, 0, len(@cmd)) + ') ) as p order by email'&lt;br /&gt;&lt;br /&gt;execute(@cmd)&lt;br /&gt;&lt;br /&gt;if object_id('tempdb..#pivotdata') is not null&lt;br /&gt;begin&lt;br /&gt; drop table #pivotdata&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Keep in mind that in order for execute to read from your temp table it must be an on-disk temporary table.  No in-memory tables (like @questions) will work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-6551339511377541249?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/6551339511377541249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=6551339511377541249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6551339511377541249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/6551339511377541249'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2009/07/dynamic-sql-pivot-with-no-aggregate.html' title='Dynamic SQL Pivot with no Aggregate'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4498520272665916853.post-8441217241822891162</id><published>2008-04-19T01:23:00.000-07:00</published><updated>2008-04-19T01:27:27.720-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='new initial'/><title type='text'>The Wheel</title><content type='html'>Why reinvent the wheel?  There are so many tools out there that do things better than I can, so why not use them &amp;amp; spend my time on something original?  So, I'm just going to redirect my domain to my new blog.&lt;br /&gt;&lt;br /&gt;Also, thanks to 37signals for making Georgia the coolest font on the Internets.  I'm going to be sure to change my default in Outlook when I get back to work on Monday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4498520272665916853-8441217241822891162?l=kockerbeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kockerbeck.blogspot.com/feeds/8441217241822891162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4498520272665916853&amp;postID=8441217241822891162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8441217241822891162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4498520272665916853/posts/default/8441217241822891162'/><link rel='alternate' type='text/html' href='http://kockerbeck.blogspot.com/2008/04/wheel.html' title='The Wheel'/><author><name>Mark Kockerbeck</name><uri>http://www.blogger.com/profile/13920143895041002841</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
