<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7874999921167706419</id><updated>2011-09-16T09:23:39.944-07:00</updated><category term='moving'/><category term='facebook'/><category term='gtd'/><category term='alt.net'/><category term='active directory'/><category term='tfs'/><category term='forms authentication'/><category term='tools'/><category term='.net 3.5'/><category term='silverlight'/><category term='apple'/><category term='random'/><category term='wwdc'/><category term='silicon valley'/><category term='c# 3.0'/><category term='wordpress'/><category term='extension methods'/><category term='mvp'/><category term='mvc'/><category term='visual studio'/><category term='3g'/><category term='cocoa'/><category term='objective-c'/><category term='sql server 2008'/><category term='parallels'/><category term='iphone'/><category term='wireless'/><category term='opinion'/><category term='amazon'/><category term='twitter'/><category term='mac'/><category term='seattle'/><category term='microsoft'/><category term='asp.net'/><category term='.net'/><category term='myspace'/><category term='code'/><category term='att'/><category term='social media'/><category term='aws'/><category term='blogs'/><category term='subversion'/><category term='resharper'/><category term='google'/><title type='text'>SlalomDev</title><subtitle type='html'>Thoughts on technology, gadgets and whatever else I feel like sharing with the world.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-8760102266076698207</id><published>2011-06-26T09:19:00.001-07:00</published><updated>2011-06-26T09:19:38.452-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wordpress'/><category scheme='http://www.blogger.com/atom/ns#' term='moving'/><title type='text'>Moving to Wordpress</title><content type='html'>Though it hasn't been updated in a while, this blog is moving to &lt;a href="http://slalomdev.wordpress.com/"&gt;slalomdev.wordpress.com&lt;/a&gt;, move your links!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-8760102266076698207?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/8760102266076698207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=8760102266076698207' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/8760102266076698207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/8760102266076698207'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2011/06/moving-to-wordpress.html' title='Moving to Wordpress'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-8853787940324510089</id><published>2009-07-17T09:39:00.000-07:00</published><updated>2009-07-17T09:39:30.936-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='gtd'/><title type='text'>How I Stay Organized</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Helvetica; font-size: 12px;"&gt;I've always been a very organized person.&amp;nbsp; Though my habits for staying organized change rather frequently.&amp;nbsp; In grade school I recall cycling through a single divided notebook to a &lt;a href="http://en.wikipedia.org/wiki/Pee_Chee_folder"&gt;pee-chee&lt;/a&gt; for every class to a notebook for every class and back again.&amp;nbsp; College was no different.&amp;nbsp; One year, small 5x7 notebooks, color coded for each class to easily be able to grab them out of my bag (yeah, I know, huge dork, it doesn't get any better…) to a meticulously organized binder with schedules I'd print out daily to manage my class and work schedules to spending way more money than I had on a &lt;a href="http://en.wikipedia.org/wiki/Handspring_(company)"&gt;Handspring Visor PDA&lt;/a&gt; (yeah, I was that guy and it was awesome).&lt;/span&gt;&lt;br /&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;In my post-college work life I'm no different.&amp;nbsp; What has changed is the amount of technology I can take advantage of.&amp;nbsp; Not too long ago I jumped on the &lt;a href="http://en.wikipedia.org/wiki/Moleskine"&gt;Moleskine&lt;/a&gt; bandwagon, I think it lasted for a month, but I'm just not a paper (or writing) person.&amp;nbsp; For one, my handwriting is horrible not to mention slow.&amp;nbsp; The time it takes for me to write something that I will later not be able to read is not worth it.&amp;nbsp; Going to school in the 90's and being subjected to keyboarding classes not once, not twice, but three times made me an excellent typist with 5th grade level handwriting.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;So here are the current methods I follow and tools I use to stay organized.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;b&gt;Inbox as a To Do List&lt;/b&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;One thing that has been true since I first got email is that I've always use my inbox as a to do list.&amp;nbsp; If something is in my inbox then it requires some action, otherwise it gets deleted or archived.&amp;nbsp; It's not anymore complicated than that.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;b&gt;Multiple Calendars&lt;/b&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Separating items between different color coded calendars works well for me.&amp;nbsp; At the core I have a personal calendar, my work calendar and a calendar that has reoccurring events for when my various bills are due.&amp;nbsp; Beyond that I'm a big fan of subscribing to calendar feeds such as my TripIt calendar (more on that in a moment), birthdays and US holidays.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;b&gt;Things&lt;/b&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;I've tried a lot of different to do list applications.&amp;nbsp; Lately I've settled on &lt;a href="http://culturedcode.com/things/"&gt;Things&lt;/a&gt;.&amp;nbsp; The combination desktop application and iPhone application are worth the initial cost.&amp;nbsp; They key is to to get in the habit of using it.&amp;nbsp; I try to get every item down throughout the day and there is nothing more rewarding than checking things off.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;b&gt;Evernote&lt;/b&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;a href="http://evernote.com/"&gt;Evernote&lt;/a&gt; is a tool that I really like, and yet still find that I am not using it nearly as much as I should be.&amp;nbsp; My note taking habits are actually not very good.&amp;nbsp; I'm super OCD about tracking to do items, but general notes from meetings tend to be pretty light.&amp;nbsp; I'm currently trying to remedy this and Evernote is the tool that seems to fit my needs the best.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;&lt;b&gt;TripIt&lt;/b&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;Last, but not least, I have been traveling quite a bit in the last couple of years.&amp;nbsp; &lt;a href="http://www.tripit.com/"&gt;TripIt&lt;/a&gt; has become and invaluable tool for keeping track of my upcoming trips and the details for those trips (i.e. flight times, hotel reservations).&amp;nbsp; Being able to subscribe to my trip items in iCal and being able to see them mixed in with other items on my calendars saves me a lot of scheduling hassle.&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;/div&gt;&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;"&gt;I think the key components to each of these tools or methods is that they are all completely in sync with my iPhone.&amp;nbsp; A system that I can maintain while I'm away from my computer is critical for me.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-8853787940324510089?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/8853787940324510089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=8853787940324510089' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/8853787940324510089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/8853787940324510089'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/07/how-i-stay-organized.html' title='How I Stay Organized'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-7040604082115219519</id><published>2009-06-29T10:57:00.000-07:00</published><updated>2009-06-29T10:57:44.365-07:00</updated><title type='text'>Our First AppStore App</title><content type='html'>Last week our client &lt;a href="http://www.sonosite.com/"&gt;SonoSite&lt;/a&gt; launched their new iPhone application into the AppStore. &amp;nbsp;SonoSite makes portable ultrasound machines. &amp;nbsp;The application we built for them provides instructional video content for general ultrasound procedures as well as a host of other supporting information. &amp;nbsp;Check out the app at&amp;nbsp;&lt;a href="http://www.sonosite.com/products/sonoaccess/"&gt;http://www.sonosite.com/products/sonoaccess/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-7040604082115219519?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/7040604082115219519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=7040604082115219519' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/7040604082115219519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/7040604082115219519'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/06/our-first-appstore-app.html' title='Our First AppStore App'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-5492410531781536564</id><published>2009-06-01T13:02:00.000-07:00</published><updated>2009-06-01T13:02:48.710-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wwdc'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>WWDC 2009</title><content type='html'>I will be attending Apple's World Wide Developer Conference again this year. &amp;nbsp;Last year Steve Jobs announced the iPhone 3G at the keynote, I'm looking forward to seeing what they have in store for us this time. &amp;nbsp;WWDC is a pretty good event for developers. &amp;nbsp;I look forward to digging into some of the iPhone SDK 3.0 features that I have not yet had a chance to dig into. &amp;nbsp;The developer NDA doesn't allow me to talk about 3.0 here, so for now I'll just say that it looks like its going to be a pretty significant update.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-5492410531781536564?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/5492410531781536564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=5492410531781536564' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5492410531781536564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5492410531781536564'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/06/wwdc-2009.html' title='WWDC 2009'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-6058988097317491691</id><published>2009-04-28T11:30:00.000-07:00</published><updated>2009-04-28T12:55:15.863-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='social media'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='myspace'/><title type='text'>Social Media Overload</title><content type='html'>I'm starting to become overwhelmed with all the social media sites.  I resisted Twitter for a long time, but I &lt;a href="http://twitter.com/SlalomDev"&gt;caved yesterday&lt;/a&gt;.  For the most part I've been pretty good about keeping it simple.  I killed my MySpace account years ago and have pretty much only used Facebook for keeping connected with folks I don't see on a daily basis.&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;There is a big push now to find a use for these tools in the enterprise.  Can Twitter really be a viable business tool?  There are certainly some cases of it working, Zappos and Alaska Airlines to name a couple.  Though I feel those users were not born out of trying to jump on the bandwagon, but rather seeing an opportunity to communicate better with customers.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;I guess to me, it boils down to each individual case.  Customers are smart, if you aren't trying to communicate with them in a genuine manor they will know and respond in kind.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-6058988097317491691?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/6058988097317491691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=6058988097317491691' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6058988097317491691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6058988097317491691'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/04/social-media-overload.html' title='Social Media Overload'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-4341383637138293351</id><published>2009-03-30T23:02:00.000-07:00</published><updated>2009-04-03T09:57:54.645-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='aws'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Using the Cloud</title><content type='html'>Over the years I've started countless projects by myself or with friends that have never been fully realized. &amp;nbsp;I'm still waiting for that one great idea that really drives me to create something from nothing. &amp;nbsp;In the mean time I am pretty happy bringing other people's ideas to light, most of the time.&lt;br /&gt;&lt;br /&gt;Without giving away too much detail, one of my current client projects is a pretty cool combination of technologies. &amp;nbsp;We are building an iPhone application with Amazon Web Services back-end. &amp;nbsp;As we've been building this it has occurred to me how many of my ideas in the past died because we would get bogged down in the details about where and how we were going to host it rather than just building it.&lt;br /&gt;&lt;br /&gt;It's thrilling to see all these cloud computing services springing up that really level the playing field for anyone with an idea to deploy, and more importantly scale if they find success.&lt;br /&gt;&lt;br /&gt;I still don't have that one great idea, but I feel like the roadblocks that existed in years past have lessened.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-4341383637138293351?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/4341383637138293351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=4341383637138293351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/4341383637138293351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/4341383637138293351'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/03/using-cloud.html' title='Using the Cloud'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total><georss:featurename>San Francisco, CA, USA</georss:featurename><georss:point>37.775196 -122.419204</georss:point><georss:box>37.7073535 -122.5359335 37.8430385 -122.30247449999999</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-1470612366335675360</id><published>2009-02-06T10:50:00.000-08:00</published><updated>2009-02-06T10:54:37.431-08:00</updated><title type='text'>Once-A-Month Blog Challenge</title><content type='html'>You might recall the &lt;a href="http://slalomdev.blogspot.com/2008/03/one-week-challenge.html"&gt;Once-A-Week Blog Challenge&lt;/a&gt; that &lt;a href="http://joelforman.blogspot.com/"&gt;Joel&lt;/a&gt; and I started last year.  Well, the wheels kinda fell off that wagon, but never fear, we have a new challenge, but this time we are lowering our expectations.  We are both committing to getting at least once post up a month!  &lt;a href="http://slalomdev.blogspot.com/2009/02/my-top-5-iphone-applications-redux.html"&gt;Here is mine for February&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-1470612366335675360?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/1470612366335675360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=1470612366335675360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1470612366335675360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1470612366335675360'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/02/once-month-blog-challenge.html' title='Once-A-Month Blog Challenge'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-1110521659624884442</id><published>2009-02-06T10:02:00.001-08:00</published><updated>2009-02-06T10:49:14.217-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>My Top 5 iPhone Applications Redux</title><content type='html'>Back in july I posted about &lt;a href="http://slalomdev.blogspot.com/2008/07/my-top-5-iphone-applications.html"&gt;my top 5 iPhone applications&lt;/a&gt;.&amp;nbsp; I figure it's been about 6 months and it would be a good time to revisit this topic as my top 5 have since changed.&amp;nbsp; So in no particular order, here they are...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284448147&amp;amp;mt=8"&gt;&lt;b&gt;Zenbe&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284448147&amp;amp;mt=8"&gt;&lt;img align="left" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SYx_3WGJ63I/AAAAAAAACxI/OeXdMLv-O8g/s320/zenbe.png" style="margin: 5px;" /&gt;&lt;/a&gt;I managed to pick this app up when it was initially released for free, now it runs $2.99, but I would still pay for it.  Zenbe is a pretty straight forward list tracking app that allows you to create multiple lists, assign due dates and organize your items.  It has the added bonus of having a pretty decent web front end that stays in sync at &lt;a href="http://lists.zenbe.com/"&gt;lists.zenbe.com&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284910350&amp;amp;mt=8"&gt;&lt;b&gt;Yelp&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284910350&amp;amp;mt=8"&gt;&lt;img align="left" src="http://3.bp.blogspot.com/_Lh3Pr0ATa7Q/SYx_62A18vI/AAAAAAAACxQ/xpl515aWuqk/s320/yelp.png" style="margin: 5px;" /&gt;&lt;/a&gt;I continue to find &lt;a href="http://www.yelp.com/"&gt;Yelp&lt;/a&gt; very useful when looking for new restaurants and bars, the iPhone app is a nice compliment to the website.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=283179414&amp;amp;mt=8"&gt;&lt;b&gt;Solebon&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=283179414&amp;amp;mt=8"&gt;&lt;img align="left" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SYx_9itY9cI/AAAAAAAACxY/3nY0UrIj3g8/s320/solebon.png" style="margin: 5px;" /&gt;&lt;/a&gt;I am pretty much addicted to iPhone solitaire, this version is great.  They have a free version as well, but I think its worth the price for the added game variations you get.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284882215&amp;amp;mt=8"&gt;&lt;b&gt;Facebook&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284882215&amp;amp;mt=8"&gt;&lt;img align="left" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SYyAAZ-tE5I/AAAAAAAACxg/UHvDNM5MGJI/s320/facebook.png" style="margin: 5px;" /&gt;&lt;/a&gt;I kinda hate to admit it, but I check &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt; on my phone way more than I probably need to be.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=300238550&amp;amp;mt=8"&gt;&lt;b&gt;Mint&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=300238550&amp;amp;mt=8"&gt;&lt;img align="left" src="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SYyACtBh-pI/AAAAAAAACxo/ewrOEXUGE8g/s320/mint.png" style="margin: 5px;" /&gt;&lt;/a&gt;&lt;a href="http://www.mint.com/"&gt;Mint&lt;/a&gt; is a great tool for tacking your expenses and investments, the iPhone application makes it even more useful.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Honorable Mentions...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=281796108&amp;amp;mt=8"&gt;&lt;b&gt;Evernote&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=281796108&amp;amp;mt=8"&gt;&lt;img align="left" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SYyAE0xThWI/AAAAAAAACxw/QawugTsyY9s/s320/evernote.png" style="margin: 5px;" /&gt;&lt;/a&gt;I still thing Evernote is a great tool, I just don't use is at much as I should.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284993459&amp;amp;mt=8"&gt;&lt;b&gt;Shazam&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284993459&amp;amp;mt=8"&gt;&lt;img align="left" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SYyAHd4d2lI/AAAAAAAACx4/oInW8IK9130/s320/shazam.png" style="margin: 5px;" /&gt;&lt;/a&gt;Shazam is one of the most clever apps I've seen.  It has been able to identify songs in some pretty poor audio situations.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=289086967&amp;amp;mt=8"&gt;&lt;b&gt;GasBag&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=289086967&amp;amp;mt=8"&gt;&lt;img align="left" src="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SYyAJ6cAAwI/AAAAAAAACyA/1Xx8iiumccM/s320/gasbag.png" style="margin: 5px;" /&gt;&lt;/a&gt;GasBag crashes way more than a public application should, but I do like the MPG tracking component of the application.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&amp;amp;mt=8"&gt;&lt;b&gt;Remote&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&amp;amp;mt=8"&gt;&lt;img align="left" src="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SYyAXeFSKUI/AAAAAAAACyI/wqFTM1etqFY/s320/remote.png" style="margin: 5px;" /&gt;&lt;/a&gt;Remote is still a great app for controlling your music from anywhere in your house, even if your house is really only about 750 sq. feet.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-1110521659624884442?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/1110521659624884442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=1110521659624884442' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1110521659624884442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1110521659624884442'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2009/02/my-top-5-iphone-applications-redux.html' title='My Top 5 iPhone Applications Redux'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SYx_3WGJ63I/AAAAAAAACxI/OeXdMLv-O8g/s72-c/zenbe.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-3648453825657819937</id><published>2008-10-15T16:36:00.000-07:00</published><updated>2008-10-15T17:40:14.725-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Connecting to iPhone Applications via Peer-To-Peer Networking</title><content type='html'>I recently found myself wanting to copy some documents to the &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=289943355&amp;amp;mt=8"&gt;AirSharing&lt;/a&gt; application on my iPhone but I was not able to connect to a Wi-Fi network at the time.&lt;br /&gt;&lt;br /&gt;As it turns out, this is really easy to do using peer-to-peer wireless networking, enabling applications like &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=289943355&amp;amp;mt=8"&gt;AirSharing&lt;/a&gt; or the &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&amp;amp;mt=8"&gt;Apple Remote&lt;/a&gt; to connect to your machine regardless of if there is an available wireless network.&lt;br /&gt;&lt;br /&gt;Note: This can be done on Windows as well, however, I will only be covering the process on a Mac.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;First you need to create a new network on your Mac by selecting your AirPort menu item and choosing "Create Network...".&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJJNubIWI/AAAAAAAACoc/q3AoXm5HJA4/s1600-h/Picture+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJJNubIWI/AAAAAAAACoc/szC1Z-Q8pks/s200-R/Picture+1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Choose a name for your network, and optionally require a password (I would suggest adding a password to restrict access to your machine).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJ-7RdTdI/AAAAAAAACok/sba-y8oXCd0/s1600-h/Picture+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJ-7RdTdI/AAAAAAAACok/GxdqT0lXBjc/s320-R/Picture+2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt; On your iPhone, tap Setttings then Wi-Fi.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaME3Z7FqI/AAAAAAAACpc/QFqbQ-cz6Zg/s1600-h/IMG_0001.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaME3Z7FqI/AAAAAAAACpc/fDMUiOTYUnc/s320-R/IMG_0001.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Your phone should find the network you just created, tap it and enter your password if you chose to set one up.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKIgXpz7I/AAAAAAAACpM/wB-k5kJqcV0/s1600-h/IMG_0003.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKIgXpz7I/AAAAAAAACpM/o_PvqpJ1y4k/s320-R/IMG_0003.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Now open AirSharing.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKK-cMWKI/AAAAAAAACpU/VuN0ojTwu1s/s1600-h/IMG_0005.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKK-cMWKI/AAAAAAAACpU/1w3AQ4WspAg/s320-R/IMG_0005.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Back on your Mac, from the Finder menu, select "Connect to Server..." (this can also be opened by pressing Command+K on your keyboard).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJ_316O8I/AAAAAAAACos/LT_EaQlncCI/s1600-h/Picture+3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJ_316O8I/AAAAAAAACos/t5w1-wRzFtI/s200-R/Picture+3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Enter the address specified by AirSharing for connecting and click "Connect".&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKBInVZjI/AAAAAAAACo0/fH1L5JT-s-U/s1600-h/Picture+4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKBInVZjI/AAAAAAAACo0/EGFhxYVacpg/s320-R/Picture+4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;A finder window will open with the AirSharing share and a mounted disk will appear on your desktop.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKFPo8CEI/AAAAAAAACpE/HxFkQFWvJmY/s1600-h/Picture+6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKFPo8CEI/AAAAAAAACpE/CRQ_Ly4u1pA/s320-R/Picture+6.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKCV6ZrRI/AAAAAAAACo8/R0Tx8aGEWVE/s1600-h/Picture+5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaKCV6ZrRI/AAAAAAAACo8/T6oyNiUx5uE/s320-R/Picture+5.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;As I mentioned above, this tip is not limited to the &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=289943355&amp;amp;mt=8"&gt;AirSharing&lt;/a&gt; application.&amp;nbsp; Any iPhone application that uses wireless connectivity to interface with your machine, such as the &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&amp;amp;mt=8"&gt;Apple Remote&lt;/a&gt;, should work with this method.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-3648453825657819937?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/3648453825657819937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=3648453825657819937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/3648453825657819937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/3648453825657819937'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/10/connecting-to-iphone-applications-via.html' title='Connecting to iPhone Applications via Peer-To-Peer Networking'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Lh3Pr0ATa7Q/SPaJJNubIWI/AAAAAAAACoc/szC1Z-Q8pks/s72-Rc/Picture+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-5768298868619112537</id><published>2008-08-15T08:47:00.000-07:00</published><updated>2008-08-15T09:48:14.821-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='active directory'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='forms authentication'/><title type='text'>Active Directory Role Provider</title><content type='html'>&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: Consolas, "Courier New", Courier, Monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;I've been using the ActiveDirectoryMembershipProvider to allow my users to login to a custom ASP.Net site with their AD credentials and it is pretty straight forward.  Recently I needed to add more granularity to who can view various parts of the site.  I wanted to take advantage of our existing AD groups so I assumed there would be something like an ActiveDirectoryRoleProvider as well.  After a little searching, it became clear that wasn't the case, so I decided to roll my own.&lt;br /&gt;&lt;br /&gt;Creating a custom role provider is pretty easy, all you have to do is create a new class and inherit RoleProvider:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;public class ActiveDirectoryRoleProvider : RoleProvider&lt;br /&gt;{}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You will have to create stubs for all the inherited members.  We only need to implement a couple of them to get basic role membership checking.  We need to get our AD configuration information out of the Web.Config values, so we'll create a few properties and override the Initialize method:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ConnectionStringName { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ConnectionUsername { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ConnectionPassword { get; set; }&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; AttributeMapUsername { get; set; }&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize(&lt;span class="kwrd"&gt;string&lt;/span&gt; name, NameValueCollection config)&lt;br /&gt;{&lt;br /&gt;    ConnectionStringName = config[&lt;span class="str"&gt;"connectionStringName"&lt;/span&gt;];&lt;br /&gt;    ConnectionUsername = config[&lt;span class="str"&gt;"connectionUsername"&lt;/span&gt;];&lt;br /&gt;    ConnectionPassword = config[&lt;span class="str"&gt;"connectionPassword"&lt;/span&gt;];&lt;br /&gt;    AttributeMapUsername = config[&lt;span class="str"&gt;"attributeMapUsername"&lt;/span&gt;];&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Initialize(name, config);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we'll override GetRolesForUser which is the bulk of our implementation.  We use the DirectorySearcher class in System.DirectoryServices to query AD for the passed username.  We then pull the memberOf property from that user and extract the CN component for each entry as the role:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] GetRolesForUser(&lt;span class="kwrd"&gt;string&lt;/span&gt; username)&lt;br /&gt;{&lt;br /&gt;    var allRoles = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;    var root = &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectoryEntry(WebConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString, ConnectionUsername, ConnectionPassword);&lt;br /&gt;&lt;br /&gt;    var searcher = &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectorySearcher(root, &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(CultureInfo.InvariantCulture, &lt;span class="str"&gt;"(&amp;amp;(objectClass=user)({0}={1}))"&lt;/span&gt;, AttributeMapUsername, username));&lt;br /&gt;    searcher.PropertiesToLoad.Add(&lt;span class="str"&gt;"memberOf"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    SearchResult result = searcher.FindOne();&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (result != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(result.Path))&lt;br /&gt;    {&lt;br /&gt;        DirectoryEntry user = result.GetDirectoryEntry();&lt;br /&gt;&lt;br /&gt;        PropertyValueCollection groups = user.Properties[&lt;span class="str"&gt;"memberOf"&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; path &lt;span class="kwrd"&gt;in&lt;/span&gt; groups)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt;[] parts = path.Split(&lt;span class="str"&gt;','&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (parts.Length &amp;gt; 0)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; part &lt;span class="kwrd"&gt;in&lt;/span&gt; parts)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt;[] p = part.Split(&lt;span class="str"&gt;'='&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (p[0].Equals(&lt;span class="str"&gt;"cn"&lt;/span&gt;, StringComparison.OrdinalIgnoreCase))&lt;br /&gt;                    {&lt;br /&gt;                        allRoles.Add(p[1]);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; allRoles.ToArray();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And finally we need to override IsUserInRole so we can easily check for role membership in code:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsUserInRole(&lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; roleName)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt;[] roles = GetRolesForUser(username);&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; role &lt;span class="kwrd"&gt;in&lt;/span&gt; roles)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (role.Equals(roleName, StringComparison.OrdinalIgnoreCase))&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the the full code (minus the unimplemented inherited methods):&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ActiveDirectoryRoleProvider : RoleProvider&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ConnectionStringName { get; set; }&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ConnectionUsername { get; set; }&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ConnectionPassword { get; set; }&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; AttributeMapUsername { get; set; }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize(&lt;span class="kwrd"&gt;string&lt;/span&gt; name, NameValueCollection config)&lt;br /&gt;    {&lt;br /&gt;        ConnectionStringName = config[&lt;span class="str"&gt;"connectionStringName"&lt;/span&gt;];&lt;br /&gt;        ConnectionUsername = config[&lt;span class="str"&gt;"connectionUsername"&lt;/span&gt;];&lt;br /&gt;        ConnectionPassword = config[&lt;span class="str"&gt;"connectionPassword"&lt;/span&gt;];&lt;br /&gt;        AttributeMapUsername = config[&lt;span class="str"&gt;"attributeMapUsername"&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.Initialize(name, config);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsUserInRole(&lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; roleName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt;[] roles = GetRolesForUser(username);&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; role &lt;span class="kwrd"&gt;in&lt;/span&gt; roles)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (role.Equals(roleName, StringComparison.OrdinalIgnoreCase))&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] GetRolesForUser(&lt;span class="kwrd"&gt;string&lt;/span&gt; username)&lt;br /&gt;    {&lt;br /&gt;        var allRoles = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;        var root = &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectoryEntry(WebConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString, ConnectionUsername, ConnectionPassword);&lt;br /&gt;&lt;br /&gt;        var searcher = &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectorySearcher(root, &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(CultureInfo.InvariantCulture, &lt;span class="str"&gt;"(&amp;amp;(objectClass=user)({0}={1}))"&lt;/span&gt;, AttributeMapUsername, username));&lt;br /&gt;        searcher.PropertiesToLoad.Add(&lt;span class="str"&gt;"memberOf"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        SearchResult result = searcher.FindOne();&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (result != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(result.Path))&lt;br /&gt;        {&lt;br /&gt;            DirectoryEntry user = result.GetDirectoryEntry();&lt;br /&gt;&lt;br /&gt;            PropertyValueCollection groups = user.Properties[&lt;span class="str"&gt;"memberOf"&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; path &lt;span class="kwrd"&gt;in&lt;/span&gt; groups)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;string&lt;/span&gt;[] parts = path.Split(&lt;span class="str"&gt;','&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (parts.Length &amp;gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; part &lt;span class="kwrd"&gt;in&lt;/span&gt; parts)&lt;br /&gt;                    {&lt;br /&gt;                        &lt;span class="kwrd"&gt;string&lt;/span&gt;[] p = part.Split(&lt;span class="str"&gt;'='&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (p[0].Equals(&lt;span class="str"&gt;"cn"&lt;/span&gt;, StringComparison.OrdinalIgnoreCase))&lt;br /&gt;                        {&lt;br /&gt;                            allRoles.Add(p[1]);&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; allRoles.ToArray();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Add the role provider to your Web.Config:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;roleManager&lt;/span&gt; &lt;span class="attr"&gt;enabled&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="attr"&gt;defaultProvider&lt;/span&gt;&lt;span class="kwrd"&gt;="ADRoleProvider"&lt;/span&gt; &lt;span class="attr"&gt;cacheRolesInCookie&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="attr"&gt;cookieName&lt;/span&gt;&lt;span class="kwrd"&gt;=".ASPXROLES"&lt;/span&gt; &lt;span class="attr"&gt;cookiePath&lt;/span&gt;&lt;span class="kwrd"&gt;="/"&lt;/span&gt;&lt;br /&gt;                 &lt;span class="attr"&gt;cookieTimeout&lt;/span&gt;&lt;span class="kwrd"&gt;="30"&lt;/span&gt; &lt;span class="attr"&gt;cookieRequireSSL&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;cookieSlidingExpiration&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="attr"&gt;createPersistentCookie&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;cookieProtection&lt;/span&gt;&lt;span class="kwrd"&gt;="All"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;providers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;clear&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="ActiveDirectoryRoleProvider"&lt;/span&gt; &lt;span class="attr"&gt;connectionStringName&lt;/span&gt;&lt;span class="kwrd"&gt;="ADConnectionString"&lt;/span&gt; &lt;span class="attr"&gt;connectionUsername&lt;/span&gt;&lt;span class="kwrd"&gt;="username"&lt;/span&gt;&lt;br /&gt;                 &lt;span class="attr"&gt;connectionPassword&lt;/span&gt;&lt;span class="kwrd"&gt;="password"&lt;/span&gt; &lt;span class="attr"&gt;attributeMapUsername&lt;/span&gt;&lt;span class="kwrd"&gt;="sAMAccountName"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="ActiveDirectoryRoleProvider"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;providers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;roleManager&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can then check the roles of your user in code like so:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;Roles.IsUserInRole(&lt;span class="str"&gt;"My Group"&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or control access to entire directories via the Web.Config:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;location&lt;/span&gt; &lt;span class="attr"&gt;path&lt;/span&gt;&lt;span class="kwrd"&gt;="RestrictedSubDirectory"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;authorization&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;allow&lt;/span&gt; &lt;span class="attr"&gt;roles&lt;/span&gt;&lt;span class="kwrd"&gt;="My Group"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;deny&lt;/span&gt; &lt;span class="attr"&gt;users&lt;/span&gt;&lt;span class="kwrd"&gt;="*"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;authorization&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;location&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-5768298868619112537?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/5768298868619112537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=5768298868619112537' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5768298868619112537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5768298868619112537'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/08/active-directory-role-provider.html' title='Active Directory Role Provider'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-5358347782078705243</id><published>2008-07-29T11:06:00.000-07:00</published><updated>2008-07-29T11:13:18.457-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='att'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='3g'/><title type='text'>My Fancy New 3G Wireless Card</title><content type='html'>&lt;img src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SI9dEXQmd5I/AAAAAAAAB38/EFZQf6VANyY/s320-R/att_usbconnect881_l.gif" style="border: 0pt none ; float: left;" /&gt;Lately I have been finding myself in more and more situations where I am giving a presentation and I need wireless connectivity and it isn't readily available.&amp;nbsp; Yesterday I finally broke down and picked up a &lt;a href="http://www.wireless.att.com/cell-phone-service/cell-phone-details/?device=AT%26T+USBConnect+881&amp;amp;q_sku=sku2640240"&gt;USBConnect 881&lt;/a&gt; card from AT&amp;amp;T, and so far, I like it.&amp;nbsp; For about $60 a month the cost isn't too bad for what you are getting, and in using it last night, the 3G speeds were pretty good for doing what I needed to do.&amp;nbsp; I orginally wanted to go with an Express PCI card for my Mac, but opted for the USB card for more flexibility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-5358347782078705243?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/5358347782078705243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=5358347782078705243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5358347782078705243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5358347782078705243'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/07/my-fancy-new-3g-wireless-card.html' title='My Fancy New 3G Wireless Card'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_Lh3Pr0ATa7Q/SI9dEXQmd5I/AAAAAAAAB38/EFZQf6VANyY/s72-Rc/att_usbconnect881_l.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-5562183209164268182</id><published>2008-07-19T10:34:00.000-07:00</published><updated>2008-07-19T13:24:03.434-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>My Top 5 iPhone Applications</title><content type='html'>So of course I picked up a shiny new iPhone 3G on launch day.&amp;nbsp; I was lucky to be in Hillsboro Oregon at the time which meant my line was not too long and I got to take advantage of no sales tax.&amp;nbsp; It's been a while since I've posted (I'm going to correct that in the next few weeks), so I thought I'd do a round-up of my top 5 favorite 3rd party applications.&amp;nbsp; In no particular order here they are...&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&amp;amp;mt=8"&gt;&lt;b&gt;Remote&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&amp;amp;mt=8"&gt;&lt;img align="left" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SIIqtI5EnZI/AAAAAAAAB3M/_yh95JjZwP4/s400-R/Remote.png" style="margin: 5px;" /&gt;&lt;/a&gt;This is Apple's fantastic iTunes remote.&amp;nbsp; I don't have an Apple TV yet, but I have been playing with this with my iTunes library on my laptop and it works flawlessly.&amp;nbsp; I can't wait to get my condo all setup so I can take full advantage of this tool.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284596345&amp;amp;mt=8"&gt;&lt;b&gt;Cube Runner&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284596345&amp;amp;mt=8"&gt;&lt;img align="left" src="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SIIyDTskScI/AAAAAAAAB3U/1yjK3IqbJAc/s320-R/CubRunner.png" style="margin: 5px;" /&gt;&lt;/a&gt;This has to be one of the less polished games in the iTunes store, but it is addicting.  The basic goal is to fly your little ship through a minefield of cubes, if you hit a cube, you die.  You pretty much just compete against yourself for high score.  The game could use stages, so you don't just end up playing the same first level over and over again, but short of that, it is an awesome first showing for a casual game.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=281796108&amp;amp;mt=8"&gt;&lt;b&gt;Evernote&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://draft.blogger.com/goog_1216488897648"&gt;&lt;img align="left" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SIIyFrGCfCI/AAAAAAAAB3c/0_VmX2WLU5s/s320-R/Evernote.png" style="margin: 5px;" /&gt;&lt;/a&gt;&lt;a href="http://evernote.com/"&gt;Evernote&lt;/a&gt; is a great desktop tool for knowledge capture.&amp;nbsp; It works on Mac and Windows, and with their latest release they have included an iPhone client.&amp;nbsp; This comes in handy so often in my life when I have meetings where lots of white boarding occurs.&amp;nbsp; All I have to do is open Evernote and take a picture of the whiteboard and the image is automatically synced with my laptop.&amp;nbsp; On top of that, Evernote has fantastic OCR technology allowing you to then search all of your content, even my aweful whiteboard chicken scratch gets properly indexed.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284708449&amp;amp;mt=8"&gt;&lt;b&gt;Urbanspoon&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284708449&amp;amp;mt=8"&gt;&lt;img align="left" src="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SIIyIf4RcoI/AAAAAAAAB30/Aa6B1A-_FE0/s320-R/UrbanSpoon.png" style="margin: 5px;" /&gt;&lt;/a&gt;I always have a terrible time picking a restaurant when it comes time to go out to eat.&amp;nbsp; This tool solves that problem in a fun way.&amp;nbsp; Using location based services, Urbanspoon will zero in on your city.&amp;nbsp; You then lock in your options, be it neighborhood, cuisine or price.&amp;nbsp; Then simply shake your phone and Urbanspoon will randomly pick a place for you, if you don't like it, shake it again!&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="margin: 5px;"&gt;&lt;b&gt;Tie: &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284035177&amp;amp;mt=8"&gt;Pandora&lt;/a&gt; and &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284916679&amp;amp;mt=8"&gt;Last.fm&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284035177&amp;amp;mt=8"&gt;&lt;img align="left" src="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SIIyHfw4TKI/AAAAAAAAB3s/rsU9q0G9l1g/s320-R/Pandora.png" style="margin: 5px;" /&gt;&lt;/a&gt;&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284916679&amp;amp;mt=8"&gt;&lt;img align="left" src="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SIIyGtfx-PI/AAAAAAAAB3k/7JKAUzJPjqY/s320-R/LastFm.png" style="margin: 5px;" /&gt;&lt;/a&gt;Both of these applications do very similar things.  Based on the same technologies of their respective web sites, you can get a customized radio station based on your music tastes. &lt;a href="http://pandora.com/"&gt; Pandora&lt;/a&gt; is based on the &lt;a href="http://en.wikipedia.org/wiki/Music_Genome_Project"&gt;Music Genome Project&lt;/a&gt;, which uses a more scientific approach to matching tunes. &lt;a href="http://www.last.fm/"&gt; Last.fm&lt;/a&gt; relies on social networks and listening patterns to do something very similar.  I am a Last.fm user, so I like this app for that reason, however, I believe Pandora streams much more reliably with less waiting for buffering.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-5562183209164268182?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/5562183209164268182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=5562183209164268182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5562183209164268182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/5562183209164268182'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/07/my-top-5-iphone-applications.html' title='My Top 5 iPhone Applications'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_Lh3Pr0ATa7Q/SIIqtI5EnZI/AAAAAAAAB3M/_yh95JjZwP4/s72-Rc/Remote.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-3909530287516044521</id><published>2008-06-09T15:23:00.000-07:00</published><updated>2008-06-09T15:26:30.682-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wwdc'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>WWDC 2008 Keynote</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SE2t6_JvflI/AAAAAAAAByA/Y0EEzs6guJo/s1600-h/IMG_0185.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SE2t6_JvflI/AAAAAAAAByA/Y0EEzs6guJo/s320/IMG_0185.JPG" alt="" id="BLOGGER_PHOTO_ID_5210011572833844818" border="0" /&gt;&lt;/a&gt;I got to attend the Apple Worldwide Developers Conference 2008 keynote this morning, it was a lot of fun.  Luckily for me I didn't have to get there at 6am like my colleges who held a spot for me.  I got to see Steve Balmer speak at Mix '08 back in March, he was good, but doesn't hold a candle to watching Mr. Jobs.&lt;br /&gt;&lt;br /&gt;On the left is a picture I took from line, so may nerds, myself included.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-3909530287516044521?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/3909530287516044521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=3909530287516044521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/3909530287516044521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/3909530287516044521'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/06/wwdc-2008-keynote.html' title='WWDC 2008 Keynote'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_Lh3Pr0ATa7Q/SE2t6_JvflI/AAAAAAAAByA/Y0EEzs6guJo/s72-c/IMG_0185.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-6022038059973186240</id><published>2008-06-01T22:27:00.001-07:00</published><updated>2008-06-01T22:38:21.474-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><title type='text'>TripIt - One of My Favorite Tools</title><content type='html'>I tend to fly fairly often (at least once a month).  I have been using &lt;a href="http://www.tripit.com"&gt;TripIt&lt;/a&gt; for a few months now and I'm a big fan.  TripIt helps you track your travels very easily.  All you do is forward your email confirmations for your flights, hotels or rental cars and TripIt will consume the information and keep all your travel information in one handy place.  That combined with the ability to subscribe to your trip details via an iCal feed, as well as a new mobile site that looks great on the iPhone, make it a great tool for any frequent traveler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-6022038059973186240?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/6022038059973186240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=6022038059973186240' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6022038059973186240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6022038059973186240'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/06/tripit-one-of-my-favorite-tools.html' title='TripIt - One of My Favorite Tools'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-8342717052057675059</id><published>2008-05-19T13:13:00.000-07:00</published><updated>2008-06-26T23:11:49.117-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual studio'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='resharper'/><title type='text'>ReSharper 4.0 Nightly Build Finally Stable?</title><content type='html'>My all time favorite add-on for Visual Studio, &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt;, has finally marked &lt;a href="http://www.jetbrains.net/confluence/display/ReSharper/ReSharper+4.0+Nightly+Builds"&gt;one of their nightly builds&lt;/a&gt; for the upcoming 4.0 version as "Stable".  This is good news since 4.0 brings support for Visual Studio 2008 and the new .Net 3.5 language features such as LINQ, Extension Methods and Automatic Properties.  ReSharper has become a tool that I find hard to live without and I have been using the nightly builds for the last couple months.  For the most part they have been good but I'm hoping this means they will have a final release soon, originally they promised the release to be in mid-Februrary.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;[UPDATE]:&lt;/span&gt; Looks like they have finally launched the beta for 4.0, get it &lt;a href="http://www.jetbrains.com/resharper/beta/beta.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;[UPDATE 6/26/2008]:&lt;/span&gt; Hooray, the final version was released last week, get it &lt;a href="http://www.jetbrains.com/resharper/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-8342717052057675059?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/8342717052057675059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=8342717052057675059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/8342717052057675059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/8342717052057675059'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/05/resharper-40-nightly-build-finally.html' title='ReSharper 4.0 Nightly Build Finally Stable?'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-6291707787485578048</id><published>2008-05-04T17:41:00.000-07:00</published><updated>2008-05-04T18:30:06.796-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silicon valley'/><category scheme='http://www.blogger.com/atom/ns#' term='random'/><title type='text'>Maker Faire 2008</title><content type='html'>Today I attended the &lt;a href="http://www.makerfaire.com/"&gt;Bay Area Maker Faire 2008&lt;/a&gt;.  Over all it was an entertaining trip, except for the hour we sat on the onramp to get to the fairgrounds.  I got to see &lt;a href="http://www.adamsavage.com/"&gt;Adam Savage&lt;/a&gt; of the &lt;a href="http://dsc.discovery.com/fansites/mythbusters/mythbusters.html"&gt;Mythbusters&lt;/a&gt; speak, as well as enjoy a couple rounds of Battle Bots.  And for your viewing pleasure, here are some Battle Bot videos taken with my new &lt;a href="http://www.theflip.com/"&gt;Flip Video&lt;/a&gt; camera.&lt;br /&gt;&lt;br /&gt;&lt;object height="350" width="425"&gt; &lt;param name="movie" value="http://www.youtube.com/v/zNwcrYwCExw"&gt;  &lt;embed src="http://www.youtube.com/v/zNwcrYwCExw" type="application/x-shockwave-flash" height="350" width="425"&gt;&lt;/embed&gt;  &lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt; &lt;param name="movie" value="http://www.youtube.com/v/CjxceCFyt1M"&gt; &lt;/param&gt; &lt;embed src="http://www.youtube.com/v/CjxceCFyt1M" type="application/x-shockwave-flash" width="425" height="350"&gt; &lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-6291707787485578048?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/6291707787485578048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=6291707787485578048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6291707787485578048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6291707787485578048'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/05/maker-faire-2008.html' title='Maker Faire 2008'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-215073683739909702</id><published>2008-04-29T13:52:00.000-07:00</published><updated>2008-04-29T14:05:28.613-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>New Date and Time Data Types in SQL Server 2008</title><content type='html'>I am delinquent in the &lt;a href="http://slalomdev.blogspot.com/2008/03/one-week-challenge.html"&gt;one-a-week challenge&lt;/a&gt; post for last week, and on top of that this is going to be a pretty lazy one, as I'm just going to refer to a good article I just found.&lt;br /&gt;&lt;br /&gt;My current client has taken to early adopting the latest SQL Server 2008 CTP.  One of my favorite new features are the enhanced date and time data types.  &lt;a href="http://www.sql-server-performance.com/authors/dasanka.aspx"&gt;Dinesh Asanka&lt;/a&gt; has a good summary of these new types over at &lt;a href="http://www.sql-server-performance.com"&gt;SQL Server Performance&lt;/a&gt; and you should really just go check out his &lt;a href="http://www.sql-server-performance.com/articles/dev/datetime_2008_p1.aspx"&gt;article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My favorite additions are the DATE and TIME data types, how many times have you wanted to just specify a date or time portion of a value and had to do some sort of crazy truncation or logic in code to keep it straight?  Well no longer.&lt;br /&gt;&lt;br /&gt;Another great addition is the DATETIME2 data type, though its not going to win any awards for clever naming, the gist of it is that you now can specify the millisecond resolution of your DATETIME, previously it was defaulted to 3 decimal places, now you can specify from 0 to 7.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-215073683739909702?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/215073683739909702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=215073683739909702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/215073683739909702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/215073683739909702'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/04/new-date-and-time-data-types-in-sql.html' title='New Date and Time Data Types in SQL Server 2008'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-1542388208468908366</id><published>2008-04-20T20:11:00.000-07:00</published><updated>2009-10-24T09:52:17.903-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tfs'/><title type='text'>TFS Blog Series: Setting Up Projects</title><content type='html'>Welcome to the second entry in &lt;a href="http://joelforman.blogspot.com/"&gt;Joel&lt;/a&gt; and my series on Microsoft Teams System (aka Team Foundation Server, aka TFS).  To catch up, check out the previous entries in the series:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://joelforman.blogspot.com/2008/04/tfs-blog-series-overview-part-1.html"&gt;Overview&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;In this post I'm going to cover the details of creating a new team project including the intricacies of setting up project permissions and permissions for the corresponding SharePoint and Reporting Services.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creating a New Project&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Creating a new project in TFS is pretty straight forward and involves the following steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Launch Team Explorer (Visual Studio).&lt;/li&gt;&lt;li&gt;In the Team Explorer toolbox, right click on your server name and choose "New Team Project...".&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwLCncsI5I/AAAAAAAABvA/4nOUG9FuXKc/s1600-h/Picture+2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191536610028299154" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwLCncsI5I/AAAAAAAABvA/4nOUG9FuXKc/s400/Picture+2.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;In the wizard, give your project a proper name and description.  You can name a project anything you want, but you should give some thought to this before committing to something because you cannot change this once the project is created.  If you work in an organization like ours where you have many projects, a consistent naming convention is important.  We use {ClientName}.{ProjectName}, so for this test I will create a project called Slalom.Test, Slalom because it is an internal project so we are our own client and Test because I'm just going to delete this thing when I'm done.&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAwLnXcsI6I/AAAAAAAABvI/12UUN5yLdhA/s1600-h/Picture+1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191537241388491682" src="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAwLnXcsI6I/AAAAAAAABvI/12UUN5yLdhA/s400/Picture+1.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Choose a project template.  TFS comes with two built in, however you can create your own custom templates as well, allowing you to have some pre-canned work items generated for every project you create.  We'll talk about template customization later in the series, for now we will just choose Agile.&lt;br /&gt;&lt;a href="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SAwMI3csI7I/AAAAAAAABvQ/B4WbtjKl5vI/s1600-h/Picture+3.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191537816914109362" src="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SAwMI3csI7I/AAAAAAAABvQ/B4WbtjKl5vI/s400/Picture+3.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Choose where you want your source control, by default TFS builds out a new repository, in most cases this is what you will want to do.&lt;br /&gt;&lt;a href="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SAwMmHcsI8I/AAAAAAAABvY/NbjwXdy1BBo/s1600-h/Picture+4.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191538319425283010" src="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SAwMmHcsI8I/AAAAAAAABvY/NbjwXdy1BBo/s400/Picture+4.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Once you click finish and let TFS build out your project you will have a new project listed in Team Explorer.&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwMvncsI9I/AAAAAAAABvg/j1Kj4mw30XA/s1600-h/Picture+5.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191538482634040274" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwMvncsI9I/AAAAAAAABvg/j1Kj4mw30XA/s400/Picture+5.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Setting Project Permissions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TFS allows you apply roles to your different users, these roles can be adjusted by right clicking on your team project and choosing "Team Project Settings &amp;gt; Group Membership..."&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwN2ncsI-I/AAAAAAAABvo/-1fRuvraF8I/s1600-h/Picture+1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191539702404752354" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwN2ncsI-I/AAAAAAAABvo/-1fRuvraF8I/s400/Picture+1.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwN4ncsI_I/AAAAAAAABvw/apAVs4Ihagk/s1600-h/Picture+2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191539736764490738" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwN4ncsI_I/AAAAAAAABvw/apAVs4Ihagk/s400/Picture+2.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For a project, there are four groups available for classifying your users rights:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Readers - Users that can access the project, but are not able to modify work items or check in code.&lt;/li&gt;&lt;li&gt;Project Administrators - Users that can do anything within the project.&lt;/li&gt;&lt;li&gt;Contributers - Users that can make changes in the project but are now allowed administrative tasks.&lt;/li&gt;&lt;li&gt;Build Services - System role for building the project (for service accounts only).&lt;/li&gt;&lt;/ol&gt;Most people generally fall under project administrators or contributors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Setting SharePoint and Reporting Services Permissions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately setting permissions within TFS does not complete the process.  Permissions must also be granted individually to the corresponding SharePoint site and SQL Server Reporting Services.&lt;br /&gt;&lt;br /&gt;For SSRS permissions, we have simplified this by creating a Team Foundation Server Users domain group and putting all valid TFS users into that group, then giving that group read permission on the reporting server.  This saves us from having to set these permissions each time.&lt;br /&gt;&lt;br /&gt;For SharePoint we still must grant users proper access, do this follow these steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Access your project portal (right click on your project and choose "Show Project Portal...") as an administrator.&lt;br /&gt;&lt;a href="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SAwRxHcsJAI/AAAAAAAABv4/a0Y0VjhTY9I/s1600-h/Picture+6.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191544005961982978" src="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SAwRxHcsJAI/AAAAAAAABv4/a0Y0VjhTY9I/s400/Picture+6.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Choose "Site Settings" from the "Site Actions" drop down on the site.&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwShncsJBI/AAAAAAAABwA/-FIphVdwzO8/s1600-h/Picture+1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191544839185638418" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwShncsJBI/AAAAAAAABwA/-FIphVdwzO8/s400/Picture+1.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Choose "Advanced Permissions" from "Users and Permissions".&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAwSkXcsJCI/AAAAAAAABwI/L1thIw6qFwQ/s1600-h/Picture+2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191544886430278690" src="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAwSkXcsJCI/AAAAAAAABwI/L1thIw6qFwQ/s400/Picture+2.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Choose "New" to add your users and give them specific SharePoint permissions.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SAwSnHcsJDI/AAAAAAAABwQ/jmjpBrEul0Y/s1600-h/Picture+3.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191544933674918962" src="http://bp2.blogger.com/_Lh3Pr0ATa7Q/SAwSnHcsJDI/AAAAAAAABwQ/jmjpBrEul0Y/s400/Picture+3.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwSpncsJEI/AAAAAAAABwY/lcem5fO_9Xs/s1600-h/Picture+4.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5191544976624591938" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwSpncsJEI/AAAAAAAABwY/lcem5fO_9Xs/s400/Picture+4.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-1542388208468908366?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/1542388208468908366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=1542388208468908366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1542388208468908366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1542388208468908366'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/04/tfs-blog-series-setting-up-projects.html' title='TFS Blog Series: Setting Up Projects'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAwLCncsI5I/AAAAAAAABvA/4nOUG9FuXKc/s72-c/Picture+2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-6520631556046488713</id><published>2008-04-13T15:50:00.000-07:00</published><updated>2008-04-13T16:03:54.568-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>Bad Dog</title><content type='html'>Well, this post is a little bit of a cop-out, but I'm still counting it for the "&lt;a href="http://slalomdev.blogspot.com/2008/03/one-week-challenge.html"&gt;one a week&lt;/a&gt;" challenge.  Next week I will get part two of &lt;a href="http://joelforman.blogspot.com/2008/04/tfs-blog-series-overview-part-1.html"&gt;Joel and my series on TFS&lt;/a&gt; out.&lt;br /&gt;&lt;br /&gt;My mom called me this morning, she was upset because her dog jumped up and grabbed her iPhone off the kitchen counter in the middle of the night, and pretty much destroyed it.  It will power on, but the screen is completely white.  When I plugged it in, it did sync, so we were able to get her a new one and restore from the backup.  Check out the photos below:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAKQWTOKqxI/AAAAAAAABts/NmLIe8M1G-4/s1600-h/IMG_0126.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAKQWTOKqxI/AAAAAAAABts/NmLIe8M1G-4/s400/IMG_0126.JPG" alt="" id="BLOGGER_PHOTO_ID_5188868433475447570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAKQxjOKqyI/AAAAAAAABt0/PFSWvfX-9Dc/s1600-h/IMG_0131.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAKQxjOKqyI/AAAAAAAABt0/PFSWvfX-9Dc/s400/IMG_0131.JPG" alt="" id="BLOGGER_PHOTO_ID_5188868901626882850" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAKQ4jOKqzI/AAAAAAAABt8/uLnGmuaiXqs/s1600-h/IMG_0135.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_Lh3Pr0ATa7Q/SAKQ4jOKqzI/AAAAAAAABt8/uLnGmuaiXqs/s400/IMG_0135.JPG" alt="" id="BLOGGER_PHOTO_ID_5188869021885967154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SAKQ-zOKq0I/AAAAAAAABuE/mKW04DXRt1Q/s1600-h/IMG_0130.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_Lh3Pr0ATa7Q/SAKQ-zOKq0I/AAAAAAAABuE/mKW04DXRt1Q/s400/IMG_0130.JPG" alt="" id="BLOGGER_PHOTO_ID_5188869129260149570" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-6520631556046488713?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/6520631556046488713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=6520631556046488713' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6520631556046488713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6520631556046488713'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/04/bad-dog.html' title='Bad Dog'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_Lh3Pr0ATa7Q/SAKQWTOKqxI/AAAAAAAABts/NmLIe8M1G-4/s72-c/IMG_0126.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-4953918023062709503</id><published>2008-04-01T10:12:00.001-07:00</published><updated>2008-04-01T15:51:47.641-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silicon valley'/><category scheme='http://www.blogger.com/atom/ns#' term='random'/><title type='text'>My First "Valley" Event</title><content type='html'>Well as a follow-up to my last &lt;a href="http://slalomdev.blogspot.com/2008/03/valley-vs-emerald-city.html"&gt;post&lt;/a&gt; about how Seattle compares to The Valley last night I attended my first "Valley" event.  A friend of mine that works for a PR firm down here told me about &lt;a href="http://www.mozilla.org/"&gt;Mozilla&lt;/a&gt;'s 10 year anniversary celebration that was going on last night.  So I decided to check it out.  It was pretty packed when I got there, but they had just made it open bar, so thanks Mozilla for the gin and tonics.  There were a lot of .com folks chatting it up, a few folks that were clearly Mozilla contributors and a few valley celebrities (or so I'm told, I didn't really know who any of them were).  At one point &lt;a href="http://en.wikipedia.org/wiki/Mitchell_Baker"&gt;Mitchell Baker&lt;/a&gt; (I think) and &lt;a href="http://en.wikipedia.org/wiki/Brendan_Eich"&gt;Brendan Eich&lt;/a&gt; got up and thanked everyone and said some words that most of us couldn't hear.  All-in-all it was an interesting experience and I hope to find my way into more of these things.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;UPDATE:&lt;/span&gt; Here is proof that I was there, or at least that the back of my head was: &lt;a href="http://valleywag.com/photogallery/mozilla10/1001073788"&gt;http://valleywag.com/photogallery/mozilla10/1001073788&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-4953918023062709503?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/4953918023062709503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=4953918023062709503' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/4953918023062709503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/4953918023062709503'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/04/my-first-valley-event.html' title='My First &quot;Valley&quot; Event'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-6574124995056295508</id><published>2008-03-30T17:30:00.000-07:00</published><updated>2008-03-30T17:36:50.656-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silicon valley'/><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='seattle'/><title type='text'>The Valley vs. The Emerald City</title><content type='html'>I don't know, how about we call this one an opinion piece.   So the New York Times published an &lt;a href="http://www.nytimes.com/2008/02/08/technology/08nation.html?_r=1&amp;amp;oref=slogin"&gt;article&lt;/a&gt; about how Seattle is becoming the next Silicon Valley.  Glenn Kelman of &lt;a href="http://www.redfin.com"&gt;Redfin&lt;/a&gt; then &lt;a href="http://blog.redfin.com/blog/2008/02/the_next_silicon_valley.html"&gt;commented&lt;/a&gt; on it favorably.  Then &lt;a href="http://www.techcrunch.com"&gt;TechCrunch&lt;/a&gt;'s Michael Arrington &lt;a href="http://www.techcrunch.com/2008/02/15/an-outsiders-flawed-view-of-silicon-valley/"&gt;disagreed&lt;/a&gt;.  And now the &lt;a href="http://scobleizer.com/2008/02/15/seattle-vs-silicon-valley-sillyness/"&gt;rest&lt;/a&gt; of &lt;a href="http://valleywag.com/357194/michael-arrington-on-why-seattle-drools-valley-rules"&gt;the&lt;/a&gt; &lt;a href="http://www.drama20show.com/2008/02/15/glenn-kelman-continues-to-prove-sanity-exists-in-the-tech-world/"&gt;world&lt;/a&gt; is throwing in their two cents.  So I thought, why shouldn't I add my thoughts to the ether.&lt;br /&gt;&lt;br /&gt;I spent the better part of the last 5 years working in Seattle as a software developer.  In August I transfered to our San Francisco office for a change of scenery.  I can't claim any real insight from a start-up perspective.  I have friends who have done &lt;a href="http://www.shelfari.com/"&gt;start-ups&lt;/a&gt;, I've consulted for start-ups, but I've never been a part of starting my own, and I may never, who knows.&lt;br /&gt;&lt;br /&gt;I have a hard time believing that your likelihood of success can so be so heavily weighted by your location.  Sure, being in Silicon Valley, amidst all the others can have its advantages, especially when it comes time to start raising money or recruiting new talent.  But good ideas can come from anywhere, be it Stanford or rural Saskatchewan.&lt;br /&gt;&lt;br /&gt;If you take a look at my &lt;a href="http://www.shelfari.com"&gt;Shelfari&lt;/a&gt; reading list on the right (a Seattle based start-up that one of my good friend's from college help found) you'll see I am in the middle of reading "Founders at Work".  I find this book to be pretty interesting, and one of the most interesting things I have pulled from it is that you don't have to be in Silicon Valley to succeed.  Sure a lot of the companies profiled are based in the valley, but certainly not all of them, and the ones that weren't don't seem to have been at a disadvantage because of it.  Their keys to success are having a good idea and having smart, motivated people making that idea reality.&lt;br /&gt;&lt;br /&gt;You can live in San Francisco and try to start as many &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; and &lt;a href="http://www.digg.com"&gt;Digg&lt;/a&gt; clones as you like, good luck with that.  But its the next big thing that matters, and that can come from anywhere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-6574124995056295508?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/6574124995056295508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=6574124995056295508' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6574124995056295508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6574124995056295508'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/valley-vs-emerald-city.html' title='The Valley vs. The Emerald City'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-7455428166610678829</id><published>2008-03-22T14:57:00.000-07:00</published><updated>2008-04-20T20:07:46.374-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Learning Cocoa</title><content type='html'>With the recent release of the iPhone SDK I've gotten pretty excited about trying my hand at building some custom iPhone applications.  Since I pay the bills writing software using Microsoft technologies I rarely write anything that isn't in C# these days.  I took plenty of C and C++ centric courses in college, but frankly I've gotten rusty.&lt;br /&gt;&lt;br /&gt;Coding for the Mac and the iPhone means working with Apple's Cocoa libraries which is done in Objective-C, a language I have never spent any time with, in Xcode, an IDE I've probably opened a handful of times but never built anything in.&lt;br /&gt;&lt;br /&gt;So in the last week or so I've been doing a lot of reading on both of these subjects.  Like most things there is a wealth of information out there that can be found with a simple Google search.  In my hunting I've found a couple of resources for Cocoa, Objective-C and Xcode that I found to be the most helpful:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;a href="http://en.wikibooks.org/wiki/Programming_Mac_OS_X_with_Cocoa_for_beginners/Objective_C%2C_the_language_and_its_advantages"&gt;Programming Mac OS X with Cocoa for beginners&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Programming Mac OS X with Cocoa for beginners is a book I found on &lt;a href="http://en.wikibooks.org/wiki/Main_Page"&gt;Wikibooks&lt;/a&gt;.  This source does a good job of explaining what Cocoa and Objective-C are and especially does a good job explaining some of the unique syntax of Objective-C that at first glance might make someone who is familiar with C, C++ or C# rub their eyes in an comically exaggerated manor indicating bewilderment.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;a href="http://www.matthew-long.com/2007/11/09/xcode-30-tutorial/"&gt;Long Pointers - Xcode 3.0 Tutorial&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Xcode 3.0 tutorial on the Long Pointers blog does a great job of walking you through how you would build a windowed application in Cocoa with the Xcode tool.  It is specifically very good at outlining how you build the interface in Interface Builder and wire it up to your controller code.&lt;br /&gt;&lt;br /&gt;I am still early in my journey to become a Mac developer, but these resources definitely helped me feel like I am moving forward as I learn more.  I'm sure there are more Mac and iPhone development posts coming in the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-7455428166610678829?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/7455428166610678829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=7455428166610678829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/7455428166610678829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/7455428166610678829'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/learning-cocoa.html' title='Learning Cocoa'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-51289148539946530</id><published>2008-03-14T14:37:00.000-07:00</published><updated>2008-03-14T19:20:11.672-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvp'/><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><category scheme='http://www.blogger.com/atom/ns#' term='alt.net'/><title type='text'>What is ALT.Net</title><content type='html'>One of the bloggers I follow regularly in the .Net community is &lt;a href="http://codebetter.com/blogs/jeremy.miller/"&gt;Jeremy D. Miller&lt;/a&gt;.  I have used his &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2006/02/01/137457.aspx"&gt;post&lt;/a&gt; on the model view presenter as a reference many times when explaining the pattern to developers who have not yet been exposed to it.&lt;br /&gt;&lt;br /&gt;Jeremy has an &lt;a href="http://msdn2.microsoft.com/en-us/magazine/cc337902.aspx"&gt;article&lt;/a&gt; on the back page of March's MSDN magazine explaining what ALT.Net is.  It's a very concise and informative explanation.  The tenets of being an ALT.Net developer that he digs into more detail are:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;ol&gt;&lt;li&gt;You're the type of developer who uses whatever works while keeping an eye out for a better way.&lt;/li&gt;&lt;li&gt;You reach outside the mainstream to adopt the best of any community.&lt;/li&gt;&lt;li&gt;You're not content with the status quo.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You realize that tools are great, but they only take you so far.&lt;/li&gt;&lt;/ol&gt;         &lt;/blockquote&gt;&lt;br /&gt;After just getting back from &lt;a href="http://slalomdev.blogspot.com/2008/03/back-from-mix-08.html"&gt;Mix '08&lt;/a&gt; it is really encouraging to see Microsoft begin to embrace the ALT.Net community by doing things like hiring &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt; and creating the ASP.Net MVC framework.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-51289148539946530?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/51289148539946530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=51289148539946530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/51289148539946530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/51289148539946530'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/what-is-altnet.html' title='What is ALT.Net'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-4498518919262896538</id><published>2008-03-14T10:44:00.000-07:00</published><updated>2008-03-14T15:10:14.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extension methods'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c# 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='.net 3.5'/><title type='text'>My IDataRecord Extension Methods</title><content type='html'>I decided it was high time I did a post with some actual code samples in it, so here we go.&lt;br /&gt;&lt;br /&gt;I am really enjoying some of the new C# 3.0 language features, one in particular is extensions methods.  If you are not yet familiar with extension methods, ScottGu has a &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx"&gt;good overview&lt;/a&gt;.  I want to highlight some specific extension methods I've created for &lt;a href="http://msdn2.microsoft.com/en-us/library/system.data.idatarecord.aspx"&gt;IDataRecord&lt;/a&gt; that I think are extremely handy, especially when you spend a lot of time working in the data layer with DataReaders like I do.  I feel like I've written variations on the same data layer 100 times.  Every time it evolves, when I went from .Net 1.1 to 2.0 I took heavy advantage of generics.  Now in .Net 3.5 I am simplifying it even more with extensions.&lt;br /&gt;&lt;br /&gt;When working with DataReaders you might often have a ton of code that looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; myString = record.GetString(record.GetOrdinal(&lt;span class="str"&gt;"MyField"&lt;/span&gt;));&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where &lt;code&gt;record&lt;/code&gt; is an IDataRecord coming from a SqlDataReader or something similar.  Now that's not a terrible line of code, but it gets pretty annoying typing record.GetOrdinal all the time. So to save me that annoyance I've added the following to my IDataRecordExtensions class:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; GetString(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDataRecord record, &lt;span class="kwrd"&gt;string&lt;/span&gt; field)&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; record.GetString(record.GetOrdinal(field));&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;An now all I have to call in my record handling code is this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; myString = record.GetString(&lt;span class="str"&gt;"MyField"&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Not ground-breaking, but better, and you can write an extension for all the types you are getting data for.  Here's a better example of how extension methods for your IDataRecord can be more useful.  Sometimes you might be dealing with a nullable type, IDataRecord doesn't handle this too gracefully, you end up having to write code that looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; myString = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;int&lt;/span&gt; ordinal = record.GetOrdinal(&lt;span class="str"&gt;"MyField"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt;(!record.IsDBNull(ordinal))&lt;br /&gt;{&lt;br /&gt; myString = record.GetString(ordinal);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Again, not a ton of code, but if you have to do this hundreds of times it's going to get annoying and you are going to make mistakes.  Now check this out, in my IDataRecordExtensions class I add the following two methods:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T GetNullable&amp;lt;T&amp;gt;(IDataRecord record, &lt;span class="kwrd"&gt;string&lt;/span&gt; field, Func&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;, T&amp;gt; func)&lt;br /&gt;{&lt;br /&gt; T result = &lt;span class="kwrd"&gt;default&lt;/span&gt;(T);&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; ordinal = record.GetOrdinal(field);&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!record.IsDBNull(ordinal))&lt;br /&gt; {&lt;br /&gt;    result = func(ordinal);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; String GetNullableString(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDataRecord record, &lt;span class="kwrd"&gt;string&lt;/span&gt; field)&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; GetNullable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(record, field, x =&amp;gt; record.GetString(x));&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;OK, what the heck is going on here.  Lets look at &lt;code&gt;GetNullableString&lt;/code&gt; first.  This is an extension method for an IDataRecord that takes a field name and then calls this private &lt;code&gt;GetNullable&lt;/code&gt; method.  Check out that third argument though.  In &lt;code&gt;GetNullable&lt;/code&gt; its defined as &lt;code&gt;Func&amp;lt;int, T&amp;gt; func&lt;/code&gt;.  What we are doing is taking advantage of lambda support in C# 3.0 and we are saying, pass me a function that takes an &lt;code&gt;int&lt;/code&gt; and returns me a generic &lt;code&gt;T&lt;/code&gt;, and in this case &lt;code&gt;T&lt;/code&gt; is a string.  &lt;code&gt;x =&gt; record.GetString(x)&lt;/code&gt; is saying passing the record's &lt;code&gt;GetString&lt;/code&gt; method as that parameter.  Now in our data handling code we can just write:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; myString = record.GetNullableString(&lt;span class="str"&gt;"MyField"&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nice.  What's even better, is now we can easily add other extensions for other more interesting nullable types, such as &lt;code&gt;double&lt;/code&gt; by adding code like this to the IDataRecordExtensions class:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt;? GetNullableDouble(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDataRecord record, &lt;span class="kwrd"&gt;string&lt;/span&gt; field)&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; GetNullable&amp;lt;&lt;span class="kwrd"&gt;double&lt;/span&gt;?&amp;gt;(record, field, x =&amp;gt; record.GetDouble(x));&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So there you go.  Hopefully my experiences with extension methods and IDataRecord are helpful to others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-4498518919262896538?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/4498518919262896538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=4498518919262896538' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/4498518919262896538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/4498518919262896538'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/my-idatarecord-extension-methods.html' title='My IDataRecord Extension Methods'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-428140109222977338</id><published>2008-03-14T10:33:00.000-07:00</published><updated>2008-03-14T10:41:54.810-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random'/><title type='text'>One a Week Challenge</title><content type='html'>&lt;a href="http://www.joelforman.com/"&gt;Joel&lt;/a&gt; and I were talking about ways to give ourselves more incentive to blog more.  We decided on a friendly challenge that would require us to both post at least once a week.  You can read Joel's &lt;a href="http://joelforman.blogspot.com/2008/03/silverlight-2.html"&gt;post&lt;/a&gt; for this week highlighting Silverlight 2 from our recent trip to &lt;a href="http://slalomdev.blogspot.com/2008/03/back-from-mix-08.html"&gt;Mix '08&lt;/a&gt;.  Don't worry Joel, I'm not counting this as my post for this week, check back later for my "real" post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-428140109222977338?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/428140109222977338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=428140109222977338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/428140109222977338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/428140109222977338'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/one-week-challenge.html' title='One a Week Challenge'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-2748119490247267098</id><published>2008-03-09T15:03:00.000-07:00</published><updated>2008-03-09T17:31:14.260-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Back from Mix '08</title><content type='html'>I attended the &lt;a href="http://visitmix.com/2008/default.aspx"&gt;Mix '08&lt;/a&gt; conference in lovely Las Vegas last week.  Mix is Microsoft's conference for discussing and launching web technologies held at the Venician Hotel and Casino.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://sessions.visitmix.com/?selectedSearch=KYN0801"&gt;opening keynote&lt;/a&gt; by &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt; (who's blog I recommend subscribing to) was pretty good.  There were two primary announcements:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Silverlight 2&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At Mix '07 Microsoft launched Silverlight, their competitive technology to Adobe's Flash.  This year they launched Sliverlight 2 Beta 1 during the keynote.  Not having ever worked with Silverlight 1 I cannot speak with much authority on the subject.  I can say that the demos were impressive, especially the &lt;a href="http://memorabilia.hardrock.com/"&gt;Hard Rock Memorabilia&lt;/a&gt; Deep Zoom demo.  In addition, my colleague &lt;a href="http://www.thannap.com/wordpress/"&gt;Than&lt;/a&gt;, who has been working with Silverlight 1 for the last year, informs me that the 2.0 release is an enormous improvement on the prior version.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Internet Explorer 8&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Also during the keynote Microsoft launched Internet Explorer 8 beta.  I did not expect to care much about this announcement considering my primary browser has been Firefox for years now, even before I made the move to the Mac.  However, my tune quickly changed as they demoed the new version.  Having been a web developer for many years now, I have come to accept the constant battle with browser compatibility.  I was not prepared for their first demo to involve a basic CSS styled site, being shown in Firefox.  The site looked fine, and then the speaker switched to Safari and again, it looked just fine.  Then he switched to IE 7, and a giant red square appeared on the page, obviously highlighting a standards compatibility issue that IE has had for ages.  And finally, he switch to IE 8, and the sight looked just like it did in Firefox and Safari.  I am truly impressed with Microsoft's acceptance of the fact that yes, they are not standards compliant, and one of their major goals in IE 8 is to fix that.  This feels like a complete 180 from the Microsoft of the past, and it is a welcome change in my opinion.  The rest of the IE 8 demo was pretty good as well.  They showed off built in development tools that should make anyone's life much easier as we all continue to build sites that must work across various browsers.&lt;br /&gt;&lt;br /&gt;I attended a couple of session that I found to surprising as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Developing Data Driven Web Applications Using ASP.Net Dynamic Data&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I walked into this &lt;a href="http://sessions.visitmix.com/?selectedSearch=T24"&gt;session&lt;/a&gt; not really knowing what I was about to see.  The presentation was about how Dynamic Data allows you to generate a UI scaffolding based on your data model for instant CRUD based UIs, sound familiar?  It should, this is clearly Microsoft's answer to &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, or at least part of it.  What they demoed was fairly good and comprehensive, and moreover, it wasn't being pushed as the end-all-be-all of frameworks as MS is known to do, but rather as yet another option in your ASP.Net arsenal.  This again, is not not something I would have expected to hear out of the Microsoft of the past.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The ASP.Net MVC Framework&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;By far my favorite presentation was &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt;'s &lt;a href="http://sessions.visitmix.com/?selectedSearch=T22"&gt;session&lt;/a&gt; on the new MVC framework for ASP.Net.  This was true for a couple of reasons, the first being that Scott is a truly engaging and entertaining speaker, which is a pretty impressive feat when you consider the content and audience.  Secondly I enjoyed it because again, this framework was not being pushed as a replacement of anything, but rather another alternative.  MVC makes up the second piece of competing with the Ruby on Rails framework, with the model-view-controller architecture becoming baked into the tools.  It is still in its early stages, but looks very promising.  I have been doing a lot of iPhone web application development lately, and one of my biggest issues is keeping may page size small.  Due to the MVC framework's natural lack of your standard viewstate/postback architecture, it seems to me that the views you generate can be much more easily optimized for  a device like the iPhone that can handle full HTML, but may sometimes be limited by bandwidth.&lt;br /&gt;&lt;br /&gt;Overall I had a blast at Mix.  Thanks Microsoft for hosting the party at Tao in the Venician, I can't imagine what the bar bill looked like for that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-2748119490247267098?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/2748119490247267098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=2748119490247267098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/2748119490247267098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/2748119490247267098'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/back-from-mix-08.html' title='Back from Mix &apos;08'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-2438494379772484615</id><published>2008-03-09T12:22:00.000-07:00</published><updated>2008-03-09T12:30:04.804-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>The NGChart Project</title><content type='html'>In a &lt;a href="http://slalomdev.blogspot.com/2007/12/google-chart-api-exactly-what-i-needed.html"&gt;previous post&lt;/a&gt; I mentioned that I was beginning work on a .Net library for wrapping the new &lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt;.  As it turns out, a couple of other people had the same idea.  Today I joined the &lt;a href="http://code.google.com/p/ngchart/"&gt;NGChart project&lt;/a&gt; on &lt;a href="http://code.google.com/"&gt;Google Code&lt;/a&gt; in order to help enhance this existing library.  I was able to easily integrate it into my current project, I urge you to check it out if you need a simple way to add basic charts to your web projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-2438494379772484615?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/2438494379772484615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=2438494379772484615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/2438494379772484615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/2438494379772484615'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2008/03/ngchart-project.html' title='The NGChart Project'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-3386148168869938588</id><published>2007-12-25T19:55:00.000-08:00</published><updated>2008-03-09T16:47:49.892-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='parallels'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>The Mac, a Viable .Net Development Platform?</title><content type='html'>If you know me, you know I'm an avid Apple fan.  This might seem a bit odd considering I pay my bills as a .Net developer, however, I am going to argue that the Mac is a fantastic .Net development platform.  About six months ago I picked up a new Intel-based &lt;a href="http://www.apple.com/macbookpro/"&gt;MacBook Pro&lt;/a&gt;.  Combined with a copy of &lt;a href="http://www.parallels.com/"&gt;Parallels&lt;/a&gt; I began doing my development work in this environment to see how well it stood up.  Now, six months into this experiment, I have to say I am happy with the results.  I'll try and outline some of the specific benefits of doing this.&lt;br /&gt;&lt;br /&gt;1. Environment Separation&lt;br /&gt;&lt;br /&gt;Working as a consultant I often have multiple clients.  Parallels lets me create separate Windows instances for each project.  It keeps things separate and once a project is complete I can archive the VM off onto an external drive in case I need to bring it back later (this has saved me more than once).&lt;br /&gt;&lt;br /&gt;2. The "Best" of Both Worlds&lt;br /&gt;&lt;br /&gt;Parallels Coherence mode makes working in both environments nice and seamless.  This is great when you are using sites that required Internet Explorer (I'm looking at you MS CRM and Changepoint).  What I really like about this mode is the ability to open documents in applications on the Mac side when I prefer a Mac based tool such as TextMate, or the ability to take advantage of the UNIX core of OS X and quickly grep a text file.&lt;br /&gt;&lt;br /&gt;3. The Hardware&lt;br /&gt;&lt;br /&gt;Hands down the MacBook Pro is the best piece of computer hardware I have owned.  Even when taking OS X out of the picture and running windows with BootCamp it is fantastic.&lt;br /&gt;&lt;br /&gt;4. Performance&lt;br /&gt;&lt;br /&gt;Overall performance of Windows within Parallels is really good.  As expected there can be slow-downs.  When installing SQL Server within the VM performance can be effected, I tend now to avoid installing the full blown SQL Server and stick with SQL Express or connecting to external machines unless it is absolutely necessary to have it local.&lt;br /&gt;&lt;br /&gt;Now, of course like most things this hasn't been completely smooth sailing.  Parallels has had some ups and downs with there recent releases, but as of the latest it seems to be pretty solid again.  And since I don't often install MS Office within the VM (unless I need it) I use Office for the Mac and it definitely falls short, especially since it is only built for PowerPC (I can't wait for 2008).  But overall I am very happy with the outcome and I will definitely continue to work this way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-3386148168869938588?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/3386148168869938588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=3386148168869938588' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/3386148168869938588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/3386148168869938588'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2007/12/mac-viable-net-development-platform.html' title='The Mac, a Viable .Net Development Platform?'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-6286404095382042523</id><published>2007-12-11T08:40:00.000-08:00</published><updated>2007-12-25T19:55:09.973-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Chart API - Exactly What I Needed</title><content type='html'>I've been looking around for a simple solution for generating charts for hand held devices that didn't involve a ton of processing and produced charts in a basic image format, not Flash.&lt;br /&gt;&lt;br /&gt;Yesterday Google was nice enough to give me a great solution.  The new &lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt; seems to be exactly what I needed.&lt;br /&gt;&lt;br /&gt;I am now in the processes of writing a .Net library that wraps these into controls that can just be placed within your ASP.Net application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-6286404095382042523?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/6286404095382042523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=6286404095382042523' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6286404095382042523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/6286404095382042523'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2007/12/google-chart-api-exactly-what-i-needed.html' title='Google Chart API - Exactly What I Needed'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7874999921167706419.post-1608448982896603719</id><published>2007-11-11T19:42:00.001-08:00</published><updated>2007-11-11T19:44:44.637-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual studio'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Integrating Subversion with Visual Studio</title><content type='html'>I just started my first open source project on Google Code (&lt;a href="http://code.google.com/p/iphowa/"&gt;iPhOwa&lt;/a&gt;) and I wanted a Subversion client that integrates well with Visual Studio.  I found one, &lt;a href="http://www.visualsvn.com/"&gt;VisualSVN&lt;/a&gt; seems to work very well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7874999921167706419-1608448982896603719?l=slalomdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://slalomdev.blogspot.com/feeds/1608448982896603719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7874999921167706419&amp;postID=1608448982896603719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1608448982896603719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7874999921167706419/posts/default/1608448982896603719'/><link rel='alternate' type='text/html' href='http://slalomdev.blogspot.com/2007/11/integrating-subversion-with-visual.html' title='Integrating Subversion with Visual Studio'/><author><name>Greg Martin</name><uri>http://www.blogger.com/profile/02167524153409547896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_Lh3Pr0ATa7Q/R3KstAM1MDI/AAAAAAAABX8/pte-a58-_UE/S220/IMG_1248_Small.jpg'/></author><thr:total>0</thr:total></entry></feed>
