<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Discord&amp;Rhyme</title><link>http://kohari.org</link><description>Rambling and occasional wisdom from Nate Kohari</description><lastBuildDate>Tue, 18 Aug 2009 02:08:19 +0000</lastBuildDate><generator>http://wordpress.org/?v=2.8.4</generator><language>en</language><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><geo:lat>40.961206</geo:lat><geo:long>-81.42516</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/discordandrhyme" type="application/rss+xml" /><feedburner:emailServiceId>discordandrhyme</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>A Few Lessons Learned</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/KK6svoiRzUs/</link><comments>http://kohari.org/2009/08/17/a-few-lessons-learned/#comments</comments><pubDate>Tue, 18 Aug 2009 02:08:19 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[Uncategorized]]></category><category><![CDATA[business]]></category><category><![CDATA[software]]></category><category><![CDATA[zen]]></category><guid isPermaLink="false">http://kohari.org/2009/08/17/a-few-lessons-learned/</guid><description><![CDATA[Running a business is nothing if not a learning experience. Every day presents a situation that you haven’t encountered before, and you have to be ready to shift your perspective and learn quickly in order to adapt. Here are a few tidbits of information that I’ve learned (sometimes the hard way) so far as we’ve [...]]]></description><content:encoded><![CDATA[<p></p><p>Running a business is nothing if not a learning experience. Every day presents a situation that you haven’t encountered before, and you have to be ready to shift your perspective and learn quickly in order to adapt. Here are a few tidbits of information that I’ve learned (sometimes the hard way) so far as we’ve been running <a href="http://agilezen.com/">Zen</a>.</p>
<h5>Save more information than you think you’ll need.</h5>
<p>Disk space is cheap, and it’s much more difficult to migrate (or generate) missing data after-the-fact than it is to collect it when something happens. At a minimum, you should have a transaction table that captures everything that happens in your system. That way, you can always use this table as a last resort to create new data if you need to in the future. Be sure to listen when your conscience says <a href="http://en.wikipedia.org/wiki/You_Ain't_Gonna_Need_It">YAGNI</a>, but <em>never trade off knowledge for extra disk space</em>. </p>
<h5>Soft-delete everything.</h5>
<p>Instead of actually deleting information from your database, just flag it with a “tombstone” and leave the record there. Not only does that allow you to recover data if a user accidentally deletes it, but maintaining the relationships between entities makes managing the data much simpler. Sure, you end up with stale data in your database, but you can always prune it after a certain period of time to clean things up – and since this pruning operation takes place out-of-band, if it doesn’t work perfectly your users aren’t bothered by it. </p>
<h5>Don’t underestimate the cost of meta-work.</h5>
<p>Not everything that is necessary is customer-facing, or even directly related to the product. I refer to work that’s important, but not quite value-adding, as <em>meta-work</em>. For example, one of the most complex parts of the Zen codebase is actually the billing system – customers don’t interact with it directly, but they would definitely be upset if Zen randomly billed their credit card! The most important parts of your product <em>are usually the parts that no one knows exist</em> – that is, until they don’t work the way they should. :) </p>
<h5>Don’t skimp on administrative software.</h5>
<p>Information is power, so make sure your system tells you when things happen. Write reporting and management screens. Make your software send you emails when things happen. Balance this against the previous point, but just because something isn’t customer-facing doesn’t make it wasteful – if an administrative screen or report helps you to serve your customers better, it adds real value. Don’t do too much up front; instead, wait until you recognize opportunities to improve your operations, and pick the low-hanging fruit. </p>
<p>Just a few random thoughts. :)</p>
<p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/4E028A9FE6FB25E4E858BA56025D3393D1C43B5C"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/4E028A9FE6FB25E4E858BA56025D3393D1C43B5C"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=KK6svoiRzUs:9s_PVlP983o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=KK6svoiRzUs:9s_PVlP983o:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/KK6svoiRzUs" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/08/17/a-few-lessons-learned/feed/</wfw:commentRss><slash:comments>4</slash:comments><feedburner:origLink>http://kohari.org/2009/08/17/a-few-lessons-learned/</feedburner:origLink></item><item><title>Open Source is not a Zero-Sum Game</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/cKrrWXUqdR8/</link><comments>http://kohari.org/2009/08/10/open-source-is-not-a-zero-sum-game/#comments</comments><pubDate>Tue, 11 Aug 2009 03:44:11 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[Uncategorized]]></category><category><![CDATA[open source]]></category><category><![CDATA[siesta]]></category><category><![CDATA[software]]></category><guid isPermaLink="false">http://kohari.org/2009/08/10/open-source-is-not-a-zero-sum-game/</guid><description><![CDATA[
I had originally left off the name of the person I was talking about because this post isn&#8217;t intended to make him sound like a bad guy. However, he felt I wasn&#8217;t being conversational, so the person that triggered this post is Sebastien Lambla, author of OpenRasta. Read his response here.

I caught some flak on [...]


Related posts:<ol><li><a href='http://kohari.org/2007/09/02/microsoft-supports-open-source-software/' rel='bookmark' title='Permanent Link: Microsoft Supports Open-Source Software'>Microsoft Supports Open-Source Software</a></li><li><a href='http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/' rel='bookmark' title='Permanent Link: Siesta: Painless REST via ASP.NET MVC'>Siesta: Painless REST via ASP.NET MVC</a></li><li><a href='http://kohari.org/2007/02/08/open-source-and-passionate-developers/' rel='bookmark' title='Permanent Link: Open Source, and Passionate Developers'>Open Source, and Passionate Developers</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p class="alert">
I had originally left off the name of the person I was talking about because this post isn&#8217;t intended to make him sound like a bad guy. However, he felt I wasn&#8217;t being conversational, so the person that triggered this post is <a href="http://serialseb.blogspot.com/" target="_blank">Sebastien Lambla</a>, author of <a href="http://trac.caffeine-it.com/openrasta" target="_blank">OpenRasta</a>. Read his response <a href="http://serialseb.blogspot.com/2009/08/open-source-nih-and-meaning-of.html">here</a>.
</p>
<p>I caught some flak on Twitter today for releasing <a href="http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/">Siesta</a> as open source. It was the same song that I heard when I wrote <a href="http://ninject.org/" target="_blank">Ninject</a>, which was: <em>why are you reinventing the wheel</em>? Normally I shake that sort of thing off, but once I found out that the person complaining was the author of a “competing” REST framework, it ruffled my feathers a little bit.</p>
<p>Siesta originated as part of <a href="http://agilezen.com/" target="_blank">Zen</a>. Implementing REST is not a difficult problem, and I’ve done it before. (Most of the difficulty is in mapping HTTP requests to method calls, which ASP.NET MVC handles for you.) Since I knew exactly how I wanted it to work, and had a reasonable idea of how to implement it myself, I just sat down and wrote it.</p>
<p>Could I have used an existing open-source framework? Sure, but I’d never heard of any other than WCF REST, which I already knew didn’t match my mindset. I searched for a little while on Google to find other libraries, but didn’t find anything. I’d also argue that REST is so low-level that it would be very difficult to come up with a clean drop-in solution – that’s why I suggested that Siesta is more an example of how to write a REST system than it is a reusable framework.</p>
<p>I believe very strongly in not falling prey to the <a href="http://en.wikipedia.org/wiki/Not_Invented_Here" target="_blank">Not Invented Here</a> syndrome. Like I said in my previous post, Zen uses a myriad of open source libraries:</p>
<ul>
<li><a href="http://www.codeplex.com/Argotic" target="_blank">Argotic</a> </li>
<li><a href="http://www.castleproject.org/dynamicproxy/index.html" target="_blank">DynamicProxy</a> </li>
<li><a href="http://code.google.com/p/elmah/" target="_blank">ELMAH</a> </li>
<li><a href="http://fluentnhibernate.org/" target="_blank">Fluent NHibernate</a> </li>
<li><a href="http://www.codeplex.com/LinqToTwitter" target="_blank">LinqToTwitter</a> </li>
<li><a href="http://logging.apache.org/log4net/index.html" target="_blank">log4net</a> </li>
<li><a href="http://code.google.com/p/jabber-net/" target="_blank">jabber-net</a> </li>
<li><a href="http://www.codeplex.com/Json" target="_blank">JSON.NET</a> </li>
<li><a href="http://aspnetresources.com/blog/markdown_announced.aspx" target="_blank">Markdown.NET</a> </li>
<li><a href="http://code.google.com/p/migratordotnet/" target="_blank">Migrator.NET</a> </li>
<li><a href="http://code.google.com/p/moq/" target="_blank">Moq</a> </li>
<li><a href="http://nhforge.org/" target="_blank">NHibernate</a> </li>
<li><a href="http://ninject.org/" target="_blank">Ninject</a> </li>
<li><a href="http://nunit.org/index.php" target="_blank">NUnit</a> </li>
<li><a href="http://quartznet.sourceforge.net/" target="_blank">Quartz.NET</a> </li>
<li><a href="http://sparkviewengine.com/" target="_blank">Spark</a> </li>
</ul>
<p>I’m all about standing on the shoulders of giants. :) However, <em>rolling your own is not always waste</em>. The bits that became Siesta took me about a total of 4-5 hours to implement end-to-end. That’s <em>much</em> less time than it would have taken me to find a framework, understand how to use it, evaluate whether it would work for what I needed, and integrate it into Zen.</p>
<p>Like I said, I’ve written several RESTful systems before, using MonoRail and raw <code>IHttpHandler</code>s – but none of them belonged to me, so I couldn’t open source them. Because I already understood the problem well, it was actually <em>less expensive</em> for me to write my own implementation.</p>
<p>As the owner of a startup, I have to justify the value of <em>everything</em> that I do to ensure that I’ll get a decent return on investment. In order for me to consider using an external framework, I have to be relatively certain that I’ll save time by using it in the long term. This leads me to my point:</p>
<p><strong>It’s not my fault if I don’t know about your product. It’s <em>your</em> fault.</strong></p>
<p>If you don’t market your product well enough for me to know about it, and I can’t even find it <em>when I’m looking for it</em>, it’s never going to get on my radar. It doesn’t matter if your product is free and open source or costs thousands – if I even don’t know it exists, how in the world am I supposed to make the difficult decision to <em>use</em> it?</p>
<p>That’s my first problem with the complaints about Siesta. My second problem is this: I spent my time and money to develop the part of Zen that became Siesta, and because other people have previously asked me for help on the topic, I’m happy to share it with anyone that’s interested, free of charge.</p>
<p><strong>It’s my code, and I’ll do what I damn well please with it.</strong></p>
<p>I haven’t always thought this way, but these days I don’t care much about mindshare or competition in the open source space. I spend enough time competing on my commercial endeavors, which have the distinction of putting food on my table. Open source is something I do because I want to help.</p>
<p>Siesta’s not perfect and it’s not the only solution, but it represents the way I think a REST system should be implemented. If you don’t like it, don’t use it. Even better, tell me what you don’t like about it so I can learn from your perspective just as you can learn from mine.</p>
<p>The goal of open source is not to develop a single solution that can be used in all situations. In fact, it’s the opposite: <em>open source thrives on competition</em>. If you feel threatened because someone else releases something that you perceive as competition, maybe you should rethink why you’re working on open source in the first place.</p>


<p>Related posts:<ol><li><a href='http://kohari.org/2007/09/02/microsoft-supports-open-source-software/' rel='bookmark' title='Permanent Link: Microsoft Supports Open-Source Software'>Microsoft Supports Open-Source Software</a></li><li><a href='http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/' rel='bookmark' title='Permanent Link: Siesta: Painless REST via ASP.NET MVC'>Siesta: Painless REST via ASP.NET MVC</a></li><li><a href='http://kohari.org/2007/02/08/open-source-and-passionate-developers/' rel='bookmark' title='Permanent Link: Open Source, and Passionate Developers'>Open Source, and Passionate Developers</a></li></ol></p><p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/D2D303E0F4588DD960540E70AF712E1AE299499F"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/D2D303E0F4588DD960540E70AF712E1AE299499F"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=cKrrWXUqdR8:dGeUdc7d8tM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=cKrrWXUqdR8:dGeUdc7d8tM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/cKrrWXUqdR8" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/08/10/open-source-is-not-a-zero-sum-game/feed/</wfw:commentRss><slash:comments>10</slash:comments><feedburner:origLink>http://kohari.org/2009/08/10/open-source-is-not-a-zero-sum-game/</feedburner:origLink></item><item><title>Siesta: Painless REST via ASP.NET MVC</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/mdzNmJXuLMg/</link><comments>http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/#comments</comments><pubDate>Mon, 10 Aug 2009 21:26:40 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[Uncategorized]]></category><category><![CDATA[open source]]></category><category><![CDATA[siesta]]></category><category><![CDATA[software]]></category><guid isPermaLink="false">http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/</guid><description><![CDATA[Zen uses quite a few open source libraries, and I feel a sense of responsibility to contribute back where I can. To that end, I’m releasing the basic infrastructure that powers the Zen API under the name Siesta.
Siesta is a simple and flexible REST system driven by ASP.NET MVC. While you can take the Siesta [...]


Related posts:<ol><li><a href='http://kohari.org/2007/08/23/functional-magic/' rel='bookmark' title='Permanent Link: Functional Magic'>Functional Magic</a></li><li><a href='http://kohari.org/2009/08/10/open-source-is-not-a-zero-sum-game/' rel='bookmark' title='Permanent Link: Open Source is not a Zero-Sum Game'>Open Source is not a Zero-Sum Game</a></li><li><a href='http://kohari.org/2008/04/01/frameworks-and-the-break-even-point/' rel='bookmark' title='Permanent Link: Frameworks and the Break-Even Point'>Frameworks and the Break-Even Point</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p><a href="http://agilezen.com/">Zen</a> uses quite a few open source libraries, and I feel a sense of responsibility to contribute back where I can. To that end, I’m releasing the basic infrastructure that powers the Zen API under the name <a href="http://github.com/enkari/siesta/tree/master">Siesta</a>.</p>
<p>Siesta is a simple and flexible <a href="http://en.wikipedia.org/wiki/REST">REST</a> system driven by ASP.NET MVC. While you can take the Siesta bits and use them directly in your app, it’s intended more as an example of how to implement your own system.</p>
<p>The basic idea behind Siesta is to communicate only using models within your application, and allow the infrastructure to handle the serialization and de-serialization, similar to how a view engine manipulates <code>ViewModels</code> or <code>ViewData</code>. Models are just POCOs, and serialization is controlled the <code>[DataContract]</code> and <code>[DataMember]</code> attributes in <code>System.Runtime.Serialization</code> (so yes, this requires .NET 3.5).</p>
<p>Siesta also uses the (sweet-with-extra-awesomesauce) <a href="http://www.codeplex.com/Json">JSON.NET</a> library from <a href="http://james.newtonking.com/">James Newton-King</a>. There’s a <code>DataContractJsonSerializer</code> in the BCL now, but as far as I could tell, it doesn’t support indentation. JSON.NET supports both, so it’s a great fit. I’ve also been using it forever, so I’m just used to it – if you deal with JSON formatting, it’s definitely worth a look.</p>
<p>The wire (serialization) format is based on MIME types, and Siesta comes with XML and JSON built-in. However, it’s also extensible by implementing a new <code>IModelSerializer</code>. Speaking of which, if someone wants to implement one for YAML, it would be greatly appreciated. ;)</p>
<p>As described in the <a href="http://learn.agilezen.com/api/concepts/formatting">Zen API documentation</a>, the wire format is determined by the <code>Content-Type</code> and <code>Accept</code> headers. <code>Content-Type</code> is preferred for incoming data, and <code>Accept</code> is preferred for outgoing data. If a header is missing, the system will fail over to the other one.</p>
<p>Here&#8217;s an example of an entity that can be serialized via REST:</p>
<pre class="csharp" name="code">[DataContract(Name = &quot;user&quot;, Namespace = &quot;&quot;)]
public class User : IEntity
{
  [DataMember(Name = &quot;id&quot;)]
  public int Id { get; set; }

  [DataMember(Name = &quot;username&quot;)]
  public string UserName { get; set; }

  [DataMember(Name = &quot;name&quot;)]
  public string Name { get; set; }

  [DataMember(Name = &quot;email&quot;)]
  public string Email { get; set; }
}</pre>
<p>And its matching controller:</p>
<pre class="csharp" name="code">public class UserController : SiestaControllerBase
{
  public IRepository&lt;User&gt; UserRepository { get; private set; }

  public UserController(IRepository&lt;User&gt; userRepository)
  {
    UserRepository = userRepository;
  }

  public ModelResult&lt;User&gt; Get(GetRequest request)
  {
    User user = UserRepository.Get(request.Id);

    if (user == null)
      throw NotFound();

    return Model(user, request.Formatting);
  }

  //...
}</pre>
<p>Don&#8217;t worry, <code>SiestaControllerBase</code> is just a simple base controller which provides the <code>Model()</code> method shortcut. This (and the <code>IEntity</code> interface you might have noticed on <code>User</code>) are entirely optional, and are actually part of the <code>Siesta.Example</code> assembly rather than the main <code>Siesta</code> assembly. As long as the types you want to communicate with are serializable, they&#8217;ll work with Siesta.</p>
<p>In contrast to the Siesta example, in Zen, we actually have separate models (which act as <a href="http://en.wikipedia.org/wiki/Data_Transfer_Object">DTOs</a>, and are serialized to/from a wire format) and entities (which are persisted to the database). The example doesn’t show this because it requires a whole separate mapping step, which can get tricky. I would highly recommend that if you use this in a real-world app, you create a separate type hierarchy and map between them.</p>
<p>Anyhow, you can grab the Siesta bits on <a href="http://github.com/enkari/siesta/tree/master">GitHub</a>, including the full version of this (simple) example. If you have feedback, by all means let me know! There’s actually quite a bit of stuff in Zen that I’d like to release as OSS – it’s just a matter of getting the time to split the code off the product and wrap it up.</p>


<p>Related posts:<ol><li><a href='http://kohari.org/2007/08/23/functional-magic/' rel='bookmark' title='Permanent Link: Functional Magic'>Functional Magic</a></li><li><a href='http://kohari.org/2009/08/10/open-source-is-not-a-zero-sum-game/' rel='bookmark' title='Permanent Link: Open Source is not a Zero-Sum Game'>Open Source is not a Zero-Sum Game</a></li><li><a href='http://kohari.org/2008/04/01/frameworks-and-the-break-even-point/' rel='bookmark' title='Permanent Link: Frameworks and the Break-Even Point'>Frameworks and the Break-Even Point</a></li></ol></p><p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/B52986888B47F66615EA2A7948AE872C1C19ED78"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/B52986888B47F66615EA2A7948AE872C1C19ED78"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=mdzNmJXuLMg:-W9qaUlt9F0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=mdzNmJXuLMg:-W9qaUlt9F0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/mdzNmJXuLMg" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/feed/</wfw:commentRss><slash:comments>18</slash:comments><feedburner:origLink>http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/</feedburner:origLink></item><item><title>Beginning ASP.NET MVC 1.0</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/jLSkd0fM4dY/</link><comments>http://kohari.org/2009/08/07/beginning-asp-net-mvc-1-0/#comments</comments><pubDate>Fri, 07 Aug 2009 16:18:29 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://kohari.org/2009/08/07/beginning-asp-net-mvc-1-0/</guid><description><![CDATA[Earlier this week, the UPS delivery guy surprised me with a copy of Beginning ASP.NET MVC 1.0 by Simone Chiaretta and Keyvan Nayyeri. I haven’t had a chance to read much more than just a brief skim of it so far, but I had an opportunity to review some of the content before it was [...]


Related posts:<ol><li><a href='http://kohari.org/2009/08/06/reboot/' rel='bookmark' title='Permanent Link: Reboot!'>Reboot!</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">E</span>arlier this week, the UPS delivery guy surprised me with a copy of <a href="http://www.amazon.com/gp/product/047043399X?ie=UTF8&amp;tag=kohariorg-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=047043399X">Beginning ASP.NET MVC 1.0</a> by <a href="http://codeclimber.net.nz/">Simone Chiaretta</a> and <a href="http://nayyeri.net/">Keyvan Nayyeri</a>. I haven’t had a chance to read much more than just a brief skim of it so far, but I had an opportunity to review some of the content before it was published. What I’ve seen looks great, and I don’t just say that because it talks about Ninject. ;) I plan to dig into it further when I can scrounge a few minutes.</p>
<p>Congratulations to Simone and Keyvan for finishing the book and getting it published! It looks like a great resource for aspiring ASP.NET MVC developers.</p>
<p>If you want to learn more, you can check out <a href="http://codeclimber.net.nz/archive/2009/08/05/beginning-asp.net-mvc-1.0-available-on-amazon.aspx">Simone</a> and <a href="http://nayyeri.net/blog/beginning-asp-net-mvc-1-0-ndash-finally-available/">Keyvan</a>’s posts.</p>


<p>Related posts:<ol><li><a href='http://kohari.org/2009/08/06/reboot/' rel='bookmark' title='Permanent Link: Reboot!'>Reboot!</a></li></ol></p><p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/C3CB856BC925214ACB7B456B4CD2F984C55573E6"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/C3CB856BC925214ACB7B456B4CD2F984C55573E6"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=jLSkd0fM4dY:3jXCjvG_GPs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=jLSkd0fM4dY:3jXCjvG_GPs:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/jLSkd0fM4dY" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/08/07/beginning-asp-net-mvc-1-0/feed/</wfw:commentRss><slash:comments>4</slash:comments><feedburner:origLink>http://kohari.org/2009/08/07/beginning-asp-net-mvc-1-0/</feedburner:origLink></item><item><title>The Media Blitz Continues</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/Kae3Ro2f9WA/</link><comments>http://kohari.org/2009/08/06/the-media-blitz-continues/#comments</comments><pubDate>Fri, 07 Aug 2009 03:48:53 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[Uncategorized]]></category><category><![CDATA[kanban]]></category><category><![CDATA[lean]]></category><category><![CDATA[podcast]]></category><category><![CDATA[zen]]></category><guid isPermaLink="false">http://kohari.org/2009/08/06/the-media-blitz-continues/</guid><description><![CDATA[In addition to working hard to improve Zen, I’ve also been talking about it to anyone that will listen. :) I’ve been fortunate enough to be featured on a few podcasts over the past few weeks to discuss lean, kanban, and Zen:
First, Scott Hanselman had me on Hanselminutes in mid-July. This conversation was a quick [...]


Related posts:<ol><li><a href='http://kohari.org/2009/07/11/hanselminutes/' rel='bookmark' title='Permanent Link: Hanselminutes'>Hanselminutes</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">I</span>n addition to working hard to improve <a href="http://agilezen.com/">Zen</a>, I’ve also been talking about it to anyone that will listen. :) I’ve been fortunate enough to be featured on a few podcasts over the past few weeks to discuss lean, kanban, and Zen:</p>
<p>First, <a href="http://hanselman.com/">Scott Hanselman</a> had me on <a href="http://hanselminutes.com/default.aspx?showID=188">Hanselminutes</a> in mid-July. This conversation was a quick introduction about lean and kanban, with a few tidbits about Zen sprinkled in. I already <a href="http://kohari.org/2009/07/11/hanselminutes/">mentioned</a> this before, but the post was a 30-second-hurry-up-and-publish-and-then-get-back-to-grinding-out-code, so I figured I’d do it a bit more justice. :)</p>
<p>Then, the guys at <a href="http://herdingcode.com/?p=203">Herding Code</a> had me on to talk about the technology behind Zen, and the process of launching a company. This turned into a great conversation, although I wasn’t quite lucid by the end. (I’m not sure you can tell by listening, but I’d put in 16 hours that day and by the end of recording, it was 1:30AM EST!)</p>
<p>Last, but certainly not least, I was featured on <a href="http://www.dotnetrocks.com/default.aspx?showNum=470">.NET Rocks</a>, where I talked with Carl and Richard about the idea behind Zen and my best understanding of lean and kanban. This was the first time I was on .NET Rocks, and I think it turned into a great conversation.</p>
<p>That’s all the podcasts that I’ve recorded so far, and without something new to talk about, I’m not sure I want to do too many more. I’m sure the audiences of the podcasts overlap, and by now I <em>must</em> be starting to annoy people. If so, sorry about that! :)</p>
<p>Anyhow, a huge thanks to the hosts of the podcasts, and everyone that listened. I’m obviously excited about this stuff, and I hope after listening to me ramble, others get excited about it too.</p>


<p>Related posts:<ol><li><a href='http://kohari.org/2009/07/11/hanselminutes/' rel='bookmark' title='Permanent Link: Hanselminutes'>Hanselminutes</a></li></ol></p><p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/DCEEA4EC61C761C128D5E5BC1D68588EDB3C2A5F"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/DCEEA4EC61C761C128D5E5BC1D68588EDB3C2A5F"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=Kae3Ro2f9WA:BVfrm_YvXIY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=Kae3Ro2f9WA:BVfrm_YvXIY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/Kae3Ro2f9WA" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/08/06/the-media-blitz-continues/feed/</wfw:commentRss><slash:comments>4</slash:comments><feedburner:origLink>http://kohari.org/2009/08/06/the-media-blitz-continues/</feedburner:origLink></item><item><title>Reboot!</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/J-m3OAk9zCg/</link><comments>http://kohari.org/2009/08/06/reboot/#comments</comments><pubDate>Fri, 07 Aug 2009 02:58:46 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[Uncategorized]]></category><category><![CDATA[meta]]></category><guid isPermaLink="false">http://kohari.org/2009/08/06/reboot/</guid><description><![CDATA[As you’ve probably noticed (well, unless you’re reading the RSS feed), I’ve rebooted my blog. It was a long time coming, really. I’ve always preferred clean user interfaces and good user experience, and well, the old design didn’t quite fit the bill. :) I’ve been wanting to fix things up for a long time, but [...]]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">A</span>s you’ve probably noticed (well, unless you’re reading the RSS feed), I’ve rebooted my blog. It was a long time coming, really. I’ve always preferred clean user interfaces and good user experience, and well, the old design didn’t quite fit the bill. :) I’ve been wanting to fix things up for a long time, but I could never quite get it to a high enough priority.</p>
<p>Today, I was finally able to scrounge some time to clean up old posts and customize a new theme. This involved going back and ripping out the crappy HTML generated by whatever code snippet plugin I was using for Windows Live Writer back in 2007…ugh. Going back through my old posts was sort of like going through a bizarro time machine. It’s amazing how much my mindset has shifted since I first started blogging.</p>
<p>So, what do you think of the new look? There’s still some things that need tweaked here and there, but overall I’m really liking it. Let me know if you see anything off kilter.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=J-m3OAk9zCg:_PgZT0ehIw4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=J-m3OAk9zCg:_PgZT0ehIw4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/J-m3OAk9zCg" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/08/06/reboot/feed/</wfw:commentRss><slash:comments>2</slash:comments><feedburner:origLink>http://kohari.org/2009/08/06/reboot/</feedburner:origLink></item><item><title>Hanselminutes</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/UPiQ1gFtv6o/</link><comments>http://kohari.org/2009/07/11/hanselminutes/#comments</comments><pubDate>Sat, 11 Jul 2009 13:19:23 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[miscellaneous]]></category><guid isPermaLink="false">http://kohari.org/2009/07/11/hanselminutes/</guid><description><![CDATA[In case you missed it yesterday, Scott Hanselman was nice enough to have me on Hanselminutes to talk about lean, kanban, and Zen. I think it turned into a pretty good conversation, so go have a listen!


Related posts:The Media Blitz Continues


Related posts:<ol><li><a href='http://kohari.org/2009/08/06/the-media-blitz-continues/' rel='bookmark' title='Permanent Link: The Media Blitz Continues'>The Media Blitz Continues</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">I</span>n case you missed it yesterday, <a href="http://hanselman.com/" target="_blank">Scott Hanselman</a> was nice enough to have me on <a href="http://hanselminutes.com/default.aspx?showID=188" target="_blank">Hanselminutes</a> to talk about lean, kanban, and <a href="http://agilezen.com/" target="_blank">Zen</a>. I think it turned into a pretty good conversation, so go have a listen!</p>


<p>Related posts:<ol><li><a href='http://kohari.org/2009/08/06/the-media-blitz-continues/' rel='bookmark' title='Permanent Link: The Media Blitz Continues'>The Media Blitz Continues</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=UPiQ1gFtv6o:ERGzvD-XSuQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=UPiQ1gFtv6o:ERGzvD-XSuQ:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/UPiQ1gFtv6o" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/07/11/hanselminutes/feed/</wfw:commentRss><slash:comments>3</slash:comments><feedburner:origLink>http://kohari.org/2009/07/11/hanselminutes/</feedburner:origLink></item><item><title>Zen is Live!</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/J0dnDgOLe90/</link><comments>http://kohari.org/2009/07/07/zen-is-live/#comments</comments><pubDate>Tue, 07 Jul 2009 14:46:07 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[miscellaneous]]></category><guid isPermaLink="false">http://kohari.org/2009/07/07/zen-is-live/</guid><description><![CDATA[It’s been about a year since the ideas for Zen started to gel in my mind. After more long nights and working weekends than I can count, I’m proud to announce that Zen is open to the public! I’d like to thank everyone for their support, especially those that tinkered with the product during the [...]]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">I</span>t’s been about a year since the ideas for <a href="http://agilezen.com/">Zen</a> started to gel in my mind. After more long nights and working weekends than I can count, I’m proud to announce that Zen is open to the public! I’d like to thank everyone for their support, especially those that tinkered with the product during the beta process – your feedback was absolutely invaluable.</p>
<p>I’d also like to extend a special thanks to <a href="http://averyblog.com/" target="_blank">James Avery</a>, <a href="http://mjeaton.net/blog/" target="_blank">Mike Eaton</a>, <a href="http://twitter.com/jaymed" target="_blank">Jayme Davis</a>, and <a href="http://www.lostechies.com/blogs/sean_chambers/" target="_blank">Sean Chambers</a>. They not only used the application since the days of the first alpha, but also through their constant heckling, convinced me to work on it in the first place, and helped me <a href="http://averageisforlosers.com/" target="_blank">through the dip</a> to get the product to launch.</p>
<p>Finally, I’d like to thank my beautiful and brilliant wife, <a href="http://nikibeth.com/">Nicole</a>, for signing up to ride this rollercoaster with me. I couldn’t do it without you.</p>
<p>So what are you waiting for? Go <a href="http://agilezen.com/signup">sign up</a> for Zen! :)</p>
<p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/B9BBEC479F94A33557B9C07BAE86448E9AE737DE"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/B9BBEC479F94A33557B9C07BAE86448E9AE737DE"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=J0dnDgOLe90:w4psWXGb9_8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=J0dnDgOLe90:w4psWXGb9_8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/J0dnDgOLe90" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/07/07/zen-is-live/feed/</wfw:commentRss><slash:comments>13</slash:comments><feedburner:origLink>http://kohari.org/2009/07/07/zen-is-live/</feedburner:origLink></item><item><title>Microsoft Finally Realizes I’m Awesome</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/ZKgoltlis8M/</link><comments>http://kohari.org/2009/07/04/microsoft-finally-realizes-im-awesome/#comments</comments><pubDate>Sat, 04 Jul 2009 16:03:05 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[miscellaneous]]></category><guid isPermaLink="false">http://kohari.org/2009/07/04/microsoft-finally-realizes-im-awesome/</guid><description><![CDATA[July 1st came with a great surprise, as I was named a Microsoft C# MVP for 2009! If you’re not familiar with the award, here’s a blurb from their website:

Microsoft Most Valuable Professionals (MVPs) are exceptional technical community leaders from around the world who are awarded for voluntarily sharing their high quality, real world expertise [...]


Related posts:<ol><li><a href='http://kohari.org/2007/09/02/microsoft-supports-open-source-software/' rel='bookmark' title='Permanent Link: Microsoft Supports Open-Source Software'>Microsoft Supports Open-Source Software</a></li><li><a href='http://kohari.org/2007/07/23/ironruby-and-a-paradigm-shift-at-microsoft/' rel='bookmark' title='Permanent Link: IronRuby and a Paradigm Shift at Microsoft'>IronRuby and a Paradigm Shift at Microsoft</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">J</span>uly 1st came with a great surprise, as I was named a <a href="http://mvp.support.microsoft.com/">Microsoft C# MVP</a> for 2009! If you’re not familiar with the award, here’s a blurb from their website:</p>
<blockquote><p>
Microsoft Most Valuable Professionals (MVPs) are exceptional technical community leaders from around the world who are awarded for voluntarily sharing their high quality, real world expertise in offline and online technical communities. Microsoft MVPs are a highly select group of experts that represents the technical community’s best and brightest, and they share a deep commitment to community and a willingness to help others.
</p></blockquote>
<p><a href="http://mvp.support.microsoft.com/"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="Microsoft MVP" border="0" alt="Microsoft MVP" src="http://kohari.org/wp-content/uploads/2009/07/microsoftmvp.png" width="148" height="60" /></a></p>
<p>Although it’s overshadowed a bit by my excitement about the imminent launch of <a href="http://agilezen.com/">Zen</a>, I’m thrilled to receive the award. Thank you to all the existing MVPs that nominated me, and congratulations to those who were renewed and other freshman MVPs, including <a href="http://mjeaton.net/blog/">Mike Eaton</a>, <a href="http://riathoughts.com/">John Stockton</a>, and <a href="http://codinggeekette.com/">Sarah Dutkiewicz</a>.</p>
<p><em>(And yes, the title is a joke. Totally kidding.)</em></p>


<p>Related posts:<ol><li><a href='http://kohari.org/2007/09/02/microsoft-supports-open-source-software/' rel='bookmark' title='Permanent Link: Microsoft Supports Open-Source Software'>Microsoft Supports Open-Source Software</a></li><li><a href='http://kohari.org/2007/07/23/ironruby-and-a-paradigm-shift-at-microsoft/' rel='bookmark' title='Permanent Link: IronRuby and a Paradigm Shift at Microsoft'>IronRuby and a Paradigm Shift at Microsoft</a></li></ol></p><p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/F5A304B73DEB40580C0458D8C5DCD009B44F3A07"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/F5A304B73DEB40580C0458D8C5DCD009B44F3A07"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=ZKgoltlis8M:-bZd8krP614:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=ZKgoltlis8M:-bZd8krP614:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/ZKgoltlis8M" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/07/04/microsoft-finally-realizes-im-awesome/feed/</wfw:commentRss><slash:comments>5</slash:comments><feedburner:origLink>http://kohari.org/2009/07/04/microsoft-finally-realizes-im-awesome/</feedburner:origLink></item><item><title>Automagic Time Localization</title><link>http://feedproxy.google.com/~r/discordandrhyme/~3/SDoBATmWnvk/</link><comments>http://kohari.org/2009/06/15/automagic-time-localization/#comments</comments><pubDate>Mon, 15 Jun 2009 15:54:50 +0000</pubDate><dc:creator>Nate</dc:creator><category><![CDATA[miscellaneous]]></category><guid isPermaLink="false">http://kohari.org/2009/06/15/automagic-time-localization/</guid><description><![CDATA[One of the most often-overlooked and easy to fix things encountered when developing a hosted software application is the management of local time. First and foremost, you should be storing timestamps in your database in UTC. I don’t care if your users are all in the same time zone now, or your app is just [...]


Related posts:<ol><li><a href='http://kohari.org/2007/09/06/functional-programming-and-database-access/' rel='bookmark' title='Permanent Link: Functional Programming and Database Access'>Functional Programming and Database Access</a></li></ol>]]></description><content:encoded><![CDATA[<p></p><p><span class="drop_cap">O</span>ne of the most often-overlooked and easy to fix things encountered when developing a hosted software application is the management of local time. First and foremost, you should be storing timestamps in your database in UTC. I don’t care if your users are all in the same time zone now, or your app is just a local deployment, or whatever other excuse you have for storing time as local time.<strong> <em>Always store timestamps in UTC.</em></strong> Do it now, and pat yourself on the back a year from now when you realize whatever reason you had for storing it as local time was irrelevant or has changed. :)</p>
<p>Okay, so once you’ve got your timestamps stored in UTC, you need to localize them for each individual user, which means you need their offset from UTC. For example, Eastern Standard Time, my time zone, is UTC-5. The most common thing that I’ve seen is to provide users with a massive dropdown of a bajillion time zones, and ask them to pick which one they’re in.</p>
<p>Maybe it’s just a pet peeve, but I <em>hate</em> it when sites ask me to pick my time zone. What about users who travel often? What about daylight savings time? Do I make my users go in and change their time zones when DST starts and stops? Do I write extra code to figure out if it’s DST in the user’s time zone? That’s pretty much impossible, at least in the US, because it’s not recognized in Hawaii, Arizona (except in the Navajo Nation), and some counties in middle America.</p>
<p>While I was building <a href="http://agilezen.com/" target="_blank">Zen</a>, I was determined to avoid making users have to choose their time zone if I could avoid it. I realized that the client computer knows what time it is, and what time zone they’re in, so it’s pretty simple to read it with Javascript. Here’s how you can grab the client computer’s UTC offset:</p>
<pre>
new Date().getTimezoneOffset() / -60
</pre>
<p>Now, all that remains is to push that information back to the server and make sure that it’s updated often. Zen’s login form has a hidden input called <code>timezoneOffset</code>, which is set using jQuery when the page is displayed:</p>
<pre>
$(document).ready(function() {
  $("#timezoneOffset").val(new Date().getTimezoneOffset() / -60);
});
</pre>
<p>Now, when the form is posted, I read the UTC offset from the hidden input, and store it in the user’s record in the database. This means that each time the user logs in, their time zone information is updated to be current. This helps not only with the daylight savings time problem, but also ensures that Zen will respond to changes in the user’s computer clock. If a user travels from EST to PST, for example, and they change their computer clock, Zen will recognize the change and update the timestamps appropriately.</p>
<p>Then, each time I need to display a timestamp to a user, I call a method on my <code>TimeHelper</code> (a custom ASP.NET MVC view helper, like the built-in <code>HtmlHelper</code> and <code>UrlHelper</code>):</p>
<pre>
public TimeHelper
{
  public User User { get; private set; }

  public TimeHelper(User user)
  {
    User = user;
  }

  public DateTime GetLocalTime(DateTime utc)
  {
    DateTime local = utc.AddHours(User.TimezoneOffset);
    return new DateTime(local.Ticks, DateTimeKind.Local);
  }
}
</pre>
<p>Just another trick to keep in your bag. :)</p>


<p>Related posts:<ol><li><a href='http://kohari.org/2007/09/06/functional-programming-and-database-access/' rel='bookmark' title='Permanent Link: Functional Programming and Database Access'>Functional Programming and Database Access</a></li></ol></p><p><a target="_blank" href="http://theloungenet.com/feeds/redirect/DOTNETRSS/KOHARI/31EE545FF610487A2836F98329932943BD792C26"><img src="http://theloungenet.com/feeds/img/DOTNETRSS/KOHARI/31EE545FF610487A2836F98329932943BD792C26"></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=SDoBATmWnvk:uheIic4-OoE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/discordandrhyme?a=SDoBATmWnvk:uheIic4-OoE:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/discordandrhyme?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/discordandrhyme/~4/SDoBATmWnvk" height="1" width="1"/>]]></content:encoded><wfw:commentRss>http://kohari.org/2009/06/15/automagic-time-localization/feed/</wfw:commentRss><slash:comments>13</slash:comments><feedburner:origLink>http://kohari.org/2009/06/15/automagic-time-localization/</feedburner:origLink></item></channel></rss>
