Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added some sample data generic data rather than site specific

  • Loading branch information...
commit 1f4c3bfa1df2b3fda1540d63209b4d18c9f48f0f 1 parent 77a4278
@hectorcorrea authored
Showing with 22 additions and 3,741 deletions.
  1. +2 −10 data/blog.1.html
  2. +0 −36 data/blog.10.html
  3. +0 −25 data/blog.11.html
  4. +0 −59 data/blog.12.html
  5. +0 −94 data/blog.13.html
  6. +0 −119 data/blog.14.html
  7. +0 −98 data/blog.15.html
  8. +0 −87 data/blog.16.html
  9. +0 −100 data/blog.17.html
  10. +0 −181 data/blog.18.html
  11. +0 −220 data/blog.19.html
  12. +1 −67 data/blog.2.html
  13. +0 −89 data/blog.20.html
  14. +0 −20 data/blog.21.html
  15. +0 −32 data/blog.22.html
  16. +0 −34 data/blog.23.html
  17. +0 −303 data/blog.24.html
  18. +0 −16 data/blog.25.html
  19. +0 −63 data/blog.26.html
  20. +0 −76 data/blog.27.html
  21. +0 −36 data/blog.28.html
  22. +0 −74 data/blog.29.html
  23. +0 −67 data/blog.3.html
  24. +0 −72 data/blog.31.html
  25. +0 −28 data/blog.32.html
  26. +0 −41 data/blog.33.html
  27. +0 −145 data/blog.34.html
  28. +0 −55 data/blog.35.html
  29. +0 −5 data/blog.36.html
  30. +0 −23 data/blog.37.html
  31. +0 −47 data/blog.38.html
  32. +0 −49 data/blog.39.html
  33. +0 −102 data/blog.4.html
  34. +0 −127 data/blog.40.html
  35. +0 −48 data/blog.41.html
  36. +0 −35 data/blog.42.html
  37. +0 −25 data/blog.43.html
  38. +0 −47 data/blog.44.html
  39. +0 −47 data/blog.45.html
  40. +0 −20 data/blog.46.html
  41. +0 −10 data/blog.47.html
  42. +0 −63 data/blog.48.html
  43. +0 −52 data/blog.5.html
  44. +0 −87 data/blog.6.html
  45. +0 −75 data/blog.7.html
  46. +0 −113 data/blog.8.html
  47. +0 −89 data/blog.9.html
  48. +11 −416 data/blogs.json
  49. +4 −9 views/about.ejs
  50. +4 −5 views/home.ejs
View
12 data/blog.1.html
@@ -1,10 +1,2 @@
-<p><img align="left" src="http://hectorcorrea.com/images/coffeescriptcup.png" alt="CoffeeScript" style="margin-right:15px"/>Below are the links to the slides and code samples that I used during my presentation <b>A Decaf Introduction to CoffeeScript</b> that I gave earlier this month.</p>
-
-<ul>
-<li>Slides (<a href="http://hectorcorrea.com/downloads/intro-to-coffeescript-slides.pdf" target="_blank">PDF</a>)</li>
-<li>Code Samples (<a href="http://hectorcorrea.com/downloads/intro-to-coffeescript-code.zip" target="_blank">zip file</a>, <a href="https://github.com/hectorcorrea/intro-to-coffeescript" target="_blank">github</a>)</li>
-</ul>
-
-<p>The slides are pretty bare since I spent most of the time showing code samples. Feel free to contact me if you have any questions as you go through them.</p>
-
-<p>You can find a detailed explanation of the Binary Tree sample that showed during the presentation on this <a href="http://hectorcorrea.com/Blog/Drawing-a-Binary-Tree-in-CoffeeScript">other blog post</a>.</p>
+<p>The content of the first sample topic</p>
+<p>It can contain text <b>in bold</b> and other <i>HTML formatting</i>
View
36 data/blog.10.html
@@ -1,36 +0,0 @@
-<p>In this blog post I describe some branching strategies that I've found useful when using traditional source control systems like Team Foundation Server (TFS).</p>
-
-<p>Team Foundation Server has very good branching and merging capabilities that can help teams manage source code in a team environment. However, despite the fact that TFS provides excellent branching and merging capabilities, I usually recommend a simple approach to branching since <i>the process</i> of branching and merging can easily get convoluted and out of control even with the best of tools.</p>
-
-<h2>The basic idea</h2>
-<p>The way I approach branching in TFS is to have one <b>main branch</b> for all on-going development on the project. This is the branch where developers do their work on a daily basis. Once the team reaches the point where the code will be released to production then a second branch (a release branch) is created. This <b>release branch</b> is a copy of the code that will be pushed to production. The main branch stays active and most of the team will continue working of the main branch as they add new features to be released in a future version of the system. A few of the developers will make changes to the release branch to fix bugs that must be ironed out before the release goes out or even after it has been promoted to production.</p>
-
-<p>The following picture shows an example of these concepts and how the branches are used over time.</p>
-
-<p align="center">
-<img src="http://hectorcorrea.com/images/branching.png" alt="Branching"/>
-</p>
-
-<p>In the previous picture we can see how the team worked on the main branch from week 1 through week 4 (the green bars.) At the end of week 4 the team decided this code had all the features needed for a version 1.0 release and created a release branch with these features.</p>
-
-<p>During the next two weeks the team made a few changes to the code in the release branch, perhaps fixed a few show-stopper bugs before promoting to production. Meanwhile, the rest of the team continued working on the main branch on long term features to be released in version 2.0 (the blue bars.)</p>
-
-<p>The team worked from week 5 through week 12 on the main branch (the blue bars.) During this time there were two hot fixes pushed to production from the release branch (green bars on week 9 and week 11.) The nice thing about the release branch concept is that it gives us total isolation from the on-going long term development on the main branch. Since the release branch is an exact copy of what's in production updating this branch when a hot-fix is needed is very safe and easy.</p>
-
-<p>On week 12, the team decided that they were ready to promote the next major version of the system to production. A that time the main branch was branched out again to the release branch. From this point the cycle is repeated: hot fixes for version 2 are made on the release branch while all new development for version 3.0 is done on the main development branch (now the purple bars.)</p>
-
-<h2>Variations to this approach</h2>
-<p>In some teams we have made a small variation to this pattern in which a totally new branch is created every time a new major version of the system is deployed to production. For example, we could create a totally new branch on week 12 for release 2 rather than sticking the version 2.0 code on the existing release branch. The advantage of this variation is that, if at the end of week 12 we need to do a hot fix to version 1 (while version 2 is still in QA) we can easily make the fix on the original release 1 branch since that branch is still an exact copy of what's in production. This could be a life saver and worth consideration.</p>
-
-<p>I first read about the concepts of the main branch and a release branch in the book <a href="http://www.amazon.com/Software-Configuration-Management-Patterns-Integration/dp/0201741172" target="_blank">Software Configuration Management Patterns: Effective Teamwork, Practical Integration</a> by Stephen P. Berczuk and Brad Appleton. This book is a good read if you want more details on the approach that I describe in this post. Chapter 4 and 5 describe the Mainline and Active Development Line patterns while chapter 17 talks about the Release Line.</p>
-
-<h2>Merging - the dark side of branching</h2>
-<p>Regardless of how neat your branching strategy might be the real issues are found in the merging process. For example, in the previous picture I didn't indicate how changes made on weeks 5 and 6 on the release branch will be merged back to the main branch. The same is true on weeks 9 and 11 when hot fixes were applied to the release branch. If these changes are also needed in the main branch somebody will need to go perform this process.</p>
-
-<p>There is nothing inherent to the branching strategy that I describe in this blog post that makes the merge process easier. Depending on the nature of the changes merging can be a messy process. The best that you can do with merging is to implement a workflow in which merging conflicting changes is minimized. However, since inevitably you will have conflicting changes to merge I find <a href="http://www.yuiblog.com/blog/2011/06/09/video-f2esummit2011-donnelly/" target="_blank">Jennifer Donnelly's</a> advise on the subject rather valuable: merging should happen frequently and within context, in other words, by the person who made the change and as soon as possible. On small teams this is usually easy to do and prevents the merging process from becoming a disaster.</p>
-
-<h2>In closing...</h2>
-<p>The ideas that I've described in this blog are neither new nor the only options for branching. However, I've found them very useful for small teams working with centralized source control systems like Team Foundation Server. The fact that these ideas are simple to implement allow development teams to gain the most of branching (i.e. code isolation) without having to have a dedicated staff in charge of source control and merging.</p>
-
-<p>Although I suspect these ideas apply to most traditional client-server source control systems I have only apply them with TFS. I am not sure however how well they fit with a distributed source control system like Git.</p>
-
View
25 data/blog.11.html
@@ -1,25 +0,0 @@
-<p>Lookie here...I am running Microsoft Visual Web Developer Express on my MacAir!</p>
-
-<p>
-<img src="http://hectorcorrea.com/images/osxwin7.png" alt="Windows 7 inside OS X Lion" align="left" style="margin-right:15px" width="35%"/>
-
-When I bought <a href="http://hectorcorrea.com/Blog/Ruby-Development-on-the-Mac-OS-X">my MacAir last year</a> to start learning Ruby and Ruby on Rails I wasn't sure how much I was going to really use it. Overtime, I've gotten familiar with it and little by little it has become my main machine at home to do pretty much everything including Ruby programming, managing my music, pictures, and documents, and web browsing. It's gotten to the point that the only reason I power up my Windows laptop at home is when I need to update one of my personal ASP.NET projects or research some C# topic in particular.</p>
-
-<p>My Windows laptop at home is a nice small Lenovo 3000 v200 that is about 4 or 5 years old. It's a very nice laptop but compared with the MacAir it feels like a clunker. There isn't anything wrong it per-se, it just feels like an old machine.</p>
-
-<p>As time went on I started pondering how to run Visual Studio inside my Mac so that I don' have to rely on two machines. There are many options to host virtual machines inside OS X including the built-in Boot Camp software that comes with the Mac, VMWare, and VirtualBox. </p>
-
-<p>In my case I decided to use <a href="http://www.virtualbox.org/" title="VirtualBox" target="_blank">VirtualBox</a> to create a Windows 7 virtual machine where I can install Microsoft Visual Web Developer Express 2010.</p>
-
-<p>The following screenshot shows Visual Web Developer Express running inside a Windows 7 virtual machine hosted on OS X.</p>
-
-<div align="center">
-<img src="http://hectorcorrea.com/images/osxwin7.png" alt="Windows 7 inside OS X Lion" width="80%" />
-</div>
-
-<p>I decided to use VirtualBox over the other virtualization options for two main reasons. One is that it's free (that's hard to beat) but also because is multi-platform which allowed me to create the virtual machine on my Windows machine (where I have plenty of disk space) and once it was ready just transfer VM to my Mac and power it up there.</p>
-
-<p>Although I configured the virtual machine that emulate a hard drive with 20 GB the VM itself only uses 12.5 GB with Windows 7 and Visual Web Developer Express installed. That was perfect for me as my MacAir has a very small solid state drive to begin with. Being able to create the virtual machine on a different machine with plenty of disk space was a big plus for me.</p>
-
-<p>Now I am able to work on all my home projects on the same machine regardless of whether I want to program in Ruby or in ASP.NET. I am not quite ready to sell my Windows laptop yet, though. We'll see if that changes in the future.</p>
-
View
59 data/blog.12.html
@@ -1,59 +0,0 @@
-<p>Ever since I got my <a href="http://hectorcorrea.com/Blog/Ruby-Development-on-the-Mac-OS-X">MacAir late last year</a> I've been having <b>issues copying files from my Mac to my external storage device</b>. My external storage device is a Buffalo HD-CELU2 DriveStation that can be accessed as a standard USB drive or as network attached storage (NAS.) I've been using this device as a NAS from my Windows computers for a couple of years with no problems but my Mac refused to work smoothly with it.</p>
-
-<p>On my Mac I was able to read files from the NAS but I couldn't write files to it. When I tried to copy files to the NAS I got the dreaded and cryptic "Finder Error -36". There are several people reporting similar issues when using a NAS from their Macs and it took me several months before I found a solution that worked for me. Below is an example of the error that Finder will throw when I tried to copy a file (SamplePDF.pdf) to my NAS (hd-celu2-fce7).</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/nas_finder_error_36.png" alt="Finder error -36 on NAS"/></p>
-
-<h2>The clues</h2>
-<p>One of the things that I noticed in dealing with this issue was that the Buffalo DriveStation worked smoothly when I connected it directly to my Mac's USB port (rather than accessing it through the network.) When I used the device through the USB port I was able to read and write files with no problems. This lead me to believe that the problem was somehow related to the way the Mac was accessing the device through the network rather than the drive itself. If the drive was formatted in a way that was incompatible with the Mac I would have the same problems no matter how I accessed it.</p>
-
-<p>Here is a description of the issues that I noticed when I connected to the Buffalo DriveStation as a network drive:</p>
-<ul>
-<li>My Mac computer can read files from the NAS with no problem.</li>
-<li>My Mac cannot write files from the NAS. I get the infamous "Finder Error -36".</li>
-<li>My Windows computer can read from the NAS and write files to it with no problem</li>
-</ul>
-
-<p>Although I was able to read and write with no problems if I connected to the device through my USB port, using it this way defeated the purpose of having a NAS in the first place. I wanted to be able to connect to the device through my wireless network at home rather than having to drag the darn thing with me around the house.</p>
-
-<p>I also noticed that the problem was not exclusive to Finder, I would also get an error when I tried to copy files to my NAS through the Terminal as shown in the following screenshot. In Terminal I was able to work around this problem by using -X switch on the copy command as shown in the following screenshot. Notice how the first copy failed but the second succeeded. The <a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/cp.1.html" target="_blank">-X switch</a> prevents the copy command from copying Extended Attributes or resource forks.<br/>
-<img src="http://hectorcorrea.com/images/nas_terminal_error.png" alt="Terminal error on NAS"/>
-</p>
-
-<h2>The solution</h2>
-<p>I found the solution to my problem at macwindows.com under <a href="http://www.macwindows.com/snowleopard-filesharing.html#012510e" target="_blank">TIP: Another take on smb.config fix for -36 file sharing error: edit nsmb.conf for "streams=no"</a>. You basically need to edit a configuration file to tell the Mac not to use streams when connecting to the NAS. In particular you need to add the following two lines to the /etc/nsmb.conf file:</p>
-
-<pre>
-[default]
-[streams=no]
-</pre>
-
-<p>If the file does not exist on your machine (it didn't on mine) you will need to create it. Editing/creating this file is bit tricky since you need elevated permissions. The macwindows.com link has detailed steps on how to do this.</p>
-
-<p>The aforementioned lines will tell the Mac OS X to
-<a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man5/nsmb.conf.5.html" target="_blank">turn off the use of NTFS streams</a>
-when connecting via SMB to a device.</p>
-
-<p>As it turns out, when the Mac connects to the Buffalo DriveStation through the network it uses a protocol called SMB. That's the reason you see "SMB://somename/somepath" in Finder when you connect to an external storage device. One of the things that I learned on the macwindows.com page is that SMB is a protocol to access drive and other devices (just like FTP or HTTP) and <i>file nsmb.conf file configures the SMB client that comes with the Mac</i> (see <a href="http://www.macwindows.com/snowleopard-filesharing.html#011011e" target="_blank">SMB vs. Samba, and what Apple uses for file sharing</a>.)
-
-<h2>An even simpler solution</h2>
-<p>I found an even <b></i>simpler way to turn off streams</i></b> in this article on Apple's web site: <a href="http://support.apple.com/kb/HT4017" target="_blank">Mac OS X v10.5, v10.6: About named streams on SMB-mounted NAS, Mac OS X, and Windows servers; "-36" or "-50" alerts may appear</a>. It turns out you can just create file on the device where you want to turn streams off by using a command like this:</p>
-
-<pre>
-touch /Volumes/SharedNAS/.com.apple.smb.streams.off
-</pre>
-
-<p>where SharedNAS is the name of your shared device. The Apple article also includes a great explanation of what the heck it means to "turn off streams" when connecting to an external device through SMB.<p/>
-
-<h2>Are there any side effects?</h2>
-<p>I've been using my NAS device from my Mac with no problems for almost two weeks since I turned off streams with the solutions in this blog post. I can now read from and write to the NAS from both my Mac and Windows computers. The only side effect that I've seen so far is that, since streams are turned off, the Mac OS X creates two files on the NAS for every file that I copy to it. These double files are only visible when I access the NAS device from my Windows computer.</p>
-
-<p>The aforementioned <a href="http://support.apple.com/kb/HT4017" target="_blank">article on the Apple web site</a> indicates that "named streams are used to store Mac OS X extended attributes and can be leveraged to avoid using AppleDouble files to store the data fork and the resource fork of legacy Mac files" so it makes sense that (1) the files are now being created since we turned off streams and (2) these double files are visible from a non OS X operating system.</p>
-
-<p>The following screenshots show how the folder with the SamplePDF file is displayed in Finder and in Windows Explorer<br/>
-<img src="http://hectorcorrea.com/images/nas_mac.png" alt="NAS file from OS X"/><br/>
-<img src="http://hectorcorrea.com/images/nas_windows.jpg" alt="NAS file from Windows"/>
-</p>
-
-<p>This double file nuance is not a big deal for me specially given that for many months I couldn't even write files to my NAS from my Mac. </p>
-
View
94 data/blog.13.html
@@ -1,94 +0,0 @@
-<p><img src="http://hectorcorrea.com/images/binarytree_simple.png" alt="git" align="left" style="margin-right:15px"/>When I started learning Ruby last year I decided to implement a <b>binary tree</b> and some of its basic operations (insert, delete, walk, and search) just to get my feet wet on the language. Binary trees are a good exercise because you need to use several features of the language like conditional statements, loops, and classes while at the same time you are solving an interesting problem. The algorithm for binary trees is well documented in most introductory books on algorithms and on the web. </p>
-
-<p>To make things a bit more challenging I also implemented a program to <b>draw the binary tree</b> so that people can see how a binary tree looks like when it has more than just a handful of nodes. In this particular case I wrote small a web application in Ruby that draws the binary tree using the new canvas element supported in HTML 5. You can see a <a href="http://binarytree.heroku.com" target="_blank">live demo of the Ruby web site</a> which allows you to draw binary trees with our own set of values or you can just let it draw binary trees with random values. For demo purposes trees on the demo site are limited to 250 nodes but you can draw much larger trees if you download the code and host it on your own.</p>
-
-<p>This blog post gives short overview of the main methods to implement the binary tree, the algorithm to draw the binary tree, and the web site to demo the drawing algorithm.</p>
-
-<h2>Binary Tree or Binary Search Tree</h2>
-<p>Properly speaking the code in this blog post implements a Binary Search Tree (BST) which is a more specific version of a Binary Tree. Cormen et al. give a good explanation of this on their book <a href="http://www.amazon.com/Introduction-Algorithms-Second-Thomas-Cormen/dp/0262032937" target="_blank">Introduction to Algorithms</a>. Binary trees are trees in which each node has at most two children, one of them called "left subtree" and the other called "right subtree" but there is no order enforced per-se (pp. 1178). Binary Search Trees on the other hand are always stored in a way as to satisfy the binary-search-tree property (pp. 287):</p>
-
-<blockquote>
-Let x be a node in a binary search tree. If y is a node in the left subtree of x, then y.key ≤ x.key. If y is a node in the right subtree of x, then y.key ≥ x.key.
-</blockquote>
-
-<p>I took a bit of a liberty on this blog post (and its related source code) and use both terms interchangeably. Please be aware that all of the references to <i>binary search</i> in this blog post are in fact references to <i>binary search trees</i>.</p>
-
-<h2>Implementing a Binary Search Tree</h2>
-<p>The procedures to implement the basic binary search tree operations like insert, delete, search, and walk are well documented in most introductory books on data structures and algorithms and on the web (e.g.
-<a href="http://www.algolist.net/Data_structures/Binary_search_tree" target="_blank">www.algolist.net</a> and <a href="http://en.wikipedia.org/wiki/Binary_search_tree" target="_blank">wikipedia</a>) and they are fairly easy to implement in Ruby.</p>
-
-<p>The class that I implemented can be used as follows:</p>
-
-<script src="https://gist.github.com/911769.js?file=gistfile1.rb"></script>
-
-<p>Out of the box we can use this BinaryTree class with numbers or strings or any other native Ruby type. We can also use it with other types as long as they implement comparable operations (i.e. def <=>). </p>
-
-<h3>Adding Nodes to a Binary Tree</h3>
-<p>The code to add nodes to the binary tree is shown below. This code first evaluates if we already have a root node, if we don't then we create a root node with the new value and we are done. If we already have a root node then scan the nodes of the tree (using the binary-search-tree property aforementioned, smaller values go to the left, equal or greater than values go to the right) until we reach a leaf node. Once we've reached a leaf node we update it to point to the new node.</p>
-
-<script src="https://gist.github.com/909230.js?file=gistfile1.rb"></script>
-
-<h3>Walking the Tree</h3>
-<p>One of the advantages of a binary search tree is that it's very easy to retrieve <i>in order</i> the values stored on it. This process is called "walking the tree in order". For example, if we have a tree with the following values: 100, 50, 200, and 150 walking the tree in order will give us: 50, 100, 150, and 200. Walking the tree can be implemented easily with a recursive function. However the recursive method, although elegant, it's not very efficient when the tree is expected to have a large number of nodes. The code that I implemented to walk the tree does not use recursion but instead uses an array as a stack to keep track of the nodes that it visits. This version is not as elegant as the recursive version found in most introductory books but it works well even when the tree has thousands of nodes.</p>
-
-<p>Below is the code for walking the tree in order that I implemented. </p>
-
-<script src="https://gist.github.com/911788.js?file=gistfile1.rb"></script>
-
-<p>While implementing this method I got to experience first hand the beauty and simplicity of one of Ruby's most touted features: blocks. You can see the use of blocks in the line <b>yield node</b> of the previous code. As the algorithm finds the next node to process it simple <i>yields it</i> to the caller program. This allows the code to walk the tree to be completely independent from the action that we want to perform on each node. For example, we can print each node to the console with the following code:</p>
-
-<pre>
-tree.walk { |node| puts "#{node.value}" }
-</pre>
-
-<p>In this example the block is a simple "puts" statement but we'll see a more sophisticated example of this when we review the code to draw the binary tree. This kind of decoupling between the iteration of the elements in the tree and the action to execute on each of them can be implemented in other programming languages via delegates or pointers but I was amazed on how simple and elegant it was to do this in Ruby.</p>
-
-<h2>How to Draw a Binary Tree</h2>
-<p>The algorithm to draw a binary tree that I implemented is pretty much a variation of the algorithm to walk the tree with the exception that we need to calculate the coordinates where each node needs to be placed as we traverse the nodes in order. Calculating the coordinates turned out to be an interesting challenge but a final simple solution.</p>
-
-<p>The basics of this algorithm are as follow:</p>
-<ul>
-<li>Draw the root node in the coordinates indicated.</li>
-<li>Draw the left subtree to the left of the root node.</li>
-<li>Draw the right subtree to the right of the root node.</li>
-</ul>
-
-<script src="https://gist.github.com/911976.js?file=gistfile1.rb"></script>
-
-<p>To calculate the coordinate where the <i>left subtree</i> should be drawn we count how many children the <i>right side</i> of the <i>left subtree</i> has. We use this number to calculate the x-coordinate as a negative offset from the root. The y-coordinate is simple a positive offset from the root. Then we recurse this process for the left subtree and right subtrees. The following code snippet shows this code.</p>
-
-<script src="https://gist.github.com/911977.js?file=gistfile1.rb"></script>
-
-<p>The procedure to calculate the coordinate where the <i>right subtree</i> should be drawn is just the reverse: we count how many children the <i>left side</i> of the <i>right subtree</i> has. We use this number to calculate the x-coordinate as a positive offset from the root. The y-coordinate is simple a positive offset from the root. Then we recurse this process for the left subtree and right subtrees. The following code snippet shows this code.</p>
-
-<script src="https://gist.github.com/911978.js?file=gistfile1.rb"></script>
-
-<p>Like in the walk method, the three draw methods presented here only calculate where the node should be drawn but they don't actually draw the node. Instead they call a block with the appropriate parameters to perform the actual operation. You can see this in the line <b>block.call(node.value, x, y, parent_x, parent_y)</b> in these three routines.</p>
-
-<p>The following code shows an example of calling the draw method on a simple tree and displaying on the console the coordinate where each of the nodes should be drawn</p>
-
-<script src="https://gist.github.com/911989.js?file=gistfile1.rb"></script>
-
-<p>There is plenty of research on the best way to draw binary trees with lots of data. The book <a href="http://www.amazon.com/Graph-Drawing-Algorithms-Visualization-Graphs/dp/0133016153" target="_blank">Graph Drawing: Algorithms for the Visualization of Graphs</a> by Tollis et al. seems to be <i>the</i> reference that most research papers and presentations cite. On pages 43-45 they provide a more sophisticated version of the algorithm that I used plus several advanced algorithms for different scenarios.</p>
-
-<p>Perhaps in the future I'll update my code to implement the enhancements suggested by Tollis et al. and also to remove the recursive calls from my implementation.</p>
-
-<h2>A Real Example of Drawing a Binary Tree on a Web Page</h2>
-<p>Once we have the coordinates where each node can be drawn we could use any graphic program to perform the actual drawing. Since I wrote this program as learning exercise I decided to write a small Ruby web application to do the actual drawing. In this web application I use the new <a href="http://diveintohtml5.org/canvas.html" target="_blank">HTML 5 canvas element</a> as the drawing surface and a series of JavaScript calls to draw lines and circles on the appropriate coordinates.</p>
-
-<p>The following code shows a simplified version of how I generate the JavaScript calls to draw the nodes (circles and labels) and lines connecting the nodes.</p>
-
-<script src="https://gist.github.com/912001.js?file=gistfile1.rb"></script>
-
-<p>Notice that this code merely creates three arrays (circles, lines, labels) with some JavaScript calls. These arrays are later inserted on a web page so that when the user renders it the tree is drawn on their browser.</p>
-
-<h2>Source Code and Live Demo</h2>
-<p>If you want to the <b>see this code running</b> you can visit <a href="http://binarytree.heroku.com" target="_blank">http://binarytree.heroku.com</a> and generate a few binary trees with random data or draw a binary tree with your own set of data.</p>
-
-<p>The demo site is limited to 250 nodes but on my local environment I've drawn trees with up to 10,000 nodes. One of the disadvantages of the drawing algorithm that I implemented is that it's not an area-efficient algorithm which leads to very wide drawings. You can see this effect in this <a href="http://hectorcorrea.com/downloads/tree500.png" target="_blank">tree with 500 nodes</a>. A more dramatic example is a tree with 5,000 nodes that I generated with this code too. If I were to print this tree it would be 115 feet long by 1 foot tall (as a reference, a basketball court is 94 feet long!) You can download this tree from http://hectorcorrea.com/downloads/tree5000.png but be aware that it's almost 4MB in size (which is why I am not making it a hyperlink.)</p>
-
-<p>You can find the <b>entire Ruby source code</b> to implement the binary tree and the binary tree drawer, as well as the demo web site on github at <a href="https://github.com/hectorcorrea/binary-tree" target="_blank">https://github.com/hectorcorrea/binary-tree</a>. Feel free to check it out and let me know what you think.</p>
-
-<b>Related Post</b>
-<ul><li><a href="http://hectorcorrea.com/Blog/Drawing-a-Binary-Tree-in-CoffeeScript" target="_blank">Drawing a Binary Tree in CoffeeScript</a></li></ul>
-
View
119 data/blog.14.html
@@ -1,119 +0,0 @@
-<img src="http://hectorcorrea.com/images/git.png" alt="git" align="left" style="margin-right:15px"/> This blog post is a beginners' guide (written by a git beginner) on how to perform <b>basic version control operations with git</b> including <b>initializing a repository</b>, <b>adding files to it</b>, and <b>using branches</b>.</p>
-
-<p>The goal of this post is to describe how to use <b>git in your local machine for version control</b>. In a future post I'll cover the basics of using git and github for collaboration with other developers.</p>
-
-<p>Everything that I show on this blog is done through git's command line via the Mac OS X terminal. The steps should be very similar in other operating systems but I have not tested them outside of the Mac.</p>
-
-<h2>Is Git Installed on my Mac?</h2>
-<p>We can issue the following commands from the terminal to find out <i>if git is installed</i> and <i>what version</i> we have installed:</p>
-
-<pre>
-which git
-git --version
-</pre>
-
-<p>The command <b>which git</b> tells us if git is in our path and should return something like "/usr/local/git/bin/git". If it returns nothing it means that git is not in our path and probably not installed in our machine.</p>
-
-<p>If git is installed, we can issue <b>git --version</b> to figure out what version we are using. The following screenshot shows what I got on my machine:</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitversion.png" alt="git version"/></p>
-
-<p>If git is not installed on your Mac you can use the <a href="http://help.github.com/mac-git-installation/" target="_blank">pre-compiled installer</a> to install it on your computer.</p>
-
-<h2>Creating a Git Repository</h2>
-
-<p>Once we have git installed on our machine creating a repository for version control is pretty simple. Let's start by creating a brand new test folder and asking git for its status.</p>
-
-<pre>
-mkdir testgit
-cd testgit
-git status
-</pre>
-
-<p>The previous call to <b>git status</b> will return something along the lines of <i>"Not a git repository (or any of the parent directories)"</i> which is OK since we haven't told git anything about this folder.</p>
-
-<p>To put this folder under version control, or in git terms, to create a local repository, we can simply issue the <b>git init</b> command. This command will create several hidden folders and files inside our testgit folder. Git uses these folders and files to keep track of changes to files. If we issue <b>git status</b> now, we will see that git reports a status rather than an error like it did before we issued git init. The following screenshot shows the results of running these two commands on my machine:</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitinit.png" alt="git init"/></p>
-
-<p>Notice how git reports that a branch called master has been created and that there is nothing to commit at this point. This folder is now officially under version control and everything that we do inside of it will be monitored by git.</p>
-
-<h2>Adding Files to a Git Repository</h2>
-<p>Let's start by saving a text file named "file1.txt" into this folder and asking git again for the status of the folder. This time git will report something like the screenshot below</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitonefiletoadd.png" alt="git one file to add"/></p>
-
-<p>Notice that git is now reporting that the new file (file1.txt) exist in the folder but has not been added to the repository, or in other words, the file is not under version control yet.</p>
-
-<p>Let's go ahead and issue the <b>git add file1.txt</b> command as suggested in the previous screenshot and then check the status of the repository again. The following screenshot shows what git reports now. Notice how git now reports that there is one new file to be committed.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitonefileadded.png" alt="git one file added"/></p>
-
-<p>By adding a file we let git know that this file now needs to be tracked for version control but it's content hasn't been added to the repository. We need to issue another git command in order to actually commit the file to the repository.</p>
-
-<h2>Committing Files to a Git Repository</h2>
-<p>To commit to the repository new files or changes to existing files we simply need to issue a command like <b>git commit -a -m "first file added"</b>. The following screenshot shows the result of committing this file and getting the status of the repository again.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitonefilecommitted.png" alt="git one file committed"/></p>
-
-<p>At this point we can add more files to the testgit folder, add them to the repository with <b>git add</b> and commit them with <b>git commit</b> and we are pretty much up and running with git.</p>
-
-<p>Likewise, we can make changes to files already in the repository (e.g. to file1.txt) and commit them with <b>git commit</b>. We don't need to do anything special to be able to make changes to files already in the repository. We just edit the file and when we are ready we commit the changes. The following screenshot shows how an example of this.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitonefilecommitted2.png" alt="git one file committed a second time"/></p>
-
-<p style="margin-left:10%; border: dashed 1px;"><b>A note for Microsoft Visual Source Safe (VSS) and Team Foundation System (TFS) users:</b> In git, the term <i>commit</i> is similar to the concept of <i>checking in</i> a file in VSS and TFS. However the term <i>checkout</i> in git refers to the process of switching to another branch which is totally different from the meaning of in VSS and TFS. Keep this in mind.</p>
-
-<h2>View History of Changes</h2>
-<p>Now that we have committed a few changes to our repository we can use several git commands to review what has changed, when each change took place, and who made each change. For example, the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html" target="_blank">git log</a> command gives us a list of commits that have been performed on the current branch. From there we can use the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-show.html" target="_blank">git show</a> command to find out what commits affected a particular file or the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-whatchanged.html" target="_blank">git whatchanged</a> command to review what were the specific changes made to a file on a particular commit. We can also use the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-blame.html" target="_blank">git blame</a> command to find out who made changes to a file (you've got to love a version control system that has a blame command.)</p>
-
-<p>There are a lot of options that can be used with any of these commands and an entire blog post could be written about any one of them. The best place to get more information is probably the <a href="http://www.kernel.org/pub/software/scm/git/docs/" target="_blank">git docs</a> web site. Below is a screenshot of what git log displays in our sample after a few commits.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitlog.png" alt="git log"/> </p>
-
-<p>It's important to notice that aforementioned commands are command line tools and their results, although comprehensive, are not exactly easy to navigate or review since they are just plain text.</p>
-
-<p>However, on the Mac OS X git comes with a graphic user interface to review the changes made to a particular branch. You can invoke this tool by issuing <b>gitk</b> on the terminal. Gitk displays the history of changes in a format that it's easier to navigate than plain text but in my opinion is still very rudimentary compared with what you can do in other version control systems like TFS. There are perhaps better tools out there that might be worth researching. Below is a screenshot of how gitk displays the history of changes in our repository. In this screenshot we can see that (1) on the second commit (2) file1.txt was changed and (3) the specific changes that were made to this file.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitk.png" alt="gitk"/> </p>
-
-<h2>Using Branches</h2>
-<p>One of the biggest advantages of using a version control system for source code is that it allows you to make changes to your projects to test things out without having to worry about messing up a good working version of your system. By using branches you can create "sandboxes" from a good version of your source code, play on your sandbox until you are happy with your changes and then merge the changes back to the good version of your system...or you can also discard the sandbox altogether if you end up not being happy with the changes. As the <a href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html" target="_blank">git tutorial</a> page says "branches are cheap and easy, so this is a good way to try something out."</p>
-
-<p>When we first added a file to our repository git created a branch called master. You can see this by issuing the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html" target="_blank">git branch</a> command from the terminal.</p>
-
-<p>If we want to <b>create a new branch</b> called "sandbox" from the current master branch we just need to issue <b>git branch sandbox</b>. This will create a new branch called "sandbox" with an exact copy of the code in the current master branch. After this if we issue the <b>git branch</b> command again we should see both branches listed as in the following screenshot. The asterisk next to the master branch means that we are currently on the master branch.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitbranch.png" alt="two branches" /></p>
-
-<p>To switch to the sandbox branch we issue the <b>git checkout sandbox</b> command. If we issue the <b>git branch</b> again the asterisk will be next to the sandbox branch.</p>
-
-<p>Any changes that we make to the files from this point forward will be localized to the sandbox branch until we switch back to the master branch. Let's say for example that we edit file1.txt and commit these changes using the regular git commit command. The following screenshot shows how the changes to file1.txt on the <i>sandbox</i> branch have been committed but the file still shows the original content on the <i>master</i> branch.</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitbranchchanges.png" alt="two branches" /></p>
-
-<p>We can use the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html" target="_blank">git merge</a> command to merge the content of one branch with another. For example, let's assume that we are happy with the changes that we made on the sandbox branch and we want to bring them to the master branch. The following commands will merge the contents of the sandbox branch back into the master branch:</p>
-
-<p align="center"><img src="http://hectorcorrea.com/images/gitmerge.png" alt="two branches" /></p>
-
-<p>The merge command will automatically <i>update</i> on the master branch any files that were updated on the sandbox branch, it will also <i>add</i> any news files to the master branch that might have been added to the sandbox branch and <i>delete</i> any files that were deleted on the sandbox. You can use some additional arguments with the merge command to configure exactly what should be merged.</p>
-
-<p>If the merge command detects that some of the files to be merged changed in both branches, git will do an automatic merge and ask you to verify the changes and perform a manual commit with git commit. Take a look at the <a href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html" target="_blank">git merge</a> documentation for more details on this.</p>
-
-<h2>Summary</h2>
-<p>In this blog post we've seen how to get started with git. We went from creating a brand new repository, committing changes to it, reviewing the history of changes that we made, and created a separate branch to test changes before merging them back to the master branch.</p>
-
-<p>As I mentioned at the beginning of this blog in a future post we'll explore how to use git to collaborate with others and work on remote repositories like github.</p>
-
-<h3>References</h3>
-
-<p>There are plenty of good references to find more information about git, the basic commands that we've reviewed in this blog entry, and advanced git topics. Below is a selected list that I've found useful.</p>
-
-<ul>
-<li>This <a href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html" target="_blank">Git Tutorial</a> is a great place to start. I learned a lot of what I posted on this blog in this tutorial.</li>
-<li>More comprehensive documentation can be found on <a href="http://www.kernel.org/pub/software/scm/git/docs/user-manual.html" target="_blank">Git User's Manual.</a></li>
-<li>The official git web site has also a ton of <a href="http://git-scm.com/documentation" target="_blank">documentation</a> that I've found useful.</li>
-</ul>
-
-<p><b>Update:</b>Lo and behold, today I found by accident the <a href="http://book.git-scm.com/index.html" target="_blank">Git Community Book</a>. This is a fantastic reference that explains in great detail some of the beginner and intermediate workflows. I highly recommend you take a look at it. It's too bad this book (although it lives under the http://git-scm.com/ domain) is not listed on the "documentation" section. Sigh.</p>
-
View
98 data/blog.15.html
@@ -1,98 +0,0 @@
-<p><img width="320px" height="240px" align="left" style="margin-right:15px" src="http://hectorcorrea.com/images/mac_macair.jpg" alt="MacAir" />
-A little more than a month ago I got myself a MacAir. Even though I’ve own computers since the mid 80s this is the first time that I buy a Machintosh. The reason I bough a Mac rather than a PC is because I wanted to <b>start experimenting with the web development tools that exist for non-Windows environments</b>. Although I’ve been a software developer for more than 15 years all my experience is with Microsoft Windows and I thought is about time I start experimenting with the tools that “the “other half of the world” is using.</p>
-
-<p>Since I got a Mac most people would probably thing that I want to start writing applications for the iPhone or the Mac but in reality I want to experiment with the development tools for web applications. I will probably write an app or two for the iPhone or the Mac just to see what it’s like but my real motivation is web development using non-Windows tools.</p>
-
-<p>This is not to say that I am abandoning development with Microsoft’s tools (or the Windows ecosystem) but rather I want to experience what else is out there. There are plenty of successful web sites (e.g. Google and Facebook) that are developed using non-Windows tools and I want to see what the development experience on those tools is like.</p>
-
-<p><b>The programming language that I decided to learn first is Ruby along with the popular web development framework Ruby on Rails</b>. Over the following months I will be posting my experiences developing applications on the Mac OS X using Ruby and Ruby on Rails from the perspective of somebody that is very familiar and comfortable with Microsoft/Windows development.</p>
-
-<h2>Why Ruby?</h2>
-<p><img width="240px" height="180px" align="left" style="margin-right:15px" src="http://hectorcorrea.com/images/ruby.jpg" alt="MacAir" />
-When I decided to learn a new language I wasn’t too thrilled to learn Perl, PHP, or Phyton. I don’t really know why, the thought of learning any of those languages just didn’t excite me despite the fact that they are the ones used some of the most successful sites including Google and Facebook. </p>
-
-<p>But <a href="http://www.ruby-lang.org" target="_blank">Ruby</a> gave me a different vibe, people seem to be very passionate and excited about Ruby and Ruby on Rails. Both of them seem to be quite popular to build web applications which is what I am most interested in. In addition a lot of the ideas for Microsoft’s ASP.NET MVC (which is my main development platform these days) were taken from Rails which made me think that there is definitively a lot to be gained from learning both Ruby and Rails.</p>
-
-<p>In his presentation <a href="http://onestepback.org/articles/10things/index.html" target="_blank">10 Things Every Java Programmer Should Know About Ruby</a> Jim Weirich has this great quote:</p>
-
-<p style="margin-left:40px">“A language that doesn’t affect the way you think about programming is not worth knowing — Alan Perlis”</p>
-
-<h2>So What Does Ruby Offer? (or How I Learned to Stop Worrying and Love the Bomb)</h2>
-<p>The Ruby programming language is introduced like this in the <a href="http://ruby-lang.org" target="_blank">ruby-lang.org</a> web site:</p>
-
-<p style="margin-left:40px">“A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.”</p>
-
-<p>In digging deeper I found that Ruby is object oriented, provides garbage collection, borrows some interesting features from functional languages (which is something I’ve been meaning to look into), and it has indeed a clean syntax.</p>
-
-<p>However, there were also a few things in Ruby that I wasn’t too excited about. In particular the fact that Ruby is an interpreted language and that it is not statically typed (although it is strongly typed.) After writing code in C# for so many years I had a hard time imaging myself using a programming language that didn't offer these features.</p>
-
-<p>With my background in C# I found the slides for <a href="http://onestepback.org/articles/10things/index.html" target="_blank">10 Things Every Java Programmer Should Know About Ruby</a> by Jim Weirich and <a href="http://www.softwaresummit.com/2006/speakers/BowlerRubyForJavaProgrammers.pdf" target="_blank">Ruby for Java Programmers</a> by Mike Bowler very interesting. Both of these presentations are packed with a lot information on what makes the Ruby language different from Java/C# and highlight its strengths. Some of the topics that they cover include:</p>
-
-<ul>
-<li>The Dynamic nature of Ruby makes factories and mock objects trivial</li>
-<li>Reflection is also taken to a new level (compared with what you can do in a statically typed language like Java or C#)</li>
-<li>Nil is an object which means you never get a null pointer</li>
-<li>Closures: an object that is a block of code</li>
-</ul>
-
-<p>Jim’s slides also address my biggest concern (namely that Ruby is not statically typed) with a great quote from Bob Martin in which he mentions how the safety net provided by static typed languages is not as important when your code is covered with unit tests as those test would catch type errors for you. I am not sure I agree with this statement 100%. It is certainly an interesting point, though.</p>
-
-<p>You can find these and other interesting articles at the <a href="http://ruby-doc.org/whyruby/" target="_blank">ruby-doc.org</a> web site.</p>
-
-<h2>Ruby on the Mac OS X</h2>
-<p>One of the nice things about OS X is that out of the box it comes with the runtime libraries for several programming languages including Perl, PHP, and Ruby.</p>
-
-<p>This is really nice feature for me since that means I can start playing with Ruby without having too worry too much about where to get the binaries or how to compile the source code. In my case my Mac came with Ruby 1.8.7.</p>
-
-<p style="text-align:center"><img src="http://hectorcorrea.com/images/rubyversion.png" alt="Ruby Version"/></p>
-
-<h2>Beginning Ruby</h2>
-<p><img align="left" src="http://hectorcorrea.com/images/beginningrubybook.jpg" alt="Beginning Ruby Book" />
-I have found the book <a href="http://www.amazon.com/Beginning-Ruby-Professional-Peter-Cooper/dp/1430223634/“ target="_blank">Beginning Ruby: From Novice to Professional</a> by Peter Cooper a great resource to learn how to program in Ruby and get going.</p>
-
-<p>Peter does a great job of covering everything from how to make sure Ruby is installed on your machine, how to install Ruby, very basic programming topics (e.g. what is a class) to more advanced topics like exception handling, database access, web development or Ruby-specific techniques like how to implement enumerators and the yield operator, mix-ins, and code blocks, development frameworks for Ruby like Rails and Sinatra.</p>
-
-<p>I highly recommend this book to anyone starting with Ruby. </p>
-
-<h2>Development Tools for Ruby</h2>
-<p>The fact that the Ruby interpreter comes built in with the Mac OS X is great, but what about editors, debuggers, IDE, source control, and other development tools. For somebody like me used to a great IDE like Microsoft’s Visual Studio I was shocked to find that there is no “standard IDE” for Ruby on the Mac or any other operating system.</p>
-
-<p>From what I’ve been able to gather, most Ruby developers are comfortable editing their code in a variety of text editors that provide color syntax, basic statement completion, and indentation but not much more. There does not seem to be a “visual debugger” like what Visual Studio provides for C#, there isn’t the concept of IntelliSense either. Despite this Ruby developers seem to be able to crank up code pretty fast.</p>
-
-<h3>Editors</h3>
-<p>You can download for free the Mac OS X development tool (called <a href="http://developer.apple.com/technologies/tools/xcode.html" target="_blank">XCode</a>) that is a full blown IDE and supports color syntax for Ruby but not visual debugger or much more integration.</p>
-
-<p>I’ve found two text editors that seem to be both popular and powerful for Ruby development:</p>
-<ul>
-<li><a href="http://macromates.com/" target="_blank">TextMate</a> seems to be one of the favorite editors for Ruby (and Rails) development on the Mac as it provides really nice keyboard shortcuts for code completion, running unit tests, integration with source control (both SubVersion and Git) and other goodies. <strike>This has been my favorite editor so far. It is not free but I will probably end up buying a license in the next few days.</strike> <b>Update: </b>As I indicated in my <a href="http://hectorcorrea.com/Blog/Web-Development-on-the-Mac-OS-X-part-II">follow up post</a> I ended up going for Sublime Text 2.</li>
-<li><a href="http://www.barebones.com/products/textwrangler/" target="_blank">TextWrangler</a> is a free text editor and supports color syntax for Ruby. Somehow I found the workflow for Ruby development not as good with this editor as with TextMate but you cannot beat the price.</li>
-</ul>
-
-<p>Here is an screenshot of TextMate</p>
-<p style="text-align:center"><img src="http://hectorcorrea.com/images/mac_textmate.jpg" alt="TextMate"/></p>
-
-<p>There are plenty of other editors that people use on the OS X to edit Ruby code that are common among *nix users including Vim and Emacs. Yet, for somebody like me, with a Windows background, those editors look and feel like something from the stone age. They can be very powerful once you learn them but the learning curve might be very steep.</p>
-
-<h3>Visual Debugger</h3>
-<p>There is not a visual debugger like the one in Microsoft Visual Studio for Ruby on the OS X or other *nix environments. This has been one of the biggest shocks to me as I’ve gotten used to have one and still miss it. </p>
-
-<p>One can make the argument that if your code is testable and properly structured (small methods, classes with single responsibility) the need for an advanced debugger is less critical. That might be true but I am still dumbfounded by the lack of one. I really hope that Ted Neward’s <a href="http://blogs.tedneward.com/2011/01/01/Tech+Predictions+2011+Edition.aspx" target="_blank">prediction for 2011</a> that “Apple starts feeling the pressure to deliver a developer experience that isn’t mired in mid-90’s metaphor” comes true.</p>
-
-<p>I should clarify that <i>there is a debugger in Ruby</i> that allows you to step through your code but it is nothing like what I was used to in Visual Studio.</p>
-
-<h3>Source Control</h3>
-<p>Although more than two years old the article <a href="http://www.smashingmagazine.com/2008/09/18/the-top-7-open-source-version-control-systems/" target="_blank">7 Version Control Systems Reviewed</a> in Smashing Magazine is a great resource to get an idea of what’s available and popular on the Mac OS X.</p>
-
-<p>Of the source control systems mentioned in the article so far I have only experimented with Git and I am very pleased with it. As with the text editors I was a shocked with the lack of visual tools to do basic operations like check in and check out but this probably due in part to the lack of a standard IDE for Ruby development.</p>
-
-<p>However, Git’s installation process on the OS X was incredible painless. I was pleasantly surprised on how well documented the process to <a href="http://help.github.com/mac-git-installation/" target="_blank">install it</a> and get <a href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html" target="_blank">started</a> are. I did notice that Git seems very light-weight compared to a traditional source control system in Windows (e.g. Team Foundation or SourceSafe.)
-
-<p>It has taken me a bit to get used to depend on command line tools to check in and check out my code but at the same time I am amazed how simple it becomes after a few days of using it. I am even using GitHub to push my code “to the cloud” and keep a copy of it outside my machine. </p>
-
-<h2>In Summary</h2>
-<p>So after little bit more than a month of playing with Ruby on the OS X on my spare time, I am starting to get familiar with the language and the development tools. All of a sudden I find myself writing code without looking at my book (or the web), running my unit tests, making changes, and checking my changes to my local and remote source control repositories. I am not nearly as proficient with Ruby or the development tools on OS X as I am with C# or Visual Studio but I am starting to get to the point where I feel comfortable.</p>
-
-<p>I am sure it will be a fun and interesting ride. I’ll keep blogging about my experiences of learning Ruby (and eventually Rails) and the development tools for OS X as I learn more.</p>
-
-<p><b>Update: </b>Check out <a href="http://hectorcorrea.com/Blog/Web-Development-on-the-Mac-OS-X-part-II">Web Development on the Mac OS X</a> for an update on my experience 18 months later.</p>
-
View
87 data/blog.16.html
@@ -1,87 +0,0 @@
-<p>A few weeks ago I noticed that when users of my site request a blog topic that does not exist although I was displaying a user friendly message indicating that the topic does not exist <b>I was not returning the proper HTTP status code (404) to indicate to the user that the page was not found</b>. This approach is typically not a problem if the user visiting my site is a human (users don’t really care about HTTP status codes) but it is important if the “user” visiting the site is a web crawler like the Googlebot or the Yahoo Slurp because <b>for these non-human users the HTTP code is very important as it means something concrete to them</b>.</p>
-
-<p>In digging deeper into this issue I realized that I was doing what is known as a “soft 404” which is not good for web crawlers because it fools them into thinking that there is a valid page for an invalid URL. In my case my site was returning a status code 200 (which means OK) rather than a status code 404 that means “Not Found.” This is in fact so common that both, the Googlebot and the Yahoo Slurp, web sites talk about this problem <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=181708" target="_blank">here</a> and <a href="http://help.yahoo.com/l/us/yahoo/search/webcrawler/indexing-12.html;_ylt=AvfLqHWhRGn0A_A0Jrnz1ymygiN4" target="_blank">here</a>.</p>
-
-<h2>The Root of the Problem</h2>
-<p>The code that was causing this issue in my controller looked similar to this:</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">class</span> BlogController : Controller</pre>
-<pre><span class="lnum"> 2: </span>{</pre>
-<pre><span class="lnum"> 3: </span> <span class="kwrd">public</span> ActionResult Sample1(<span class="kwrd">string</span> topicName)</pre>
-<pre><span class="lnum"> 4: </span> {</pre>
-<pre><span class="lnum"> 5: </span> <span class="kwrd">bool</span> isTopicFound = SomeLogic(topicName);</pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">if</span> (!isTopicFound)</pre>
-<pre><span class="lnum"> 7: </span> {</pre>
-<pre><span class="lnum"> 8: </span> var route = <span class="kwrd">new</span> RouteValueDictionary(<span class="kwrd">new</span> { controller = <span class="str">"Error"</span>, action = <span class="str">"NotFound"</span> });</pre>
-<pre><span class="lnum"> 9: </span> <span class="kwrd">return</span> <span class="kwrd">new</span> RedirectToRouteResult(route);</pre>
-<pre><span class="lnum"> 10: </span> }</pre>
-<pre><span class="lnum"> 11: </span> <span class="rem">// regular code to display topic</span></pre>
-<pre><span class="lnum"> 12: </span> }</pre>
-<pre><span class="lnum"> 13: </span>}</pre>
-</div>
-</p>
-
-<p>Although this code displays a nice user friendly page to the user (via the NotFound action of the Error controller) because I am using <b>RedirectToRouteResult</b> the browser gets an HTTP code 302 (Found) followed by a 200 (OK) which is not what I wanted. Below is a trace of a request like this with Fiddler. Notice how the original request to <i>/Blog/Sample1</i> got a 302 response code indicating that something was found at a new URL and then the new URL (<i>/Error/NotFound</i>) in turn got an HTTP status code of 200 (OK) because this second URL indeed returned OK.</p>
-
-<p><img src="http://hectorcorrea.com/images/http_302_200.jpg" alt="HTTP code 302 plus HTTP code 200"/></p>
-
-<h2>Throwing an HttpException</h2>
-<p>When I decided to update my ASP.NET MVC site to handle this issue correctly my first thought was to throw an <b>HttpException</b> from my controller, for example something along these lines:</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">public</span> ActionResult Sample2(<span class="kwrd">string</span> topic)</pre>
-<pre><span class="lnum"> 2: </span>{</pre>
-<pre><span class="lnum"> 3: </span> <span class="kwrd">bool</span> isTopicFound = <span class="kwrd">false</span>; <span class="rem">// SomeLogic(topicName);</span></pre>
-<pre><span class="lnum"> 4: </span> <span class="kwrd">if</span> (!isTopicFound)</pre>
-<pre><span class="lnum"> 5: </span> {</pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">throw</span> <span class="kwrd">new</span> HttpException(404, <span class="str">"Blog topic not found"</span>);</pre>
-<pre><span class="lnum"> 7: </span> }</pre>
-<pre><span class="lnum"> 8: </span> <span class="rem">// regular code to display topic</span></pre>
-<pre><span class="lnum"> 9: </span>}</pre>
-</div>
-</p>
-
-<p>The HttpException can either be handled in the controller’s <b>OnException method</b> or on the <b>Application_Error</b> (in Global.asax.) Whatever code we use we need to be sure we don't rely on RedirectToRouteResult like in the previous example or otherwise we'll be back on the HTTP 302 + HTTP 200 trap.</p>
-
-<p>If the HttpException is not handled at all in the code then the <b>customErrors section</b> in the web.config could redirect the user to a default error page so they see a user friendly error message. In this case however the returned HTTP code is an HTTP 302 followed by an HTTP 200 just like in the previous example! This actually makes sense giving that the parameter in the customErrors section where the page is configured is clearly named “defaultRedirect”. However this does not address the problem that I am trying to solve.</p>
-
-<h2>The ASP.NET MVC way</h2>
-<p>As it turns in ASP.NET MVC you can <b>directly change the status code of the response and still display whatever view you want to</b>. The code is actually very simple as shown in the following example. Notice how the status code is forced to 404 (Not Found) and the “Error” view is selected.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">public</span> ActionResult Sample3(<span class="kwrd">string</span> topic)</pre>
-<pre><span class="lnum"> 2: </span>{</pre>
-<pre><span class="lnum"> 3: </span> <span class="kwrd">bool</span> isTopicFound = <span class="kwrd">false</span>; <span class="rem">// SomeLogic(topicName);</span></pre>
-<pre><span class="lnum"> 4: </span> <span class="kwrd">if</span> (!isTopicFound)</pre>
-<pre><span class="lnum"> 5: </span> {</pre>
-<pre><span class="lnum"> 6: </span> HttpContext.Response.StatusCode = 404;</pre>
-<pre><span class="lnum"> 7: </span> HttpContext.TrySkipIisCustomErrors = true; //Prevents the standard IIS 404 page from showing. </pre>
-<pre><span class="lnum"> 8: </span> HttpContext.Response.Clear();</pre>
-<pre><span class="lnum"> 9: </span> <span class="kwrd">return</span> <span class="kwrd">new</span> ViewResult() { ViewName = <span class="str">"Error"</span> };</pre>
-<pre><span class="lnum"> 10: </span> }</pre>
-<pre><span class="lnum"> 11: </span> <span class="rem">// regular code to display topic</span></pre>
-<pre><span class="lnum"> 12: </span>}</pre>
-</div>
-</p>
-
-<p>This code accomplishes both goals: the user sees a human friendly error (via the Error view) and the HTTP status code returned is 404 as show in the following Fiddler trace. Notice how the original request to <i>/Blog/Sample3</i> returns a 404 code directly without doing a redirect.</p>
-
-<p><img src="http://hectorcorrea.com/images/http_404.jpg" alt="HTTP code 404"/></p>
-
-<p>Line #7 in the previous example (HttpContext.TrySkipIisCustomErrors = true;) is required to hint IIS that we want to use our own HTTP 404 page rather than the IIS default page. </p>
-
-<p>Now when somebody tries to access a topic that does not exist on my blog they get both a nice error message and the correct HTTP status code. You can try this by hitting this link to a <a href="http://www.hectorcorrea.com/Blog/A-non-existing-topic" target="_blank">non-existing blog topic</a> and looking with Fiddler the HTTP status code returned.
-
-
-<h4>A Couple of Gotchas</h4>
-<p>While looking into this problem I noticed that throwing an HttpException from a controller is slightly different than throwing any other exception. For example, although you can decorate your controllers with the <b>HandleError</b> attribute and configure what view will be rendered in case of exceptions, HandleError does not handle HttpExceptions. This <a href="http://stackoverflow.com/questions/812235/error-handling-in-asp-net-mvc/812344#812344" target="_blank">post on StackOverflow</a> has more information on this issue.</p>
-
-<p>The second gotcha that I ran into is that if you return an HTTP status code 404 and your view is smaller than 513 bytes Google's Chrome browser will not render your view but rather Chrome will render its own view. This issue has been <a href="http://perso.hirlimann.net/~ludo/blog/archives/2008/09/chrome-and-404s.html" target="_blank">documented before</a> and it only happens on Chrome. Most likely this won't be an issue for you in production as most views are in fact larger than 512 bytes that by the time all the content of your page is considered but you should keep it in mind while testing as it might throw you off.</p>
-
View
100 data/blog.17.html
@@ -1,100 +0,0 @@
-<p>A few days ago I was struggling with a problem with <a href="http://logging.apache.org/log4net/index.html" target="_blank">log4net</a> in a web application. I have used log4net in many applications before with little or no problem but in this case even with a single user hitting the web site I was seeing strange logging behaviors. In my case <b><i>some of the log entries were being logged but others were not.</i></b></p>
-
-<p>The application in question is a C# ASP.NET MVC web application running under IIS. I am using the true and tried RollingFileAppender. It couldn't have been a more typical use of log4net and yet I was seeing a weird things.</p>
-
-<p>Here are the symptoms that I was seeing:</p>
-<ul>
-<li>Log4net was logging some entries but not others.
-<li>The issue was happening even when I was the only user on the site.
-<li>The issue was only happening in one of our development servers but not on my local box.
-</ul>
-
-<p>Since some entries were being logged but not others I was able to rule out the possibility that IIS might not have enough rights to write to the folder configured for the RollingFileAppender. This is a typical issue but not applicable in my case since if IIS wouldn't have enough rights nothing would be logged at all. In addition since the issue was happening even when I was the only user on the site I was sure it was not due to heavy utilization or some sort of race condition (which log4net typically handles nicely anyway.)</p>
-
-<p>The fact that the issue was happening only on the development server with IIS 6 and not on my local machine with IIS 7 made me suspect that the different versions of IIS might the culprit but wasn't sure about that.</p>
-
-<h2>Turning log4net internal diagnostic</h2>
-
-<p>To begin troubleshooting I turned on log4net's diagnostic option to see if log4net was itself reporting problems that would give me a hint. If you are not familiar with this log4net feature check out the "How do I enable log4net internal debugging?" section in the <a href="http://logging.apache.org/log4net/release/faq.html" target="_blank">log4net FAQ.</a><p>
-
-<p>In my case I configured log4net to dump all of its diagnostic information to a file called "LogDiag.txt". After running my application and hitting the site a few times I went to see what was being logged in the LogDiag.txt file and lo and behold I noticed that there were <i>three LogDiag.txt files</i> being generated. The following picture shows how this looked on my machine:</p>
-
-<p><img src="http://hectorcorrea.com/images/log4netdiag.jpg" alt="Log4net diagnostic"/></p>
-
-<p>I opened the "LogDiag.txt" file and there were no errors indicated logged in there. However, the other two files (the ones prefixed with a GUID) had the following error:</p>
-
-<pre>
-log4net:ERROR [RollingFileAppender]
- Unable to acquire lock on file c:\dev\SandboxMvc\SandboxMvc\App_Data\LogFile.
- The process cannot access the file 'c:\dev\SandboxMvc\SandboxMvc\App_Data\LogFile'
- because it is being used by another process.
-log4net:ERROR [RollingFileAppender]
- OpenFile(c:\dev\SandboxMvc\SandboxMvc\App_Data\LogFile,True) call failed.
-</pre>
-
-<h2>Houston, we have a problem...</h2>
-<p>OK so we indeed have a problem. Log4net is clearly telling me that it is having problems writing to the log file. That's good. At least I am not going crazy. But how come? How come am I having this problem now but not in other applications? How come it happens only on the web server but not in my local box?</p>
-
-<p>The answer turned out to be the way IIS was configured on the server where the problem was happening. It turns out that IIS on that particular box is configured to use what is known as a <b>web garden</b> which means that IIS will launch <i>multiple worker processes</i> to handle requests. That was different from the configuration on my local box where IIS was setup to have a single worker process running.</p>
-
-<p>The following picture shows how to configure IIS to use one or many worker processes. In this picture you can see that the "ASP.NET 4.0 Application Pool" is configured to use a maximum of three worker processes.</p>
-
-<p><img src="http://hectorcorrea.com/images/IisWorkerProcesses.JPG" alt="IIS Maximum Worker Processes Configuration"/></p>
-
-<p>When the IIS application pool is configured to use more than one worker process (i.e. a web garden) what happens is that multiple processes will be spun by IIS to serve requests for your application. If you configured log4net to use a single file to log requests (as I did) then this means that multiple processes will attempt to write to a single file and locking issues will arise. Once I realized what the problem was finding a solution was quite easy.</p>
-
-<p>The fact that there were three worker process running also explained why I saw three "LogDiag.txt" files on my machine. Log4net was smart enough to name each file differently (remember that two of them were prefixed with a GUID) so that it's internal logging didn't experience the same problem that I was having.</p>
-
-<p>Before I discuss how you can work around this issue let me clarify that there is nothing wrong per-se with having a web garden in IIS. This configuration is actually good on a server-class machine. The discussion on when and how to configure a web garden is beyond the scope of this blog post however the lesson learned is that <i><b>if you have a web garden you need to take this into account when configuring the RollingFileAppender.</b></i></p>
-
-<h2>How to address the issue</h2>
-<p>There are two ways that we can configure the RollingFileAppender to work in a web garden. One option is to configure it to use what is known as <a href="http://logging.apache.org/log4net/release/sdk/log4net.Appender.FileAppender.LockingModel.html" target="_blank">"minimal lock"</a> on the log file. With this option log4net will only lock the file for the duration of each log operation. This option reduces the chances that more than one process will collide as they keep the file locked to a minimum. However, there is no guarantee that under load they might actually collide. Additionally there is a performance penalty in opening and closing the file on each log entry. I am not sure if the penalty is too high but it's worth testing if you decide to use this option. Below is an example of how to configure the RollingFileAppender to use minimal locking (notice the lockingModel setting in line 2.)</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">appender</span> <span class="attr">name</span><span class="kwrd">="LogFileAppender"</span> <span class="attr">type</span><span class="kwrd">="log4net.Appender.RollingFileAppender,log4net"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span> <span class="kwrd">&lt;</span><span class="html">lockingModel</span> <span class="attr">type</span><span class="kwrd">="log4net.Appender.FileAppender+MinimalLock"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 3: </span> <span class="kwrd">&lt;</span><span class="html">param</span> <span class="attr">name</span><span class="kwrd">="File"</span> <span class="attr">value</span><span class="kwrd">=".\\App_Data\\LogFile"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 4: </span> <span class="kwrd">&lt;</span><span class="html">param</span> <span class="attr">name</span><span class="kwrd">="AppendToFile"</span> <span class="attr">value</span><span class="kwrd">="true"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 5: </span> <span class="kwrd">&lt;</span><span class="html">datePattern</span> <span class="attr">value</span><span class="kwrd">=".yyyy-MM-dd'.txt'"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">&lt;</span><span class="html">rollingStyle</span> <span class="attr">value</span><span class="kwrd">="Composite"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 7: </span> <span class="kwrd">&lt;</span><span class="html">maxSizeRollBackups</span> <span class="attr">value</span><span class="kwrd">="5"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 8: </span> <span class="kwrd">&lt;</span><span class="html">maximumFileSize</span> <span class="attr">value</span><span class="kwrd">="100KB"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 9: </span> <span class="kwrd">&lt;</span><span class="html">staticLogFileName</span> <span class="attr">value</span><span class="kwrd">="true"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 10: </span> <span class="kwrd">&lt;</span><span class="html">layout</span> <span class="attr">type</span><span class="kwrd">="log4net.Layout.PatternLayout"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 11: </span> <span class="kwrd">&lt;</span><span class="html">conversionPattern</span> <span class="attr">value</span><span class="kwrd">="[LOGENTRY] %date %-5level %logger{2} - %message %newline"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 12: </span> <span class="kwrd">&lt;/</span><span class="html">layout</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 13: </span><span class="kwrd">&lt;/</span><span class="html">appender</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<p>The second option to take care of the problem is to <b>make sure that each IIS worker process writes to its own file</b> so that there are no collisions at all. With this option if the web garden is configured to use three worker processes then you'll have three simultaneous log files (one for each active worker process.) Each of them can use an exclusive lock on the file as these files are not shared across processes. This method is guaranteed not to have collisions and allows you to keep using the fast exclusive lock method. The disadvantage is that now you have multiple log files to look at rather than a single consolidated one. Below is an example on how to configure the RollingFileAppender to create one file for each process. Notice how line 2 now has been configured to use a <b>PatternString</b> to name the file and the inclusion of pattern <b>%processid</b> to make each file unique by each process ID.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">appender</span> <span class="attr">name</span><span class="kwrd">="LogFileAppender"</span> <span class="attr">type</span><span class="kwrd">="log4net.Appender.RollingFileAppender,log4net"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span> <span class="kwrd">&lt;</span><span class="html">file</span> <span class="attr">type</span><span class="kwrd">="log4net.Util.PatternString"</span> <span class="attr">value</span><span class="kwrd">=".\\App_Data\\Log[%processid]"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 3: </span> <span class="rem">&lt;!--&lt;lockingModel type="log4net.Appender.FileAppender+MinimalLock" /&gt;</span></pre>
-<pre><span class="lnum"> 4: </span><span class="rem"> &lt;param name="File" value=".\\App_Data\\LogFile" /&gt;--&gt;</span></pre>
-<pre><span class="lnum"> 5: </span> <span class="kwrd">&lt;</span><span class="html">param</span> <span class="attr">name</span><span class="kwrd">="AppendToFile"</span> <span class="attr">value</span><span class="kwrd">="true"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">&lt;</span><span class="html">datePattern</span> <span class="attr">value</span><span class="kwrd">=".yyyy-MM-dd'.txt'"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 7: </span> <span class="kwrd">&lt;</span><span class="html">rollingStyle</span> <span class="attr">value</span><span class="kwrd">="Composite"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 8: </span> <span class="kwrd">&lt;</span><span class="html">maxSizeRollBackups</span> <span class="attr">value</span><span class="kwrd">="5"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 9: </span> <span class="kwrd">&lt;</span><span class="html">maximumFileSize</span> <span class="attr">value</span><span class="kwrd">="100KB"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 10: </span> <span class="kwrd">&lt;</span><span class="html">staticLogFileName</span> <span class="attr">value</span><span class="kwrd">="true"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 11: </span> <span class="kwrd">&lt;</span><span class="html">layout</span> <span class="attr">type</span><span class="kwrd">="log4net.Layout.PatternLayout"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 12: </span> <span class="kwrd">&lt;</span><span class="html">conversionPattern</span> <span class="attr">value</span><span class="kwrd">="[LOGENTRY] %date %-5level %logger{2} - %message %newline"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 13: </span> <span class="kwrd">&lt;/</span><span class="html">layout</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 14: </span><span class="kwrd">&lt;/</span><span class="html">appender</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<h2>But I thought log4net was thread-safe?</h2>
-<p>Log4net is indeed thread-safe as it is clearly indicated on log4net's <a href="http://logging.apache.org/log4net/release/faq.html" target="_blank">FAQ</a>. A lot of people get confused on this because the documentation for the <a href="http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.html" target="_blank">RollingFileAppender</a> says that the <i>appender</i> is not thread safe. In reality the log4net code takes this into account (<a href="http://stackoverflow.com/questions/1294668/log4net-fileappender-not-thread-safe/1294842#1294842" target="_blank">[1]</a><a href="http://stackoverflow.com/questions/4098409/thread-safety-of-log4net/4102027#4102027" target="_blank">[2]</a>) and makes sure logging is thread-safe. Some people have even run <a href="http://stackoverflow.com/questions/1519211/multithread-safe-logging/1520449#1520449" target="_blank">tests to prove this</a>.</p>
-
-<p>However, the fact that log4net is <i>thread-safe</i> does not mean that is <i>process-safe</i> to write to a single file. This is not log4net's fault, there is no such thing as the ability to have multiple processes write concurrently to the same text file. We use relational databases (not text files) when we need to have multiple processes write to a single repository of data.</p>
-
-<h2>In summary</h2>
-<p>If you are using log4net's RollingFileAppender in an environment where IIS is configured to use multiple worker processes (i.e. a web garden) you must ensure that the RollingFileAppender uses one file per worker process rather than a single file. </p>
View
181 data/blog.18.html
@@ -1,181 +0,0 @@
-<p>This blog posts presents an easy to use C# class to encrypt and decrypt strings in .NET.</p>
-
-<p>Although the <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aspx" target="_blank">System.Security.Cryptography</a> namespace in the .NET Framework provides a wealth of classes to encrypt and decrypt values, it seems that MSDN fails short of providing a good and simple example on how to use these classes for the most common request: encrypt a string.</p>
-
-<p>The class presented in this blog allows you to encrypt and decrypt a string with the following lines of code: </p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">string</span> encryptionPassword = <span class="str">"supersecret"</span>;</pre>
-<pre><span class="lnum"> 2: </span><span class="kwrd">string</span> textToEncrypt = <span class="str">"the quick brown fox jumps over the lazy dog"</span>;</pre>
-<pre><span class="lnum"> 3: </span>&nbsp;</pre>
-<pre><span class="lnum"> 4: </span><span class="kwrd">string</span> encrypted = Crypto.Encrypt(textToEncrypt, encryptionPassword);</pre>
-<pre><span class="lnum"> 5: </span><span class="kwrd">string</span> original = Crypto.Decrypt(encrypted, encryptionPassword);</pre>
-</div>
-</p>
-
-<p>Disclaimer: The code presented in this blog post is just one of the many ways to encrypt and decrypt strings in .NET. If you need to encrypt incredible confidential information (like the nuke launch codes) you should check specific books on Cryptography. Having said that, you probably arrived to this post because you are in search of a simple example on encryption with .NET. If that's the case then this post is for you.</p>
-
-<p>Below is the code of a simple C# class to encrypt and decrypt strings. All in all it's 61 lines of code including curly braces. You can just copy and paste this code to your project and voil&agrave; you are ready to encrypt and decrypt strings. If you are bit curious the remainder of this post explains how the code works. </p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="rem">// Code based on the book "C# 3.0 in a nutshell by Joseph Albahari" (pages 630-632)</span></pre>
-<pre><span class="lnum"> 2: </span><span class="rem">// and from this StackOverflow post by somebody called Brett</span></pre>
-<pre><span class="lnum"> 3: </span><span class="rem">// http://stackoverflow.com/questions/202011/encrypt-decrypt-string-in-net/2791259#2791259</span></pre>
-<pre><span class="lnum"> 4: </span><span class="kwrd">static</span> <span class="kwrd">public</span> <span class="kwrd">class</span> Crypto</pre>
-<pre><span class="lnum"> 5: </span>{</pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> <span class="kwrd">byte</span>[] salt = Encoding.ASCII.GetBytes(<span class="str">"Ent3r your oWn S@lt v@lu# h#r3"</span>);</pre>
-<pre><span class="lnum"> 7: </span>&nbsp;</pre>
-<pre><span class="lnum"> 8: </span> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> Encrypt(<span class="kwrd">string</span> textToEncrypt, <span class="kwrd">string</span> encryptionPassword)</pre>
-<pre><span class="lnum"> 9: </span> {</pre>
-<pre><span class="lnum"> 10: </span> var algorithm = GetAlgorithm(encryptionPassword);</pre>
-<pre><span class="lnum"> 11: </span>&nbsp;</pre>
-<pre><span class="lnum"> 12: </span> <span class="kwrd">byte</span>[] encryptedBytes;</pre>
-<pre><span class="lnum"> 13: </span> <span class="kwrd">using</span> (ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV))</pre>
-<pre><span class="lnum"> 14: </span> {</pre>
-<pre><span class="lnum"> 15: </span> <span class="kwrd">byte</span>[] bytesToEncrypt = Encoding.UTF8.GetBytes(textToEncrypt);</pre>
-<pre><span class="lnum"> 16: </span> encryptedBytes = InMemoryCrypt(bytesToEncrypt, encryptor);</pre>
-<pre><span class="lnum"> 17: </span> }</pre>
-<pre><span class="lnum"> 18: </span> <span class="kwrd">return</span> Convert.ToBase64String(encryptedBytes);</pre>
-<pre><span class="lnum"> 19: </span> }</pre>
-<pre><span class="lnum"> 20: </span>&nbsp;</pre>
-<pre><span class="lnum"> 21: </span> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> Decrypt(<span class="kwrd">string</span> encryptedText, <span class="kwrd">string</span> encryptionPassword)</pre>
-<pre><span class="lnum"> 22: </span> {</pre>
-<pre><span class="lnum"> 23: </span> var algorithm = GetAlgorithm(encryptionPassword);</pre>
-<pre><span class="lnum"> 24: </span>&nbsp;</pre>
-<pre><span class="lnum"> 25: </span> <span class="kwrd">byte</span>[] descryptedBytes;</pre>
-<pre><span class="lnum"> 26: </span> <span class="kwrd">using</span> (ICryptoTransform decryptor = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV))</pre>
-<pre><span class="lnum"> 27: </span> {</pre>
-<pre><span class="lnum"> 28: </span> <span class="kwrd">byte</span>[] encryptedBytes = Convert.FromBase64String(encryptedText);</pre>
-<pre><span class="lnum"> 29: </span> descryptedBytes = InMemoryCrypt(encryptedBytes, decryptor);</pre>
-<pre><span class="lnum"> 30: </span> }</pre>
-<pre><span class="lnum"> 31: </span> <span class="kwrd">return</span> Encoding.UTF8.GetString(descryptedBytes);</pre>
-<pre><span class="lnum"> 32: </span> }</pre>
-<pre><span class="lnum"> 33: </span>&nbsp;</pre>
-<pre><span class="lnum"> 34: </span> <span class="rem">// Performs an in-memory encrypt/decrypt transformation on a byte array.</span></pre>
-<pre><span class="lnum"> 35: </span> <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">byte</span>[] InMemoryCrypt(<span class="kwrd">byte</span>[] data, ICryptoTransform transform)</pre>
-<pre><span class="lnum"> 36: </span> {</pre>
-<pre><span class="lnum"> 37: </span> MemoryStream memory = <span class="kwrd">new</span> MemoryStream();</pre>
-<pre><span class="lnum"> 38: </span> <span class="kwrd">using</span> (Stream stream = <span class="kwrd">new</span> CryptoStream(memory, transform, CryptoStreamMode.Write))</pre>
-<pre><span class="lnum"> 39: </span> {</pre>
-<pre><span class="lnum"> 40: </span> stream.Write(data, 0, data.Length);</pre>
-<pre><span class="lnum"> 41: </span> }</pre>
-<pre><span class="lnum"> 42: </span> <span class="kwrd">return</span> memory.ToArray();</pre>
-<pre><span class="lnum"> 43: </span> }</pre>
-<pre><span class="lnum"> 44: </span>&nbsp;</pre>
-<pre><span class="lnum"> 45: </span> <span class="rem">// Defines a RijndaelManaged algorithm and sets its key and Initialization Vector (IV) </span></pre>
-<pre><span class="lnum"> 46: </span> <span class="rem">// values based on the encryptionPassword received.</span></pre>
-<pre><span class="lnum"> 47: </span> <span class="kwrd">private</span> <span class="kwrd">static</span> RijndaelManaged GetAlgorithm(<span class="kwrd">string</span> encryptionPassword)</pre>
-<pre><span class="lnum"> 48: </span> {</pre>
-<pre><span class="lnum"> 49: </span> <span class="rem">// Create an encryption key from the encryptionPassword and salt.</span></pre>
-<pre><span class="lnum"> 50: </span> var key = <span class="kwrd">new</span> Rfc2898DeriveBytes(encryptionPassword, salt);</pre>
-<pre><span class="lnum"> 51: </span>&nbsp;</pre>
-<pre><span class="lnum"> 52: </span> <span class="rem">// Declare that we are going to use the Rijndael algorithm with the key that we've just got.</span></pre>
-<pre><span class="lnum"> 53: </span> var algorithm = <span class="kwrd">new</span> RijndaelManaged();</pre>
-<pre><span class="lnum"> 54: </span> <span class="kwrd">int</span> bytesForKey = algorithm.KeySize / 8;</pre>
-<pre><span class="lnum"> 55: </span> <span class="kwrd">int</span> bytesForIV = algorithm.BlockSize / 8;</pre>
-<pre><span class="lnum"> 56: </span> algorithm.Key = key.GetBytes(bytesForKey);</pre>
-<pre><span class="lnum"> 57: </span> algorithm.IV = key.GetBytes(bytesForIV);</pre>
-<pre><span class="lnum"> 58: </span> <span class="kwrd">return</span> algorithm;</pre>
-<pre><span class="lnum"> 59: </span> }</pre>
-<pre><span class="lnum"> 60: </span>&nbsp;</pre>
-<pre><span class="lnum"> 61: </span>}</pre>
-</div>
-</p>
-
-<h2>The Crypto class</h2>
-<p>The Crypto class presented in this post has four methods. Methods <b>Crypt</b> and <b>Decrypt</b> are public and are the ones that your code calls to encrypt and decrypt values. The other two methods (InMemoryCrypt and GetAlgorithm) are used internally by the class.</p>
-
-<h2>Encrypt()</h2>
-<p>The process of encrypting values in .NET requires a few steps that are not evident to first comers. In a nutshell this process involves setting up the algorithm that will be used for encryption and pushing the data to encrypt through it. In our case since we want to encrypt strings and the .NET cryptography classes don't provide overloads for strings out of the box we'll need to take a few extra steps to account for this. The Encrypt() method in our Crypto class takes care of these steps. Let's review this method in detail.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 8: </span> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> Encrypt(<span class="kwrd">string</span> textToEncrypt, <span class="kwrd">string</span> encryptionPassword)</pre>
-<pre><span class="lnum"> 9: </span> {</pre>
-<pre><span class="lnum"> 10: </span> var algorithm = GetAlgorithm(encryptionPassword);</pre>
-<pre><span class="lnum"> 11: </span>&nbsp;</pre>
-<pre><span class="lnum"> 12: </span> <span class="kwrd">byte</span>[] encryptedBytes;</pre>
-<pre><span class="lnum"> 13: </span> <span class="kwrd">using</span> (ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV))</pre>
-<pre><span class="lnum"> 14: </span> {</pre>
-<pre><span class="lnum"> 15: </span> <span class="kwrd">byte</span>[] bytesToEncrypt = Encoding.UTF8.GetBytes(textToEncrypt);</pre>
-<pre><span class="lnum"> 16: </span> encryptedBytes = InMemoryCrypt(bytesToEncrypt, encryptor);</pre>
-<pre><span class="lnum"> 17: </span> }</pre>
-<pre><span class="lnum"> 18: </span> <span class="kwrd">return</span> Convert.ToBase64String(encryptedBytes);</pre>
-<pre><span class="lnum"> 19: </span> }</pre>
-</div>
-</p>
-
-<p>The first thing we do in the Encrypt() method is <b>define what algorithm</b> we want to use for encryption (see line 10.) In our case the we will use the Rijndael algorithm (more on this later.) This algorithm class has the ability to provide either an encryptor or a decryptor. For the Encrypt() method we obviously need an encryptor (see line 13.)</p>
-
-<p>The second thing we do is <b>convert to bytes the string</b> that we received with the value to encrypt (line 15.) This is an important step as the .NET encryption classes work with bytes, not strings.</p>
-
-<p>As you probably already know <a href="http://csharpindepth.com/Articles/General/Strings.aspx" target="_blank">strings in .NET are encoded in Unicode</a> and as such they can hold characters from pretty much any language in the world. Some of these characters need more than one byte to be stored and therefore the number of <i>bytes</i> that you get on line 15 might be larger than the number of <i>characters</i> in your string.</p>
-
-<p>If you only deal with ASCII values you probably don't give this much thought as most of the characters in your strings translate to a single byte (for example character "A" can be represented by one byte with value of 65 - its ASCII value.) However, strings in .NET can hold characters that need multiple bytes to be stored. For example, the Japanese character <img src="http://hectorcorrea.com/images/japanesechar.png" alt="Japanese char (12453)" /> maps to three bytes with values 227, 130, and 166.</p>
-
-<p>So now that we have defined an algorithm to use (along with its corresponding encryptor) and converted to bytes the information to encrypt we are ready to pass this information to the InMemoryCrypt method (line 16) to finally <b>perform the encryption</b>. We'll talk about the details of the InMemoryCrypt method in the section below but for now let's just say that it encrypts the bytes that we pass to it and gives us back the corresponding encrypted bytes.</p>
-
-<p>Finally, on line 18 we <b>convert the encrypted bytes back to a .NET string</b> since that's what we want as an end result. This is the reverse process of what we did in line 15.</p>
-
-<p>As you can see, although the Encrypt method is only a few lines long there is a lot going on. This is not exactly what I would call a self evident process and it is no wonder this is one of the most commonly asked questions in .NET message boards!</p>
-
-<h2>GetAlgorithm()</h2>
-<p>The GetAlgorithm() method declares what algorithm will be used for encryption and sets up the corresponding encryption keys. The .NET framework supports several algorithms and each of them has different strengths and weaknesses. On this particular example we are using the <a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard" target="_blank">Rijndael algorithm</a>. You can find a lot of information about this algorithm on the web but for the purpose of this blog post let's just say that it uses a pair of values (known as key and initialization vector) to encrypt a set of bytes. In our case both, the key and the initialization vector (IV), will be calculated from an "encryptionPassword" that we provide.</p>
-
-<p>Let's look in detail at the code of this method.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 47: </span> <span class="kwrd">private</span> <span class="kwrd">static</span> RijndaelManaged GetAlgorithm(<span class="kwrd">string</span> encryptionPassword)</pre>
-<pre><span class="lnum"> 48: </span> {</pre>
-<pre><span class="lnum"> 49: </span> <span class="rem">// Create an encryption key from the encryptionPassword and salt.</span></pre>
-<pre><span class="lnum"> 50: </span> var key = <span class="kwrd">new</span> Rfc2898DeriveBytes(encryptionPassword, salt);</pre>
-<pre><span class="lnum"> 51: </span>&nbsp;</pre>
-<pre><span class="lnum"> 52: </span> <span class="rem">// Declare that we are going to use the Rijndael algorithm with the key that we've just got.</span></pre>
-<pre><span class="lnum"> 53: </span> var algorithm = <span class="kwrd">new</span> RijndaelManaged();</pre>
-<pre><span class="lnum"> 54: </span> <span class="kwrd">int</span> bytesForKey = algorithm.KeySize / 8;</pre>
-<pre><span class="lnum"> 55: </span> <span class="kwrd">int</span> bytesForIV = algorithm.BlockSize / 8;</pre>
-<pre><span class="lnum"> 56: </span> algorithm.Key = key.GetBytes(bytesForKey);</pre>
-<pre><span class="lnum"> 57: </span> algorithm.IV = key.GetBytes(bytesForIV);</pre>
-<pre><span class="lnum"> 58: </span> <span class="kwrd">return</span> algorithm;</pre>
-<pre><span class="lnum"> 59: </span> }</pre>
-</div>
-</p>
-
-<p>Line 50 shows the call to Rfc2898DeriveBytes to get a <b>generator of pseudo-random bytes</b> based on our "encryptionPassword" and "salt" values.</p>
-
-<p>Line 53 <b>declares an instance of the Rijndael algorithm</b> and then on lines lines 56 and 57 we <b>set the key and initialization vector values</b> needed by this algorithm. Notice how we set these two values with as many bytes required depending on the KeySize and BlockSize of the algorithm.</p>
-
-<p>Technically you could skip the call to Rfc2898DeriveBytes and manually set the values used for key and initialization vector. However if you do this you need to make sure that you have enough bytes to fill the key and initialization vector. This can be a problem if the "encryptionPassword" value was too short (say it's only 10 bytes long but the algorithm expects 32 bytes values.) The Rfc2898DeriveBytes takes care of this problem as it can generate enough bytes even if the "encryptionPassword" and "salt" are too short.</p>
-
-<h2>InMemoryCrypt()</h2>
-<p>The classes on the .NET Framework use streams to perform the encryption process. This allows the encryption of very large blocks of text while consuming very little memory. This is a nice feature of the framework as it allows you to encrypt entire documents without having to load the entire document in memory in one chunk. The drawback is that you must go through these streams even when you encrypt small sets of data like in our example.</p>
-
-<p>The InMemoryCrypt() method (lines 35-43) hides the process of setting up the streams to read through the bytes to encrypt and dump the resulting bytes into another stream.</p>
-
-<h2>Encryption password and Salt</h2>
-<p>The "encryptionPassword" value that the Encrypt() and Decrypt() methods receive should be a value that only you know. This "encryptionPassword" alone is enough to decrypt a value encrypted with this code.</p>
-
-<p>On the other hand the "salt" value defined on the class (line 6) and used in GetAlgorithm() on line 50 does not need to be kept secret as it is useless without the encryption password. It is important however that you use the exact same "salt" value to decrypt as you used to encrypt which is why I declared it as a static member of the class rather than make it a parameter to Encrypt and Decrypt. Feel free to update this value or make it configurable on your own implementation.</p>
-
-<h2>A few final words</h2>
-<p>The Decrypt() method (lines 21-32) is pretty much the reverse of the Encrypt() method so I won't elaborate on it.</p>
-
-<p>There are many things to consider when choosing an encryption algorithm:</p>
-<ul>
-<li>Some algorithms are one-way only meaning that they can encrypt a value but you cannot decrypt it. These algorithms are known as hashing algorithms and are perfect for storing password in a database.</li>
-<li>Other algorithms do allow for encryption and decryption. Within these algorithms some of them are symmetrical (like Rijndael) meaning they use the same key for encryption and decryption whereas others are asymmetrical and use different keys known as private and public keys.</li>
-</ul>
-<p>Keep this in mind when deciding what algorithm to use in your application.</p>
-
-<p><b>References</b></p>
-
-<p>As indicated at the top of the Crypto class most of the code for this blog post was taken from the excellent book <a href="http://www.amazon.com/3-0-Nutshell-Desktop-Reference-OReilly/dp/0596527578" target="_blank">C# 3.0 in a Nutshell</a> by Joseph Albahari and Ben Albahari (pages 630-632) and from this <a href="http://stackoverflow.com/questions/202011/encrypt-decrypt-string-in-net/2791259#2791259" target="_blank">post</a> in StackOverflow by somebody called Brett.</p>
-
-<p>There is a good summary of the different encryption options in the book "C# 3.0 in a Nutshell" (see pages 627-638)</p>
View
220 data/blog.19.html
@@ -1,220 +0,0 @@
-<p>One of the nice things about ASP.NET MVC is the ability to easily integrate standard web libraries like jQuery in .NET web applications. In this blog post I am going to show how to execute AJAX calls with jQuery from an ASP.NET MVC application. The first example shows how to do it with an <a href="#HTTPGET">HTTP GET</a> call and the second one uses an <a href="#HTTPPOST">HTTP POST</a> call. Both examples use JSON in the return type.</p>
-
-<a name="HTTPGET"></a>
-<h2>HTTP GET Example</h2>
-<p>This is probably the simplest example on how to execute an AJAX call with jQuery but it should be OK to show the general concept. In this page when the user clicks on the "click here" hyperlink a request is made to the server to retrieve the time on the server and display to the user. The AJAX part of this example is that the request to the server is executed <i>without</i> making a full page reload as it can be seen in the screenshot below (notice that the time the page was originally loaded does not change after I clicked the hyperlink and retrieved the server time.) Again, not terribly exciting but good enough for our purposes.</p>
-
-<img src="http://hectorcorrea.com/images/AjaxSample1Screen.jpg" alt="Ajax Sample 1 screenshot"/>
-
-<h3>The MVC View</h3>
-<p>The MVC view that makes this possible is rather simple and it's composed of the following elements</p>
-<ul>
-<li>A SCRIPT tag on the HEAD to include the jQuery library
-<li>A SCRIPT block to declare the code to execute the jQuery call
-<li>The HTML to render the page
-</ul>
-
-<p>To include jQuery in an ASP.NET MVC you just need to a add a SCRIPT tag to the head that looks like this (line 3):</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">head</span> <span class="attr">id</span><span class="kwrd">="Head1"</span> <span class="attr">runat</span><span class="kwrd">="server"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span> <span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;</span>AJAX Sample 1<span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 3: </span> <span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">src</span><span class="kwrd">="&lt;%: Url.Content("</span>~/<span class="attr">Scripts</span>/<span class="attr">jquery-1</span>.<span class="attr">4</span>.<span class="attr">1</span>.<span class="attr">js</span><span class="kwrd">") %&gt;"</span> <span class="attr">type</span><span class="kwrd">="text/javascript"</span><span class="kwrd">&gt;&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 4: </span><span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<p>The HTML code for this page is also very simple as we are only displaying some text coming from the server (line 2), rendering a hyperlink to let the user invoke the AJAX call (line 4), and rendering a placeholder to display the value returned by the AJAX call (line 5). Notice that there is no JavaScript code in this HTML block. This is by design and I'll describe the reason for this in the next paragraphs (see Hijax section below.)</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span> <span class="kwrd">&lt;</span><span class="html">h2</span><span class="kwrd">&gt;</span>Ajax Sample 1<span class="kwrd">&lt;/</span><span class="html">h2</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span> <span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;</span>Page loaded at: <span class="asp">&lt;%</span>: System.DateTime.Now.ToString() <span class="asp">%&gt;</span><span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 3: </span>&nbsp;</pre>
-<pre><span class="lnum"> 4: </span> <span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="GetServerTime"</span> <span class="attr">id</span><span class="kwrd">="AjaxLink"</span><span class="kwrd">&gt;</span>Click here<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;</span> to get current time.<span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 5: </span> <span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">="CurrentServerTimeDiv"</span><span class="kwrd">&gt;&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<p>Of course the interesting part of this example is the actual JavaScript block that wires the HTML anchor tag to JavaScript and makes the AJAX call.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">="text/javascript"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span>&nbsp;</pre>
-<pre><span class="lnum"> 3: </span> $(document).ready(<span class="kwrd">function</span> () {</pre>
-<pre><span class="lnum"> 4: </span> <span class="rem">//Setup the AJAX call</span></pre>
-<pre><span class="lnum"> 5: </span> $(<span class="str">"#AjaxLink"</span>).click(<span class="kwrd">function</span> (<span class="kwrd">event</span>) {</pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">event</span>.preventDefault();</pre>
-<pre><span class="lnum"> 7: </span> GetCurrentServerTime();</pre>
-<pre><span class="lnum"> 8: </span> });</pre>
-<pre><span class="lnum"> 9: </span> });</pre>
-<pre><span class="lnum"> 10: </span>&nbsp;</pre>
-<pre><span class="lnum"> 11: </span> <span class="kwrd">function</span> GetCurrentServerTime() {</pre>
-<pre><span class="lnum"> 12: </span> <span class="rem">// Make the call to the server</span></pre>
-<pre><span class="lnum"> 13: </span> $.getJSON(<span class="str">"GetServerTime"</span>, <span class="kwrd">null</span>, UpdateServerTime);</pre>
-<pre><span class="lnum"> 14: </span> }</pre>
-<pre><span class="lnum"> 15: </span>&nbsp;</pre>
-<pre><span class="lnum"> 16: </span> <span class="kwrd">function</span> UpdateServerTime(result) {</pre>
-<pre><span class="lnum"> 17: </span> <span class="rem">// Update the page with the result</span></pre>
-<pre><span class="lnum"> 18: </span> <span class="kwrd">var</span> message = <span class="str">"Time on the server is: "</span> + result.ServerTime;</pre>
-<pre><span class="lnum"> 19: </span> $(<span class="str">"#CurrentServerTimeDiv"</span>).html(message);</pre>
-<pre><span class="lnum"> 20: </span> }</pre>
-<pre><span class="lnum"> 21: </span>&nbsp;</pre>
-<pre><span class="lnum"> 22: </span><span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<p>This JavaScript block has three main sections. The first section (lines 3-9) wires the HTML anchor tag with name "AjaxLink" to a JavaScript function called "GetCurrentServerTime()". It is customary to add this setup code to the ready event to make sure it's executed when the DOM of the page has been fully constructed even if not all of the resources for the page (e.g. images) have been downloaded. You can read more about this <a href="http://api.jquery.com/ready/" alt="jQuery Ready" target="_blank">here</a>. In this case we are replacing the "click" event of the anchor tag "AjaxLink" with a call to our own "GetCurrentServerTime()" JavaScript function.
-</p>
-
-<p>The second section of the JavaScript block (lines 11-14) is the actual JavaScript function that will be executed when the user clicks on the link. This code executes a jQuery's getJSON call to URL "GetServerTime", passing no arguments (null), and executing function "UpdateServerTime" upon completion. When this code is executed our MVC controller will be hit. More on this later.</p>
-
-<p>The third section of the JavaScript code (lines 16-19) is executed when our controller finishes its execution. In our case the controller returns an object with one property "ServerTime" that we use to construct a message to display on the placeholder "CurrentServerTimeDiv" that was defined in the HTML code.</p>
-
-<h3>The MVC Controller</h3>
-<p>When the user clicks on the hyperlink a request is sent through an HTTP GET to our controller. The controller will perform an operation (in this case just merely calculating the time on the server) and return this value to the view. The code for this controller is shown below:</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="rem">// GET /AjaxSample/GetServerTime</span></pre>
-<pre><span class="lnum"> 2: </span><span class="kwrd">public</span> ActionResult GetServerTime()</pre>
-<pre><span class="lnum"> 3: </span>{</pre>
-<pre><span class="lnum"> 4: </span> var viewModel = <span class="kwrd">new</span> Models.AjaxSampleViewModel();</pre>
-<pre><span class="lnum"> 5: </span> viewModel.ServerTime = DateTime.Now.ToString();</pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">if</span> (Request.IsAjaxRequest())</pre>
-<pre><span class="lnum"> 7: </span> {</pre>
-<pre><span class="lnum"> 8: </span> <span class="kwrd">return</span> Json(viewModel, JsonRequestBehavior.AllowGet);</pre>
-<pre><span class="lnum"> 9: </span> }</pre>
-<pre><span class="lnum"> 10: </span> <span class="rem">// Fallback view if JavaScript is not supported by the browser</span></pre>
-<pre><span class="lnum"> 11: </span> <span class="kwrd">return</span> View(<span class="str">"ServerTime"</span>, viewModel);</pre>
-<pre><span class="lnum"> 12: </span>}</pre>
-</div>
-</p>
-
-<p>When this code executes through an AJAX call (as in our case) it will return a JSON object to the client with the results. This is why our JavaScript code was able to use "result.ServerTime" to display the result. The following screenshot shows how the resulting object looks in JavaScript:</p>
-
-<img src="http://hectorcorrea.com/images/AjaxSample1JSON.jpg" alt="Ajax JSON result"/>
-
-<h4>Hijax</h4>
-<p>You might be wondering why do we need a fallback clause in our controller (line 10-11) if the view explicitly makes an AJAX call. The reason for this precaution is in case the client browser does not support JavaScript or JavaScript is disabled. Although JavaScript is almost always enabled in most desktop and laptop computers that's not always the case in mobile devices.</p>
-
-<p>This is also the reason we wired the AJAX call on the document ready event rather than directly on the HTML anchor tag in our view. For example, although we could have just as easily wired the AjaxLink anchor tag directly to the "GetCurrentServerTime" function that wouldn't have worked if JavaScript was disabled. Instead we wired the JavaScript call on the document ready event which is only executed if JavaScript is enabled. If JavaScript is disabled (and therefore the document ready event is not fired) the HTML anchor tag in our view is already wired to hit the "GetCurrentServer" URL which maps to the "GetServerTime" method in our controller.</p>
-
-<p>This approach to JavaScript is known as <a href="http://domscripting.com/blog/display/41" alt="Hijax" target="_blank">Hijax</a> and is a good way to provide progressive enhancement to your web pages. </p>
-
-<a name="HTTPPOST"></a>
-<h2>HTTP POST Example</h2>
-<p>You can also execute AJAX calls using an HTTP POST request. For example, in the following screenshot the information in the textboxes (e-mail and comment) is sent through an asynchronous HTTP POST to the server.</p>
-
-<img src="http://hectorcorrea.com/images/AjaxSample2Screen.jpg" alt="Ajax Sample 2 screenshot"/>
-
-<h3>The MVC View</h3>
-<p>Like in our previous example, the MVC view that makes this possible is very simple and it's composed of the following elements</p>
-<ul>
-<li>A SCRIPT tag on the HEAD to include the jQuery library
-<li>A SCRIPT block to declare the code to execute the jQuery call
-<li>The HTML to render the page
-</ul>
-
-<p>The HTML code for this page is shown below. Notice how we declare an HTML form named "SaveCommentForm" (line 3) with two textbox controls (lines 4-6) and a submit button (line 7). Below the form there is a placeholder section called "NewComment" where we will display the results from the server after the user has added a new comment. Like in our previous example there is no JavaScript on this HTML code, we will be wire the JavaScript call when the web page is rendered on the browser using the Hijax method that we described before.
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;</span>Page loaded at: <span class="asp">&lt;%</span>: System.DateTime.Now.ToString() <span class="asp">%&gt;</span><span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span> </pre>
-<pre><span class="lnum"> 3: </span><span class="asp">&lt;%</span> <span class="kwrd">using</span> (Html.BeginForm(<span class="str">"SaveComment"</span>, <span class="str">"AjaxSample"</span>, FormMethod.Post, <span class="kwrd">new</span> { id = <span class="str">"SaveCommentForm"</span> })) { <span class="asp">%&gt;</span></pre>
-<pre><span class="lnum"> 4: </span>Your e-mail address:<span class="asp">&lt;%</span>: Html.TextBox(<span class="str">"emailAddress"</span>)<span class="asp">%&gt;</span><span class="kwrd">&lt;</span><span class="html">br</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 5: </span>Enter a comment:<span class="kwrd">&lt;</span><span class="html">br</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 6: </span><span class="asp">&lt;%</span>: Html.TextArea(<span class="str">"comment"</span>)<span class="asp">%&gt;</span><span class="kwrd">&lt;</span><span class="html">br</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 7: </span><span class="kwrd">&lt;</span><span class="html">input</span> <span class="attr">type</span><span class="kwrd">="submit"</span> <span class="attr">value</span><span class="kwrd">="Save"</span> <span class="kwrd">/&gt;</span></pre>
-<pre><span class="lnum"> 8: </span><span class="asp">&lt;%</span> } <span class="asp">%&gt;</span></pre>
-<pre><span class="lnum"> 9: </span> </pre>
-<pre><span class="lnum"> 10: </span><span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">="NewComment"</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<p>The JavaScript that powers this web page is very similar to the one that we used in our previous example and is shown below.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">="text/javascript"</span><span class="kwrd">&gt;</span></pre>
-<pre><span class="lnum"> 2: </span>&nbsp;</pre>
-<pre><span class="lnum"> 3: </span> $(document).ready(<span class="kwrd">function</span> () {</pre>
-<pre><span class="lnum"> 4: </span> <span class="rem">//Setup the AJAX call</span></pre>
-<pre><span class="lnum"> 5: </span> $(<span class="str">"#SaveCommentForm"</span>).submit(<span class="kwrd">function</span> (<span class="kwrd">event</span>) {</pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">event</span>.preventDefault();</pre>
-<pre><span class="lnum"> 7: </span> SaveComment(<span class="kwrd">this</span>);</pre>
-<pre><span class="lnum"> 8: </span> });</pre>
-<pre><span class="lnum"> 9: </span> });</pre>
-<pre><span class="lnum"> 10: </span>&nbsp;</pre>
-<pre><span class="lnum"> 11: </span> <span class="kwrd">function</span> SaveComment(form) {</pre>
-<pre><span class="lnum"> 12: </span> <span class="rem">// Make an AJAX call to the server</span></pre>
-<pre><span class="lnum"> 13: </span> <span class="rem">// notice that we request a JSON response</span></pre>
-<pre><span class="lnum"> 14: </span> $.ajax({</pre>
-<pre><span class="lnum"> 15: </span> url: form.action,</pre>
-<pre><span class="lnum"> 16: </span> type: form.method,</pre>
-<pre><span class="lnum"> 17: </span> dataType: <span class="str">"json"</span>,</pre>
-<pre><span class="lnum"> 18: </span> data: $(form).serialize(),</pre>
-<pre><span class="lnum"> 19: </span> success: CommentSaved</pre>
-<pre><span class="lnum"> 20: </span> });</pre>
-<pre><span class="lnum"> 21: </span>&nbsp;</pre>
-<pre><span class="lnum"> 22: </span> }</pre>
-<pre><span class="lnum"> 23: </span>&nbsp;</pre>
-<pre><span class="lnum"> 24: </span> <span class="kwrd">function</span> CommentSaved(result) {</pre>
-<pre><span class="lnum"> 25: </span> <span class="rem">// Update the page with the result</span></pre>
-<pre><span class="lnum"> 26: </span> <span class="kwrd">var</span> newComment = <span class="str">"Thank you for you comment "</span> + result.emailAddress + <span class="str">"&lt;br/&gt;&lt;pre&gt;"</span> + result.comment + <span class="str">"&lt;/pre&gt;"</span>;</pre>
-<pre><span class="lnum"> 27: </span> <span class="kwrd">var</span> comments = newComment + <span class="str">"&lt;br/&gt;"</span> + $(<span class="str">"#NewComment"</span>).html();</pre>
-<pre><span class="lnum"> 28: </span> $(<span class="str">"#NewComment"</span>).html(comments);</pre>
-<pre><span class="lnum"> 29: </span> }</pre>
-<pre><span class="lnum"> 30: </span>&nbsp;</pre>
-<pre><span class="lnum"> 31: </span><span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span></pre>
-</div>
-</p>
-
-<p>The first section of this JavaScript block (lines 3-9) uses the Hijax technique aforementioned to redirect the submit event of the "SaveCommentForm" to call a JavaScript function named "SaveComment".</p>
-
-<p>The "SaveComment" function is defined on the second section of the JavaScript block (lines 11-20.) In this example we are issuing an HTTP POST (line 16) to the original location (line 15) that the HTML form would have on its own but we are making the call asynchronous (by using the AJAX function) and requesting that the result is delivered to us in JSON notation (line 17). When the asynchronous call completes we want jQuery to fire the "CommentSaved" function (line 19.) The following picture shows the values that are passed at runtime to the <i>url</i>, <i>type</i>, and <i>data</i> parameters in this AJAX call. Notice that the <i>form.method</i> is POST and <i>form.action</i> points to the "SaveComment" URL. </p>
-
-<img src="http://hectorcorrea.com/images/AjaxSample2Ajax.jpg" alt="Ajax Sample 2 runtime values"/>
-
-<p>The third section of the JavaScript code (lines 24-30) is executed when our controller finishes its execution. In our case the controller returns a JSON object (similar to the HTTP GET example) that we use to update the page.</p>
-
-<h3>The MVC Controller</h3>
-<p>The controller to process our HTTP POST request is shown below. In essence this code is very similar to the one that we used before in the HTTP GET example. We process the request (although in this code I just indicate that we would need to do something with it) and then return a JSON object back to the called. Like in our previous example we return a full view as a fallback plan.</p>
-
-<p>
-<!-- code formatted by http://manoli.net/csharpformat/ -->
-<div class="csharpcode">
-<pre><span class="lnum"> 1: </span><span class="rem">// POST /AjaxSample/SaveComment</span></pre>
-<pre><span class="lnum"> 2: </span>[HttpPost]</pre>
-<pre><span class="lnum"> 3: </span><span class="kwrd">public</span> ActionResult SaveComment(<span class="kwrd">string</span> comment, <span class="kwrd">string</span> emailAddress)</pre>
-<pre><span class="lnum"> 4: </span>{</pre>
-<pre><span class="lnum"> 5: </span> <span class="rem">//[Code to actually save the comment would go here]</span></pre>
-<pre><span class="lnum"> 6: </span> <span class="kwrd">if</span> (Request.IsAjaxRequest())</pre>
-<pre><span class="lnum"> 7: </span> {</pre>
-<pre><span class="lnum"> 8: </span> <span class="kwrd">return</span> Json(<span class="kwrd">new</span> { comment = comment, emailAddress = emailAddress, savedAt = DateTime.Now.ToString() });</pre>
-<pre><span class="lnum"> 9: </span> }</pre>
-<pre><span class="lnum"> 10: </span> <span class="rem">// Fallback view if JavaScript is not supported by the browser</span></pre>
-<pre><span class="lnum"> 11: </span> <span class="kwrd">return</span> View(<span class="str">"CommentSaved"</span>);</pre>
-<pre><span class="lnum"> 12: </span>}</pre>
-</div>
-</p>
-
-<h2>...and that's it</h2>
-<p>As you can see it is relatively straightforward to make AJAX calls using jQuery within ASP.NET MVC views to your controllers.</p>
-
-<h4>References</h4>
-
-<p>I took the idea of using Hijax for the jQuery calls from the book <a href="http://www.amazon.com/ASP-Net-MVC-Action-Jeffrey-Palermo/dp/1933988622" target="_blank">ASP.NET MVC in Action</a> by Jeffrey Palermo et al. (pages 195-214)</p>
-
-<p>In addition to the online documentation for jQuery, Joe Brinkman's e-book <a href="http://www.wrox.com/WileyCDA/WroxTitle/jQuery-for-ASP-NET-Developers.productCd-0470478454.html" target="_blank">jQuery for ASP.NET Developers</a> is a great place for beginners. If you are new to jQuery this is probably the best way to spend 7 bucks (other than buying a latte and a croissant at your local coffee shop!)</p>
-
-<p>Steve Sanderson's book <a href="http://www.amazon.com/ASP-NET-Framework-Second-Experts-Voice/dp/1430228865" target="_blank">Pro ASP.NET MVC 2 Framework</a> also has a good explanation on how to use jQuery in ASP.NET MVC applications (pages 517-559) that is worth checking out.</p>
View
68 data/blog.2.html
@@ -1,67 +1 @@
-<p>A few days ago I configured Sublime Text 2 editor to use three different hotkeys for compiling and running CoffeeScript files. I am new to Sublime so I consider somewhat of an achievement that I was able to pull this off with help from the interwebz and a bit of luck.</p>
-
-<h2>Run a CoffeeScript file in the Sublime console</h2>
-<p>The first hotkey that I configured runs a CoffeeScript file and displays its output to the Sublime’s console window. This is useful when I want to quickly run a small CoffeeScript program that outputs to the console. The following screenshot shows this:</p>
-
-<p><img src="http://hectorcorrea.com/images/sublimetextconsole.png"/></p>
-
-<p>To wire up this hotkey I created a new <i>Build System</i> for CoffeeScript files. You can do this via the Tools + Build System + New Build System menu option. Copy the following code inside the editor and save it as CoffeeScriptRun.sublime-build in the default directory (in my Mac the path was ~/Library/Application Support/Sublime Text 2/Packages/User)</p>
-
-<p>For Mac</p>
-
-<pre>{
- "cmd": ["coffee", "$file"],
- "selector" : "source.coffee",
- "path" : "/usr/local/bin"
-}
-</pre>
-
-<p>For Windows</p>
-<pre>{
- "cmd": ["coffee", "$file"],
- "selector" : "source.coffee"
-}
-</pre>
-
-<p>From now on, when I hit <b>command+B</b> (<img src="http://km.support.apple.com/library/APPLE/APPLECARE_ALLGEOS/HT1343/ks_command.gif"/> +B) while editing a CoffeeScript file, Sublime automatically calls the CoffeeScript compiler with the current opened file. Command+B is the default key in Sublime Text to run the build command. You can also run this command from the menu by going to Tools + Build. The output of the CoffeeScript will be displayed in the Sublime Text console at the bottom of the screen.</p>
-
-<h2>Generate the JavaScript file for a CoffeeScript file</h2>
-
-<p>The second command that I configured was to re-generate the JavaScript file associated with a CoffeeScript file. </p>
-
-<p>One easy way to do this is to create another build file like I did above but use a slightly different command to tell the CoffeeScript compiler to produce a JavaScript file. The disadvantage of this approach is that then I have to toggle between build modes via the Tools + Build System and then use command+B to produce the JavaScript file. This is just too many steps for something that I need to do quite often.</p>
-
-<p>What I really wanted was a hotkey to re-generate the JavaScript file in one shot. To do this I had to create a new key binding (Sublime Text wording for hotkey) by going to the Sublime Text 2 + Preferences + Key bindings - User and entering the following text:</p>
-
-<pre>
-[
- { "keys": ["super+j"], "command": "coffeescript_to_javascript" }
-]
-</pre>
-
-<p>This tells Sublime to wire the <b>command+J</b> key to a command called “coffeescript_to_javascript”. The next step is to create the code associated with “coffeescript_to_javascript”. To do this I went to Tools + New Plugin... menu and replaced the default code with the following: </p>
-
-<pre>
-import sublime, sublime_plugin
-
-class CoffeescriptToJavascript(sublime_plugin.TextCommand):
- def run(self, edit):
- self.view.window().run_command('exec', {'cmd': ["coffee", "-c", self.view.file_name()]})
-</pre>
-
-<p>Two things to notice in this code. One is that the name of the class (CoffeescriptToJavascript) is the CamelCase version of the name of the command (“coffeescript_to_javascript”) that I defined in the key bindings. This is very important as Sublime will automatically look for a class with the CamelCase version for the value defined in the key bindings.</p>
-
-<p>I wish I could remember where I stole the idea for this code, I know it was somewhere in the <a href="http://www.sublimetext.com/forum/" target="_blank">Sublime message board</a> but I didn’t save the link.</p>
-
-<p>The second thing to notice is that the run command in this code is calling the CoffeeScript compiler (coffee) and passing both the -c flag to produce the JavaScript and the name of the file to compile (which will be the name of the current file being edited.) </p>
-
-<p>I saved this plugin file as CoffeeScriptCompile.py in the same location where you saved the build file that we created before. I restarted Sublime to make sure the new plugin was loaded. </p>
-
-<p>From now on, when I use <b>command+J</b> Sublime runs “coffee -c somefile.coffee” and generates the corresponding somefile.js file. This command does not output the result to the console, though. </p>
-
-<h2>Outputting the JavaScript code to the Sublime Console</h2>
-<p>Lastly, using the steps defined in the previous section I created another plugin to output the JavaScript to Sublime’s console rather than to a file. This is very useful when I want to dig and see how a particular CoffeeScript feature is translated to its JavaScript equivalent. </p>
-
-<p>I wired this command to the <b>command+M</b> key and pass the “-p” flag to the CoffeeScript compiler to get the JavaScript to the standard output.</p>
-
-
+<p>The content of another sample topic</p>
View
89 data/blog.20.html
@@ -1,89 +0,0 @@
-<p>While rewriting my personal web site with ASP.NET I noticed that although support for the ASP.NET Membership Provider comes included out of the box in a ASP.NET MVC project not all the options are fully implemented to the same extend that they are in a brand new ASP.NET WebForms project. For example, the option to reset your own password if you forgot your old one is not available out of the box in an ASP.NET MVC project.</p>
-<p>Out of the box the following options are fully implemented in a ASP.NET MVC project:</p>
-<ul>
- <li>Login in</li>
- <li>Login out</li>
- <li>Change your password</li>
- <li>Create new user</li>
-</ul>
-<p><b><i>Adding support for Password Recovery to an ASP.NET MVC project turned out to be pretty easy as the core functionality already exists in the Membership Provider and it's just a matter of calling it from your application.</i></b></p>
-<p>The process that I implemented goes like this:</p>
-<ul>
- <li>From the <b>LogOn</b> view users can go to the PasswordReset view</li>
- <li>In the <b>PasswordReset</b> the user indicates his/her username and then they are sent to the QuestionAndAnswer view</li>
- <li>In the <b>QuestionAndAnswer</b> view the user enters the answer to their own security question</li>
- <li>Finally, the user is sent to the <b>PasswordResetFinal</b> view with a message indicating that their password has been reset and e-mailed to them.</li>
-</ul>
-
-<p>The rest of this blog post describes the details on how this works. The <b>source code</b> is also available in the link at the bottom of this post.</p>
-
-<h2>New Views and Controllers</h2>
-<h3>LogOn</h3>
-<p>The first thing that I did was update the LogOn view that comes with ASP.NET and added a link to start the Password Reset process. I wired this link to the a new method called PasswordReset in the AccountController.</p>
-<p align="center"><img alt="LogOn View" border="1 px" src="http://hectorcorrea.com/images/password_logon.jpg" /></p>
-<h3>Password Reset</h3>
-<p>Secondly I created the HTTP-GET PasswordReset method in the AccountController and a very simple view (PasswordReset.aspx) to allow the user to enter his/her username so that we can reset their password. The PasswordReset.aspx view is extremely simple as it only has a textbox where the user enter their user name.</p>
-<p align="center"><img alt="Password Reset View" border="1 px" src="http://hectorcorrea.com/images/password_reset.jpg" /></p>
-<blockquote> public ActionResult PasswordReset()<br />
-{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;if (!MembershipService.PasswordResetEnabled) throw new Exception(&quot;Password reset is not allowed&quot;);<br />
-&nbsp;&nbsp;&nbsp;&nbsp;return View();<br />
-} </blockquote>
-<p>I also implemented an HTTP-POST PasswordReset method in the AccountController to pick up the data and continue the process. This controller method decides whether the next step is to reset the password for this user or if we need to ask him/her a Password Recovery question before we reset their password. This step is required to honor the requiresQuestionAndAnswer configuration setting in the ASP.NET Membership Provider.</p>
-<blockquote> [HttpPost]<br />
-public ActionResult PasswordReset(string userName)<br />
-{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;if (!MembershipService.PasswordResetEnabled) throw new Exception(&quot;Password reset is not allowed&quot;);<br />
-<br />
-&nbsp;&nbsp;&nbsp;&nbsp;if (MembershipService.RequiresQuestionAndAnswer)<br />
-&nbsp;&nbsp;&nbsp;&nbsp;{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>return RedirectToAction(&quot;QuestionAndAnswer&quot;, new { userName = userName } );</b><br />
-&nbsp;&nbsp;&nbsp;&nbsp;}<br />
-&nbsp;&nbsp;&nbsp;&nbsp;else<br />
-&nbsp;&nbsp;&nbsp;&nbsp;{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MembershipService.ResetPassword(userName, GetLoginUrl());<br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RedirectToAction(&quot;PasswordResetFinal&quot;, new { userName = userName });<br />
-&nbsp;&nbsp;&nbsp;&nbsp;}<br />
-} </blockquote>
-<h3>Password Question and Answer</h3>
-<p>If the Membership Provider is configured to require a question and answer before resetting a user's password then we route users to the QuestionAndAnswer view. This view is also very simple as it merely has two labels (one with the username and another with password question for the user) and a textbox where the user will enter the answer to their password question.</p>
-<p align="center"><img alt="Security Question View" border="1 px" src="http://hectorcorrea.com/images/password_question.jpg" /></p>
-<p>To support this QuestionAndAnswerView I implemented an HTTP-GET controller method that fetches the security question for the username entered in the PasswordReset view.</p>
-<blockquote> public ActionResult QuestionAndAnswer(string userName)<br />
-{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;if (!MembershipService.PasswordResetEnabled) throw new Exception(&quot;Password reset is not allowed&quot;);<br />
-&nbsp;&nbsp;&nbsp;&nbsp;ViewData[&quot;UserName&quot;] = userName;<br />
-&nbsp;&nbsp;&nbsp;&nbsp;ViewData[&quot;Question&quot;] = <b>MembershipService.GetUserQuestion(userName);</b><br />
-&nbsp;&nbsp;&nbsp;&nbsp;return View();<br />
-} </blockquote>
-<p>Finally I added an HTTP-POST method to support the QuestionAndAnswer. By the time we get to this HTTP-POST method we have all the information that we need to reset a user's password (namely the user name and the answer to the security question.) Hence this method is where the call to actually reset the user's password actually happens.</p>
-<blockquote> [HttpPost]<br />
-public ActionResult QuestionAndAnswer(string userName, string answer)<br />
-{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;if (!MembershipService.PasswordResetEnabled) throw new Exception(&quot;Password reset is not allowed&quot;);<br />
-&nbsp;&nbsp;&nbsp;&nbsp;<b>MembershipService.ResetPassword(userName, answer, GetLoginUrl());</b><br />
-&nbsp;&nbsp;&nbsp;&nbsp;return <b>RedirectToAction(&quot;PasswordResetFinal&quot;, new { userName = userName });</b><br />
-} </blockquote>
-<h3>Password Reset Final</h3>
-<p>The last step in the process if a new view called PasswordResetFinal that just displays a message to the user telling him/her that a new password has been generated and e-mailed to them.</p>
-<p align="center"><img alt="Password Reset Final View" border="1 px" src="http://hectorcorrea.com/images/password_final.jpg" /></p>
-<h2>Changes to the Model</h2>
-<p>Every ASP.NET MVC project comes with a default model called AccountMembershipService to support the Views and Controllers that handle membership information. This AccountMembershipService is not much more than a wrapper for the ASP.NET MembershipProvider. Adding functionality to this model to support the password reset operation was very simple as the MembershipProvider already provides the core functions. The MembershipService referenced in the controller actions in the code actually point to an instance of this&nbsp;AccountMembershipService.</p>
-<p>For example, the QuestionAndAnswer view calls the following method to to retrieve the security question for a user. Notice how this method's only job is to forward the calls to the Membership provider.</p>
-<blockquote> public string GetUserQuestion(string userName)<br />
-{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;<b>MembershipUser user = _provider.GetUser(userName, false);</b><br />
-&nbsp;&nbsp;&nbsp;&nbsp;if (user == null)<br />
-&nbsp;&nbsp;&nbsp;&nbsp;{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Exception(&quot;User name not found&quot;);<br />
-&nbsp;&nbsp;&nbsp;&nbsp;}<br />
-&nbsp;&nbsp;&nbsp;&nbsp;else<br />
-&nbsp;&nbsp;&nbsp;&nbsp;{<br />
-&nbsp;&nbsp;&nbsp;&nbsp;return <b>user.PasswordQuestion;</b><br />
-&nbsp;&nbsp;&nbsp;&nbsp;}<br />
-} </blockquote>
-<p>All in all I added two methods to the AccountMembershipService (one to retrieve a user's security question and one to actually do the password reset) plus a few properties to expose a couple of features of the Membership provider (like the need for a security question) that were not exposed on the default implementation.</p>
-<h2>In Summary...</h2>
-<p>As I indicated at the beginning of this blog post, adding support for Password Recovery to an ASP.NET MVC project turned out to be pretty easy as the core of the functionality already exists in the Membership Provider.</p>
-
-<p>You can download the source code of a brand new working ASP.NET MVC web site updated to support the password recovery functionality from <a href="http://hectorcorrea.com/downloads/passwordrecoverymvc.zip">here.</a> Keep in mind that this code assumes that you already have the ASP.NET membership provider and its database configured in your system. The readme.txt file inside the download provides further instructions on how to run this sample. </p>
View
20 data/blog.21.html
@@ -1,20 +0,0 @@
-<p>A few months ago I decided write a C# program to handle binary trees. I was lucky to still remember some of the basics of this data structure from my college days and was able to write a program to handle the add operation and the code to "walk the tree" in a few hours. To make things more interesting I also decided to write a program to draw the binary tree on the screen. This turned out to be an interesting challenge and kept me busy for a few weeks.</p>
-
-<p dir="ltr" style="margin-right: 0px">The <a href="/downloads/DataStructures.zip">source code for this program is here</a>. This version uses generics so it can be used with any type that implements the IComparable interface.</p>
-
-<p>A binary tree, as indicated in <a target="_blank" href="http://en.wikipedia.org/wiki/Binary_tree">Wikipedia</a>, is a tree data structure in which each node has at most two children. To implement this data structure I created two classes: <strong>BinaryTreeNode</strong><t></t> and <strong>BinaryTree</strong><t></t>. The former is used to represent each node while the later is used to organize the nodes following the rules of binary trees. In addition, I created a third class <strong>BinaryTreeDrawer</strong><t></t> that implements the algorithm to actually draw a binary tree on the screen and let you <em>see </em>how the information is organized.</p>
-
-<p dir="ltr" style="margin-right: 0px"><em>A word of caution.</em> Although in production environments tree structures are used to optimize access to information the classes that I am providing here were not implemented with performance and optimization in mind. These classes are meant to showcase how binary trees are organized internally and allow people <em>to see them</em>.</p>
-
-<p>The demo program allows you to add values to a binary tree and see how the tree looks graphically. For example, below is the graphical representation that it generates when the following values are added to a binary tree: 100, 50, 150, 25, 75, 12, 40, 60, and 90.</p>
-
-<p align="center"><img height="156" alt="binary tree image" width="202" border="0" src="http://hectorcorrea.com/Images/binarytree2.png" /></p>
-
-<p>It is interesting to see how trees with random values look on the screen when hundreds of nodes are added to them. Click <a target="_blank" href="/downloads/binarytree200nodes.png">here</a> if you want to see a binary tree with 200+ random nodes (180 KB.)</p>
-
-<p>With any luck I'll post an updated version in the next few weeks that will include the find and delete operation. My real goal is to post a program to represent <strong>B-Trees</strong> and <strong>B<sup>+</sup>-Trees</strong> in C# (which are the kings of the trees) and that a lot of people confuse with binary trees. Stay tuned.</p>
-
-<p><img alt="" border="0" src="http://hectorcorrea.com/images/download.gif" /> Download the <a href="http://hectorcorrea.com/downloads/DataStructures.zip">source code</a>.</p>
- <p>
- Posted on
- 11/27/2006 9:42:00 AM
View
32 data/blog.22.html
@@ -1,32 +0,0 @@
-<p>A couple of weeks ago I finished reading <a target="_blank" href="http://www.amazon.com/exec/obidos/ISBN=0321150783">Lean Software Development</a> by Mary and Tom Poppendieck. What a great little book! In this book Mary and Tom present several tools for lean (their term for agile) software development plus an excellent background on why these types of methods work.</p>
-
-<p>Mary has a background (theory and practice) on manufacturing processes and in this book she describes how lean processes were/are successfully applied by companies like Toyota and 3M. I am usually disappointed when people try to compare software development to other industries (e.g. construction of buildings) because most of the times they don't have any background on the other field and make unfounded simplifications. Mary, on the other hand, has real life experience on manufacturing and software development and can compare between the two with realistic examples.</p>
-
-<p>In this book the authors describe 7 lean principles, their rational, and how to apply them to software development:</p>
-
-<ol>
- <li>Eliminate waste</li>
- <li>Amplify learning</li>
- <li>Decide as late as possible</li>
- <li>Deliver as fast as possible</li>
- <li>Empower the team</li>
- <li>Build integrity</li>
- <li>See the whole</li>
-</ol>
-
-<p>Of these principles, <strong>eliminate waste</strong> is probably the most well known in agile software development and most people in our industry have come to accept it as a good think. Some other concepts, like <strong>deciding as late as possible</strong>, are typically not well understood by managers (and developers) and can be seen as incompatible with software development. Deciding as late as possible means that we don't need to make premature decisions about the software and we should keep our options open. This allow us to decide only <em>when we have enough information</em> about the system. For example, let's say that we are about to roll out version 1.0 of our system and we are not sure if we need to support "undo" in a specific feature. Instead of guessing and locking ourselves into the decision (possible an expensive one), let's roll the system out, see it in action, and <em>then</em> evaluate if we need this feature. Once the users use our system we might find that undo is actually needed but not in the way that we had anticipated. So instead of locking ourselves with a solution ahead of time, let's wait until we know enough about the problem. As the authors say, the key to be able to decide as late as possible is that we must build a capacity for change into the system. Unit testing and Test Driven Development are two good ways to account for this.</p>
-
-<p>In addition, Mary and Tom provide with 22 thinking tools that can be applied in software development.</p>
-<ol>
- <li>Seeing Waste</li>
- <li>Value Stream Mapping</li>
- <li>Feedback</li>
- <li>Iterations</li>
- <li>Synchronization</li>
- <li>Set-Based Development</li>
- <li>Options Thinking</li>
- <li>Queue Theory</li>
- <li>and 14 others</li>
-</ol>
-
-<p>Although a large part of the material presented in this book can be found in other books (e.g. <a target="_blank" href="http://www.amazon.com/exec/obidos/ISBN=073561993X">Agile Project Management with Scrum</a> by Ken Schwaber and <a target="_blank" href="http://www.amazon.com/exec/obidos/ISBN=0131111558">Agile & Iterative Development</a> by Craig Larman) this one includes comparison with other industries that are hard to find in other books. In addition, the authors provide the theory and motivation behind each lean/agile principle from a point of view that is not exclusive to software development. This makes the book an excellent guide for people involved in software projects without a software background (e.g. business owners.)</p>
View
34 data/blog.23.html
@@ -1,34 +0,0 @@
-<p>Early August I had the opportunity to visit the computer museum in Paris. The <a target="_blank" href="http://www.museeinformatique.fr/">Musee de l'Informatique</a> has a neat variety of computers in display that range from 1960s mainframe computers, early personal computer models (IBM, Apple, Commodore) from the 80s, and other computer related stuff including punch cards, old hard drives, mother boards, software, to name a few.</p>
-
-<p>Here are a few pictures that I took while I was there.</p>
-
-<p>First things first: a 1960's mainframe. The big cabinet to the left with a bunch of yellow wires (below the clock) is the memory bank: 32K of RAM! The other big cabinet to the right is the CPU. I need to remember this picture next time I complain that my laptop is "too heavy"</p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/mainframe.jpg"><img height="267" alt="Mainframe" width="401" src="http://hectorcorrea.com/images/mainframe.jpg" /></a></p>
-
-<p>This IBM PC is almost identical to the first computer that I owned. Check it out, it had two (not one!) floppy drives :)</p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/ibmpc.jpg"><img height="450" alt="IBM PC" width="300" src="http://hectorcorrea.com/images/ibmpc.jpg" /></a></p>
-
-<p>I also saw this Commodore computer. They didn't have a Commodore 64 which was the very first computer that I used but this one reminded me a lot of those days.</p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/commodore.jpg"><img height="200" alt="Commodore" width="300" src="http://hectorcorrea.com/images/commodore.jpg" /></a></p>
-
-<p>And of course, for those of you who started on the "dark side" there was also an Apple II.</p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/apple.jpg"><img height="450" alt="Apple II" width="300" src="http://hectorcorrea.com/images/apple.jpg" /></a></p>
-
-<p>Walk down on memory lane: Sidekick anyone? You've got to admit that there was no better way to edit Turbo Pascal 3.0 code than with a "terminate and stay resident" editor like Sidekick. High tech circa 1985.</p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/software.jpg"><img height="450" alt="software" width="300" src="http://hectorcorrea.com/images/software.jpg" /></a></p>
-
-<p>A DOS developer?</p>
-
-<p> <a target="_blank" href="http://hectorcorrea.com/images/cartoon.jpg"><img height="400" alt="Cartoon" width="300" src="http://hectorcorrea.com/images/cartoon.jpg" /></a></p>
-
-<p>Hard drives and floppy disks</p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/harddrive.jpg"><img style="width: 242px; height: 189px" height="100" alt="Hard drive" width="150" src="http://hectorcorrea.com/images/harddrive.jpg" /></a> </p>
-
-<p><a target="_blank" href="http://hectorcorrea.com/images/floppies.jpg"><img height="138" alt="Floopy disks" width="207" src="http://hectorcorrea.com/images/floppies.jpg" /></a></p>
-<p> </p>
View
303 data/blog.24.html
@@ -1,303 +0,0 @@
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Below are the brief notes that I took while at DevConnections in Las Vegas (November/2008) This blog entry is mostly bullet points of things that I found interesting without much details. I'll elaborate on some of these topics in future blog entries.<o:p></o:p></span></p>
-
-<div class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal; text-align: center" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt">Tuesday, November 11th</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; mso-outline-level: 2"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><span style="font-size: 10pt; color: black; font-family: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"><img alt="" align="left" src="http://hectorcorrea.com/images/vg_mandalaybay.jpg" /></span>Opening Keynote </span><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Times New Roman&quot;,&quot;serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Scott Gu started with an overview of some of the new features released in the last year which included:</span></p>
-<ul>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Dynamic data access (to build a database application with a wizard</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Charting controls for ASP.NET</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">ASP.NET MVC - </span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">TDD friendly,&nbsp;c</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">loser to the metal (HTML) programming model, </span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Not for everyone</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Several Silverlight demos<o:p></o:p></span></li>
-</ul>
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Then he went to describe some of the new things coming in Visual Studio 2010 and ASP.NET 4.0 which included:</span></p>
-<ul>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Visual Studio's UI will use WPF rather than Windows Form</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Better support for release and deployment (e.g. support for multiple web.config files, one for each environment)</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Better support for documentation and integration with TFS work items</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Native support for SharePoint</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">TDD workflow</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Distributed caching for ASP.NET apps (look for project Velocity)</span></li>
- <li><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">NET continuum (web, desktop, RIA)<o:p></o:p></span></li>
-</ul>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><a href="http://weblogs.asp.net/christoc/archive/2008/11/11/scott-guthrie-s-keynote-at-devconnections-openforce.aspx">Chris Hammond</a> has a&nbsp;very nice summary of this sesion</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">.<o:p></o:p></span></p>
-<div class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; text-align: center; mso-outline-level: 2" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; mso-outline-level: 2"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Entity Framework in a World of Services and Processes<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><img alt="" align="left" src="http://hectorcorrea.com/images/vg_backpack.jpg" />The Entity Data Model (.edmx) generated with the Entity Framework (EF) is serializable by default which makes it compatible with WCF out of the box.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Context in EF is the equivalent to a database connection in data access<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Gotcha: You need to enumerate LINQ results before passing them back with the EF if you (as you should) surround your context with a using statement <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">using (EF context)<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">{<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">var blog = from x in ctx.Blogs select y;<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">return blogs.ToArray() // enumerate before end of using<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">}<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">In my opinion, the Entity Framework seems unfinished. Although EF makes really easy to ready data using an object model the interface to save data (inserts and updates) looks complicated. Several &quot;hacks&quot; were needed to save data.&nbsp;The problem seems to stem from the&nbsp;fact that the EF is very&nbsp;good understanding state but not inferring intent. Currently all operations apply to the entire object graph and there is no easy way to make operations more granular. This will be worked out in version 2.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">ADO.NET Data Sets (formerly known as Astoria) makes data accessible through HTTP via a REST approach. In this approach the intent is inferred from the URL. <o:p></o:p></span></p>
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">SOAP uses lots of&nbsp;verbs while REST&nbsp;few&nbsp;verbs (put/get/post/delete) but lots of nouns.<o:p></o:p></span></p>
-
-<div class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; text-align: center; mso-outline-level: 2" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; mso-outline-level: 2"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">ASP.NET MVC - so what?<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><img alt="" align="left" src="http://hectorcorrea.com/images/vg_bike.jpg" />Scott Hanselman gave a very good presentation describing what MVC provides and does not when compared with traditional ASP.NET Web Forms. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">The first thing he clarified is that ASP.NET is greater than MVC&nbsp;or WebForms. Secondly, both approaches are here to stay. They target different audiences. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">ASP.NET with Web Forms hides HTML from the developer and adds a state subsystem to HTML.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">MVC is a new project type in ASP.NET. It gives the developer more control over the HTML, lends to code easier to test (TDD friendly), but it is not for everyone. Unlike WebForms there are no event in MVC, that is there is no button&rsquo;s click event, no page postback, no viewstate, and no page lifecycle. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">If we lose so many &ldquo;web form&rdquo; features with MVC, isn&rsquo;t it like going back to classic ASP? No, there was no separation of concerns in classic ASP (more on this below) the code was all lumped in a single page and it wasn&rsquo;t easy to test.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">You can mix and match WebForms and MVC in a single web site. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">A typical URL in an MVC follows this format: </span><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><font color="#0000ff">http://controller/method/methodparameter</font></span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">, for example: </span><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><font color="#0000ff">http://products/retrieve/3</font></span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">The name MVC comes from the Model View Controller pattern. Sites with MVC use a controller (C) to interact with a model (M) to get data and return views (V). This model enforces a clear separation of concerns between the model, the view, and the controller, for example, the controller does not know anything about HTML, that&rsquo;s the job of the view. The view does not know anything about the database, that&rsquo;s the job of the model. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">The default view used by MVC uses WebForms. You can build your own or use third party views. Scott showed a kind of view using a third party product called NHAML that was quite different to a traditional WebForm way of constructing an HTML page.<o:p></o:p></span></p>
-<div class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt; text-align: center" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">LINQ to everything</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><img alt="" align="left" src="http://hectorcorrea.com/images/vg_lion.jpg" />The speakers gave a tour of all the different LINQ flavors to query a variety of data sources. Slides</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt">&nbsp;can be found at </span><span style="font-size: 10pt; color: #573323; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><a target="_blank" href="http://blogs.msdn.com/aconrad/">http://blogs.msdn.com/aconrad/</a></span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">&nbsp;<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to objects</strong> - Provides a mechanism to query objects. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to SQL</strong> &ndash; Provides LINQ&rsquo;s functionality but targeting a database (SQL Server only) rather than objects.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to Entities</strong> &ndash; A higher level of abstraction than LINQ to SQL, includes support for modeling (Entity Data Models) and supports multiple backend via plug-ins (although the only available at this point is for SQL Server)<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to DataSet</strong> &ndash; So that you don&rsquo;t los you investment on DataSets Microsoft provides this flavor. The tag line is: &quot;Not having to say you're sorry&quot; Supports everything from DataSets (e.g. offline access) with a few extra features (e.g. LINQ joins)<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to XML</strong> &ndash; Provides a lightweight XML API (lighter than the DOM.) Several new XML classes are LINQ aware. For example, the new XDocument is LINQ aware but not the old XmlDocument.</span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Easier to generate XML documents with Linq to XML than traditional use of the DOM.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">XDocument xdoc = new XDocument(<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">new XElement(&quot;contacts&quot;,<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">from c in contacts where country = &quot;South Africa&quot;)<o:p></o:p></span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><em><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">select new XElement(&quot;name&quot;)</span></em></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal">&nbsp;</p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">VB.NET you can type XML directly as regular VB code (without having to add quotes) and embed expressions in the XML&nbsp;(similar to the way they are embedded in an ASP.NET) that get rendered at runtime to produce the final XML. This is really cool. Too bad we don&rsquo;t have it in C#.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to ADO.NET Data Services</strong> - ADO.NET Data Services allow you to publish your data model as REST-based web services so that any HTTP client can consume them. For example you can use a URL like this http:/localhost/myservice.svc/customers(&quot;ALFKI&quot;)/Orders to retrieve orders for customer with key &ldquo;ALFKI&rdquo;. You can query ADO.NET Data Services with LINQ. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to Cloud Data Sources</strong> - At PDC earlier this year Microsoft unveiled two &quot;cloud data sources&quot;: Microsoft Azure and SQL Data Services<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><strong>LINQ to [insert your custom provider here]</strong> &ndash; You can write your own data source and make it LINQ friendly. Must implement IQueryable&lt;T&gt; and IQueryProvider. The two main challenges are (1) translate LINQ expressions to your native data source language and (2) transform query results to objects. They demo a LINQ to Twitter implementation. <o:p></o:p></span></p>
-<div class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt; text-align: center" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Implementing RESTful Services with WCF 3.5 SP1</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: 21.6pt"><span><img alt="" align="left" src="http://hectorcorrea.com/images/vg_geeks.jpg" />&nbsp;<a target="_blank" href="http://www.RobBagby.com">www.RobBagby.com<o:p></o:p></a></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">In 1993 Web = Content, today Web = Content + Capabilities. Web is a graph of linked resources. Resources support a fixed set of operations (HTTP verbs)</span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-font-weight: bold; mso-bidi-font-style: italic">REST is an architectural style, not a specification</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Play well with HTTP (honor response codes, use verbs) as we build other applications to run on the web. HTTP&nbsp;has proven to be good why not continuing using it.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">New 3.5 binding webHttpBinding does not use SOAP envelope, it's RESTful friendly.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Use&nbsp;WebGet and WebInvoke attributes.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-font-weight: bold">WCF REST Starter Kit (CodePlex project) has three components:&nbsp;</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">New DLL Microsoft.ServiceModel.Web.dll,&nbsp;</span><span style="font-size: 10pt; color: black; font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"><span style="mso-list: Ignore"><span style="font: 7pt &quot;Times New Roman&quot;"> </span></span></span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Visual Studio 2008 Templates and&nbsp;</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">REST Samples.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 2.4pt 0in 1.2pt; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Rob suggested four features our services should provide: (1) Use appropriated HTTP verbs, (2) Chose a representation, (3) Provide addressability, and (4) use valid HTTP response codes. These features are fully supported in the WCF REST Starter Kit via (1) WebGet attribute, (2) ResponseFormat parameter, (3) URITemplate, and (4) WebProtocolException class.<span style="mso-spacerun: yes">&nbsp; </span><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 2.4pt 0in 1.2pt; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p>&nbsp;</o:p></span></p>
-<div class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal; text-align: center" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt">Wednesday, November 12th</span><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt">&nbsp;<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; mso-outline-level: 2"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">From one server to two: Making the leap</span><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Times New Roman&quot;,&quot;serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><img alt="" align="left" src="http://hectorcorrea.com/images/vg_stratosphere.jpg" />I came late to this session so I don&rsquo;t have much on the first part of it but I found it very interesting. The speaker (Richard Campbell) was very honest on what you get and what you don&rsquo;t get when you start using more than one server to host your application.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">You use load balancing to improve reliability and scalability, but that does not necessarily translate into performance. By using load balancing the application will be more resistant to hardware faults (reliability) and support more users (scalability) but it won&rsquo;t become faster.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">NLB adds overhead to the processing of a request, especially if you use server affinity. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">You tell the cluster to drain a server, this will let the server finish processing whatever requests/sessions are currently on the server but it won&rsquo;t take more requests. This work as expected when no affinity is used. When affinity is used draining a server can take hours since sessions don&rsquo;t expire immediately and users could keep submitting requests on the same session and the machine won&rsquo;t be free up until all sessions have been closed or expired.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">If you use the no affinity approach objects need to be marked as serializable to be saved in the session cache. This is because with no affinity session is stored out of proc. It&rsquo;s very important to keep session information to a minimal when storing it out of process. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Windows comes with a State Server that stores session (state) information in memory. It&rsquo;s about twice as fast as storing information in SQL Server but it is a single point of failure. You can store session information in SQL Server as well and cluster SQL Server to prevent single point of failure. Third parties are worth considering.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">He recommends that if you create a cluster, go all the way: use the no affinity approach. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">When testing clusters make sure you test large time spans (10-15 minutes at least) to make sure you get a realistic picture. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Windows NLB detects if a machine goes down but it does not detect if IIS becomes non-responsive. You get what you paid for it.&nbsp;</span><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">&nbsp;</span><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><o:p></o:p></span></p>
-<div class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; text-align: center; mso-outline-level: 2" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: normal; mso-outline-level: 2"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">WCF Durable Services<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><img alt="" align="left" src="http://hectorcorrea.com/images/vg_belagio.jpg" />Juval Lowy started this session by talking about Custom Context in WCF and you can use this to pass out of band parameters in the header of a request. For example, if you need to have a way to identify who is making the call instead of passing an extra parameter on each method call you can store this information in the Context of the request and pass it back and forth. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">There are three bindings that support this feature, look for bindings with the word &ldquo;Context&rdquo; on them, for example BasicHttpContextBinding.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">He&rsquo;s build a few wrapper classes that make using the context information a breeze. Download them from his site: </span><a href="http://idesign.com/"><span style="font-size: 10pt; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"><font color="#0000ff">http://idesign.com</font></span></a><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'"> <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">After explaining this Juval moved to talk about durable sessions. He started by describing how in most client/server programming there is the implicit assumption that requests are short (milliseconds to minutes) Most client/server programming models assume this and work OK when the duration of the requests are short but fall short when requests take hours or days. On large time spans clients may come and go; hosts may come and go or move to different machines. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">For long running requests you cannot keep service state in memory at all times, you need to persist it. Clients need to provide a state identifier so that the server can pull the correct state from the persistent storage. There are two basic was ways to pass this information around. One is to add an extra parameter to every call and pass the session identifier there but this is ugly and introduces &ldquo;infrastructure&rdquo; information to the business methods. A better approach is to pass this information in the context of the request. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">You can add values to the context of a request from both, the client and the server. Server is the preferred approach. <o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">If you change values on a static context on the server side make sure you make it thread safe (i.e. use lock)<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">To use durable services add DurableService attribute to your service class.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">You can mark some of your methods with DurableOperation(CompleteInstance=true) to indicate that this method completes a session (e.g. the work to be done has been completed) and let the server know that when this method is called it can clear the session information for this caller. Once you end a session you need to recreate it (custom code required.)<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Juval showed all his examples using a &ldquo;File Persistent&rdquo; provider to keep things simple. WCF provides a SQL Persistent provider. Look under the 3.5\SQL folder for the scripts to create the database.<o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Towards the end Juval closed the session by demoing &ldquo;transactional memory&rdquo; &ndash; this was very cool but I got lost in the process and my notes are not very clear. The basic idea was that you can implement transactions for operations that happen in memory. For example, execute this process but don&rsquo;t change any values in memory if an exception happens in the process. Basically you decide when changes to values in memory are committed.&nbsp;<o:p></o:p></span></p>
-<div class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal; text-align: center" align="center"><span style="font-size: 10pt; color: red; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"><hr align="center" width="100%" size="2" />
-</span></div>
-
-<p class="MsoNormal" style="margin: 0in 0in 0pt; line-height: normal"><span style="font-size: 16pt; color: #bc8f5f; font-family: &quot;Arial&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: 'Times New Roman'">Building a WCF Router for Your Applications</span><span style="font-size: 12pt; color: red; font-family: &quot;Times New Roman&quot;,&quot;serif&quot;; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p>
-
-<p class="MsoNormal" style="margin: 0.2in 0in; line-height: 21.6pt"><span style="font-size: 10pt; color: black; font-family: &quot;Arial&quo