tag:blogger.com,1999:blog-12538097631776449132024-02-20T22:16:29.139-06:00CDeutsch's BlogRamblings of a Computer Programmer & Amateur Motorsports EnthusiastChristopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comBlogger65125tag:blogger.com,1999:blog-1253809763177644913.post-19849893247367051442013-09-29T19:15:00.000-05:002013-09-29T19:15:20.192-05:00How to Add Barcode Scanning to your Web App using Xamarin<span style="font-family: Arial; font-size: 18px;">Recently I had a client who wanted to add barcode scanning capabilities to their web app. Their web app was already responsive thanks to <a href="http://getbootstrap.com/">Bootstrap</a> but there isn't a convenient way to scan a bar code from mobile Safari or Chrome.</span><br />
<span style="font-family: Arial; font-size: 18px;"></span><br />
<span style="font-family: Arial; font-size: 18px;">This turned out to be fairly trivial thanks to <a href="http://xamarin.com/">Xamarin</a> and two components in their <a href="http://components.xamarin.com/">Component Store</a>:</span><br />
<span style="font-family: Arial; font-size: 18px;"><a href="http://components.xamarin.com/view/jsbridge/">JsBridge</a> - eases Native to Javascript communication</span><br />
<span style="font-family: Arial; font-size: 18px;"><a href="http://components.xamarin.com/view/zxing.net.mobile/">ZXing.Net.Mobile</a> - handles the barcode scanning</span><br />
<br />
<span style="font-family: Arial; font-size: 18px;"></span>
<span style="font-family: Arial; font-size: 18px;">Here are some screenshots of what the web app looks like when accessed via the iOS app:</span><br />
<div style="background-color: #eeeeee; padding: 10px;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8QbpaWsT3esJyBA3eSlWAzEgioEX1DUN6R723REEXZ43DZUiEbOHa1qhdLeS_RAGmMLERWlDI57FR6v9eDLTIzbKtFug4u_PwjvC91bpdLXfjNd-YcJ63oc7xyztPKk7Iu00xSRBiNtU/s1600/IMG_4088.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 15px;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8QbpaWsT3esJyBA3eSlWAzEgioEX1DUN6R723REEXZ43DZUiEbOHa1qhdLeS_RAGmMLERWlDI57FR6v9eDLTIzbKtFug4u_PwjvC91bpdLXfjNd-YcJ63oc7xyztPKk7Iu00xSRBiNtU/s320/IMG_4088.PNG" width="179" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2hQBB5D-yGmoiFb6pPekLIT6cRH8X6n-7Hhk5txLyyLM6NSleBQ7PbXw143bZdzJ8w9AjQH4vZlpa9iSJXQMB2FW2HDIrONqQQ6SR4VeaXDb9ZSaAXVGCwiu8oUCkHKMvTEwC7lnJn8w/s1600/IMG_4089.PNG" imageanchor="1" style="float: left; margin-bottom: 1em; margin-right: 15px;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2hQBB5D-yGmoiFb6pPekLIT6cRH8X6n-7Hhk5txLyyLM6NSleBQ7PbXw143bZdzJ8w9AjQH4vZlpa9iSJXQMB2FW2HDIrONqQQ6SR4VeaXDb9ZSaAXVGCwiu8oUCkHKMvTEwC7lnJn8w/s320/IMG_4089.PNG" width="179" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBQlw-uLn5-ATKUWYJrTMc75r7CljOT4zZBS42jH9wZTvrVuZpOEETxVCdt8_kSP4IBBgTefNyJ9TUJAGHLnbu0qTP8iRYnB7ogJg73dv9yaMzqWc9bcI_sH1KwsIb06dKBHprQSXRZjk/s1600/IMG_4090.PNG" imageanchor="1" style="float: left; margin-bottom: 1em; margin-right: 15px;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBQlw-uLn5-ATKUWYJrTMc75r7CljOT4zZBS42jH9wZTvrVuZpOEETxVCdt8_kSP4IBBgTefNyJ9TUJAGHLnbu0qTP8iRYnB7ogJg73dv9yaMzqWc9bcI_sH1KwsIb06dKBHprQSXRZjk/s320/IMG_4090.PNG" width="179" /></a>
<br />
<div style="clear: both;">
</div>
</div>
<span style="font-family: Arial; font-size: 18px;"><br /></span>
<br />
<span style="font-family: Arial; font-size: 18px;">One of the requirements of the bar code scanning was to not show the <b>Scan</b> button if the user is not using the native app. To do this I customize the UserAgent of the UIWebView and then do UserAgent sniffing on the server side to hide or show the <b>Scan</b> button.</span><br />
<div>
<span style="font-family: Arial; font-size: 18px;"><br /></span></div>
<span style="font-family: Arial; font-size: 18px;">You'll notice if you view the web app in a browser the <b>Scan</b> button is not displayed:</span><br />
<span style="color: #042eee; font-family: Arial; font-size: 18px;"><u>http://xamarinbarcodesample.apphb.com/</u></span><br />
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9XKU2AuKtd3KekBikvKzwKr8AqXnfIaj56abnlI8_pvdeSq8zZXQQjHTjgsy-D6_rWzpPQTUUpk4aoLI25Yku-VEH4haPGedMCxF3R6troJwDKeCKt8QW2r3R0dNclzMpZOsVLXnIPQo/s1600/Screen+Shot+2013-09-25+at+3.49.32+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9XKU2AuKtd3KekBikvKzwKr8AqXnfIaj56abnlI8_pvdeSq8zZXQQjHTjgsy-D6_rWzpPQTUUpk4aoLI25Yku-VEH4haPGedMCxF3R6troJwDKeCKt8QW2r3R0dNclzMpZOsVLXnIPQo/s400/Screen+Shot+2013-09-25+at+3.49.32+PM.png" width="400" /></a></div>
</div>
<span style="font-family: Arial; font-size: medium;">To enable this functionality in the iOS app we append a <b>XamarinBarcodeSampleApp</b> </span><span style="font-family: Arial; font-size: medium;">string to the default UserAgent of the UIWebView:</span><br />
<script src="https://gist.github.com/crdeutsch/6707396.js"></script>
<span style="font-family: Arial; font-size: medium;"><br /></span><span style="font-family: Arial; font-size: medium;">Then in the web app we do UserAgent sniffing for this string.</span><br />
<script src="https://gist.github.com/crdeutsch/6707476.js"></script>
<span style="font-family: Arial; font-size: medium;"><br /></span><span style="font-family: Arial; font-size: 18px;">To wire up the <b>Scan</b> button we take advantage of JsBridge. The first thing we do is register the <b>mt.js</b> library. Secondly we listen for the <b>scanComplete</b> event which is triggered on the iOS app side. Thirdly we handle the <b>Scan</b> button click event and let the iOS side know about it by firing the <b>scanBarcode</b> event.</span><br />
<script src="https://gist.github.com/crdeutsch/6707524.js"></script>
<span style="font-family: Arial; font-size: 18px;"><br /></span><span style="font-family: Arial; font-size: 18px;">On the iOS side we need to enable JsBridge, then listen for the <b>scanBarcode</b> event. When <b>scanBarcode</b> is fired we display the </span><span style="font-family: Arial; font-size: medium;">ZXing.Net.Mobile</span><span style="font-family: Arial; font-size: 18px;"> scanner. If the user successfully scans a barcode we fire the <b>scanComplete</b> event and pass the barcode string as an event parameter.</span><br />
<span style="font-family: Arial; font-size: 18px;"><br /></span>
<span style="font-family: Arial; font-size: 18px;">The native / hybrid iOS app source code can be downloaded here: </span><br />
<span style="font-family: Arial; font-size: medium;"><a href="https://github.com/crdeutsch/Xamarin.iOS.BarcodeSample">https://github.com/crdeutsch/Xamarin.iOS.BarcodeSample</a></span><br />
<br />
<span style="font-family: Arial; font-size: 18px;">The web app source code is here:</span><br />
<span style="font-family: Arial; font-size: medium;"><a href="https://github.com/crdeutsch/Xamarin.Web.BarcodeSample">https://github.com/crdeutsch/Xamarin.Web.BarcodeSample</a></span><br />
<div>
<br /></div>
<h4>
<span style="font-family: Arial; font-size: medium;">Final thoughts:</span></h4>
<span style="font-family: Arial; font-size: medium;">Xamarin tools are flexible enough to handle the requirements of the Web Application developer dipping their toes into native development. </span><br />
<span style="font-family: Arial; font-size: medium;"><br /></span>
<span style="font-family: Arial; font-size: medium;">In fact the Xamarin tools work so nicely with UIWebView based web apps that I'd urge any developer looking at PhoneGap or Titanium to add Xamarin to your review list and avoid the limitations you may run into. </span><br />
<span style="font-family: Arial; font-size: medium;"><br /></span>
<span style="font-family: Arial; font-size: medium;">For instance, I built a series of HTML5 based game for a client that play audio via Flash in a desktop browser. To make them work on an iPad I used Titanium to martial the audio playback to native code. At the time I figured Titanium was the best solution since the bulk of the code was already Javascript. I eventually ran into limitations with Titanium when I wanted to detect custom gestures and realized they don't have a 1 to 1 mapping with the iOS API like Xamarin does. I plan on porting this app to Xamarin in the near future to take advantage of more advanced native iOS functionality.</span><br />
<span style="font-family: Arial; font-size: medium;"><br /></span>
<span style="font-family: Arial; font-size: medium;">In a future blog post I will demonstrate how to use JsBridge and another library I wrote to martial audio calls to the native side like I did for those HTML5 games.</span><br />
<br />
<span style="font-family: Arial; font-size: medium;">DISCLAIMER: I've been work full time for Xamarin for about 3 weeks as a web developer. The following experiences and opinions were developed during my 3 years as a freelance consultant.</span><br />
<div>
<span style="font-family: Arial; font-size: medium;"><br /></span></div>
<span style="font-family: Arial; font-size: 18px;"></span>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-59993188405274359572013-09-29T18:00:00.001-05:002013-09-29T19:46:42.294-05:00Runaway Open Source Project - Lessons learned from developing HiSRCTL;DR: Never reference files on servers you pay for in Open Source projects.<br />
<br />
Today I noticed my monthly Amazon AWS bill was $20 more then normal.<br />
<br />
Somehow 143GB of outbound transfer had happened in Sept. After an hour or two of investigation and deleting things out of buckets that may have caused it, I finally turned on logging and waited.<br />
<br />
The logging revealed a plethora of requests for a file called 50K. I couldn't even remember what the file was there for. I thought maybe my account had been hacked. I finally Googled <b>cdeutsch/50K</b> and it immediately clicked.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkXTznsMolxNgnNSHRoga1V2e9JLvpo5NBwp4vJqrzeNHpuvk_Ie7kY4TITEmcJW9a2SemL7YU4vt8EwVeFvMP7cgFbuHssj0ojhuXTKnohyphenhyphenUlX1uokAzdsNU1qZ8b60untp981uGVJ-U/s1600/Screen+Shot+2013-09-29+at+3.38.56+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkXTznsMolxNgnNSHRoga1V2e9JLvpo5NBwp4vJqrzeNHpuvk_Ie7kY4TITEmcJW9a2SemL7YU4vt8EwVeFvMP7cgFbuHssj0ojhuXTKnohyphenhyphenUlX1uokAzdsNU1qZ8b60untp981uGVJ-U/s400/Screen+Shot+2013-09-29+at+3.38.56+PM.png" width="400" /></a></div>
<br />
<br />
Back in April of 2012 I helped developed the open source javascript library <a href="https://github.com/teleject/hisrc">HiSRC</a>. HiSRC checks for high resolution support and does a quick bandwidth test, if it detects either, high resolution images are served up dynamically on the client side.<br />
<br />
Unfortunately I had placed the <a href="https://github.com/teleject/hisrc/blob/master/hisrc.js#L22">50K test file in one of my Amazon S3 buckets</a> and didn't change or remove that Url when making the library available publicly.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge28e7z_kiCHh6ZvGTWDFHI1K0Kv69zGVFOQ9hjLXhzGsuxnVzPsQ_L6wFXb5ELTwuLwtHsne4toXrBYeWK85xLMCop-COUCjASG5dxMj8wyTlNk6DwDvItNkLd_XcqakWsqr-wekXEUI/s1600/Screen+Shot+2013-09-29+at+3.56.27+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge28e7z_kiCHh6ZvGTWDFHI1K0Kv69zGVFOQ9hjLXhzGsuxnVzPsQ_L6wFXb5ELTwuLwtHsne4toXrBYeWK85xLMCop-COUCjASG5dxMj8wyTlNk6DwDvItNkLd_XcqakWsqr-wekXEUI/s640/Screen+Shot+2013-09-29+at+3.56.27+PM.png" width="640" /></a></div>
<br />
Fast forward to August 2013 and adoption of the HiSRC library has started to catch on by big names sites such as the following:<br />
<a href="https://uber.com/">https://uber.com/</a><br />
<a href="https://www.converse.com/">https://www.converse.com/</a><br />
<a href="http://www.kia.com/us/en/vehicle/soul/2014/experience">http://www.kia.com/us/en/vehicle/soul/2014/experience</a><br />
<a href="http://www.tennis-warehouse.com/">http://www.tennis-warehouse.com/</a><br />
<a href="http://balzac.montblanc.com/">http://balzac.montblanc.com/</a><br />
<a href="http://www.rolandsands.com/mobile/bikes">http://www.rolandsands.com/mobile/bikes</a><br />
<a href="https://www.bresicwhitney.com.au/">https://www.bresicwhitney.com.au/</a><br />
<br />
While it's flattering to have my nick <b>cdeutsch</b> appear in the source code of these sites, it's costing me money.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFoO6jj9AM5VgIQdMuXXTbAbWeg1QJn2p0WO6qlAOWRrUuaOYwwOka2z6Nl1QpC_cq6soEfU6SthZUwmn7whc0rejjeqN8rzbflSphP2YwMm6av24c-TjXsrrWvYj92QUFEeNV0-lwDZ8/s1600/Screen+Shot+2013-09-29+at+3.32.06+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFoO6jj9AM5VgIQdMuXXTbAbWeg1QJn2p0WO6qlAOWRrUuaOYwwOka2z6Nl1QpC_cq6soEfU6SthZUwmn7whc0rejjeqN8rzbflSphP2YwMm6av24c-TjXsrrWvYj92QUFEeNV0-lwDZ8/s320/Screen+Shot+2013-09-29+at+3.32.06+PM.png" width="320" /></a></div>
<br />
I've deleted the 50K file, but <a href="http://aws.amazon.com/articles/1109?_encoding=UTF8&jiveRedirect=1#12">Amazon S3 will still charge me for the 403 errors</a> that are now happening.<br />
<br />
I'm waiting to hear back from Amazon on how to resolve this and am working on contacting the 3 biggest sites to get them to make the necessary changes.<br />
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-61462976529364499432013-06-17T17:17:00.002-05:002013-06-18T08:06:40.053-05:00What's The Best Structure for API Responses?I learned something new while listening to <a href="http://trafficandweather.io/posts/2013/6/7/episode-12-">Episode 12</a> of the <a href="http://trafficandweather.io/">Traffic and Weather</a> podcast.<br />
<br />
<a href="https://twitter.com/johnsheehan">John Sheehan</a> mentioned that when you return your XML or JSON from an API you should have an error envelop separate from the data envelop.<br />
<br />
The main reason is if you're deserializing the output and mapping it to a class in a static language you can use error.message or error.code without namespace conflicts. This also gives you a consistent target for a given endpoint. John recommends avoiding returning one structure for success and another structure for error (something that I've been doing to date).<br />
<br />
My take away is that John recommends structuring your return data like so:<br />
<br />
Success:
<br />
<pre class="Cpp" name="code">{
data: {
id: 1,
model: 'Mustang',
make: 'Ford'
},
error: null
}
</pre>
<br />
Error:
<br />
<pre class="Cpp" name="code">{
error: {
code: 3,
message: 'Car not found'
}
}
</pre>
<br />
<b>
Continue reading to see the <span style="color: #cc0000;">NOT RECOMMENDED</span> way</b><br />
<b><br /></b>
The way I traditionally did it was without envelopes but the structure changes based on success vs error:<br />
<br />
Success (the <b>car</b> object):
<br />
<pre class="Cpp" name="code">{
id: 1,
model: 'Mustang',
make: 'Ford'
}
</pre>
Error (the <b>error</b> object):<br />
<pre class="Cpp" name="code">{
code: 3,
message: 'Car not found'
}
</pre>
<br />
What I liked about my method is that you can deserialize directly to the class you want ("<b>Car</b>") without creating a wrapper class. For example, my way you don't have to have a class like this.<br />
<br />
<pre class="Cpp" name="code">public class CarResponse
{
public Car Data { get; set; }
public ApiError Error { get; set; }
}
</pre>
<br />
The downside of my method is you have to do some extra work to parse errors into ApiError instead of Car.<br />
<br />
I'm not 100% convinced I want to switch and have a bunch of response wrapper classes, but it's debatable whether there is another person more involved with APIs then John, so I'll probably be switching. ;)<br />
<br />
Some questions I have for John's method (UPDATE: see comments for John's answers, my examples have been updated to reflect them).<br />
<ol>
<li>What's the recommendation for naming the envelop of the <b>success</b> data. Ex. "<b>car</b>" or always use something generic like "<b>data</b>"</li>
<li>On success do you return the <b>error</b> envelop at all? If so, do you indicate a "no error" status code? Ex. "code: 0"</li>
</ol>
<br />
If you're working with APIs be sure to checkout John's excellent tool <a href="https://www.runscope.com/">Runscope</a>. It's good stuff.Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-64212655772445406132012-11-27T21:06:00.001-06:002013-07-19T18:48:30.431-05:00Fixing 404 Errors for ASP.NET MVC Apps that Bundle Assets when Deployed to IISUPDATE 07/19/2013: As pointed out in the comments by Ray Moro, a better way to fix this may be to remove the extension from your bundle name. So <b>/bundle/myscrips.js</b> becomes <b>/bundle/myscripts</b> this will cause it to run the module without having to change the config settings below.<br />
<br />
That's a mouthful of a title.<br />
<br />
If you're using <b>ScriptBundle</b> and <b>StyleBundle</b>'s in an ASP.NET MVC4 app and you're suddenly getting 404 errors even though <b>EnableOptimizations</b> is set to <b>true</b> make sure you have the following in your <b>Web.Config</b> in the <b>system.webServer</b> section:<br />
<br />
<pre class="html" name="code"><modules runAllManagedModulesForAllRequests="true">
<remove name="BundleModule" />
<add name="BundleModule" type="System.Web.Optimization.BundleModule" />
</modules>
</pre>
<br />
I've wasted incalculable amounts of time on this issue, TWICE!!! I don't know why this isn't in the web.config by default or better yet not needed to use Bundling.
Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-24708965257766446772012-10-14T18:26:00.002-05:002012-10-19T09:23:46.298-05:00Trip to San Francisco GuideHere are my lessons learned after spending 9 days in San Francisco which is a follow up to my post <a href="http://blog.cdeutsch.com/2012/09/planning-trip-to-san-francisco.html">Planning a trip to San Francisco</a> where I solicited advice on what to do and where to eat.<br />
<br />
Tips<br />
<ul>
<li>Be prepared to do some walking, so bring comfortable shoes. Some days I walked up to 6 or 7 miles. There are also very steep hills/streets so keep that in mind before following the route your GPS gives you. The shortest distance may not be the easiest. For instance, it was brutal walking from the bay to Union Square via Mason St. Had I gone down a couple blocks I could have avoided the hill.</li>
<li>Biking across the Golden Gate Bridge over to <a href="http://goo.gl/maps/LQSwq">Sausalito</a> and taking a <a href="http://goldengateferry.org/schedules/Sausalito.php">ferry</a> back is a great idea. There are many places to rent bikes including <a href="http://www.blazingsaddles.com/san-francisco.aspx">Blazing Saddles</a>.Walking to Sausalito is not such a great idea since there is a long stretch of walking on the side of road.</li>
<li>Sign up and try <a href="https://www.uber.com/">Uber</a>. Much nicer service then a cab but typically more expensive.</li>
<li>Avoid walking through the <a href="http://en.wikipedia.org/wiki/Tenderloin,_San_Francisco">Tenderloin</a>, especially at night. Ask locals or your hotel concierge where that is if you can't figure it out.</li>
<li>Take advantage of the <a href="http://www.bart.gov/index.aspx">BART</a> when you can. Great for getting from Union Square to the Mission or Pier 1. The best service I received while in San Francisco was from the vagrant lady who helped me buy my first BART ticket. She was a pro at working that thing. I should have given her a bigger tip considering the service I got elsewhere.</li>
<li>If you want to spend a whole day exploring the city do one of the <a href="http://www.bigbustours.com/eng/sanfrancisco/custompage.aspx?id=tour_of_san_francisco&gclid=">open bus tours</a> that allows you to hop-on and hop-off. The one I did had about 20 stops and another bus came about every 20 minutes, so for example you could hop-off and hang out at <a href="http://en.wikipedia.org/wiki/Haight-Ashbury">Haight Ashbury</a> for a while and then continue on after you've spent some time there.</li>
<li>If you're going to visit <a href="http://www.alcatrazcruises.com/index.aspx">Alcatraz</a> and take the <a href="http://www.alcatrazcruises.com/website/audio-tour.aspx">Cellhouse Audio Tour</a> (recommended) allow for a good 3-4 hours minimum with travel time. Also, sign up in advance. I wanted to go on a Monday and it was sold out until Wednesday.</li>
<li>Be ware of the fog. If you're going to do something like take the open top bus tour or visit the Golden Gate, you want to do it on a clear day. The fog can come in and ruin the amazing scenery.</li>
</ul>
<div>
My Favorites</div>
<div>
<ul>
<li><a href="http://www.zeitgeistsf.com/">Zeitgeist</a> - great beer selection reasonably priced. Great bloody marries too!</li>
<li><a href="http://www.missionbeachcafesf.com/">Mission Beach Cafe</a> for weekend breakfast - Get a side of their bacon. I'm still thinking about it! There's usually a good hour wait to get in so be prepared for that. We put our name on the list and walked to Zeitgeist to get a bloody marry and timed it perfectly. </li>
<li><a href="http://www.zerozerosf.com/">Zero Zero</a> - we had the Avocado Bruschetta, Geary pizza, Little Shells, and build your own desert sunday. It was all excellent. Some of the best food I had while I was there.</li>
<li><a href="http://fogharbor.com/">Fog Harbor Fish House</a> - I ate lunch here and had an excellent view of Alcatraz and the Golden Gate. I also had dinner and it was a bit dark to take in the view but the food was still excellent both times.</li>
<li><a href="http://www.bluebottlecoffee.net/">Blue Bottle Coffee</a> - excellent coffee</li>
</ul>
<div>
Disappointments</div>
</div>
<div>
<ul>
<li>You can't get into a Giants game using a StubHub ticket/barcode that's on your phone. This is the city that arguably has more startups and innovation then the rest of the world combined AND charges $.10 for each grocery bag you use. I'm dumbfounded that I had to go to will call and have a paper ticket printed off.</li>
<li>Versus Minnesota, service (like at restaurants) is on average slower and less attentive, but relax you're on vacation. ;)</li>
</ul>
</div>
<div>
<br /></div>
<div>
<br /></div>
<br />
<br />
<br />
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-30308037006797286342012-09-23T14:09:00.003-05:002012-10-14T18:26:58.726-05:00Planning a Trip to San FranciscoUPDATE 10/14/2012: Here's a <a href="http://blog.cdeutsch.com/2012/10/trip-to-san-francisco-guide.html">follow up on how the trip went</a>.<br />
<br />
I'll be taking my first trip to San Francisco, Sept 29 - Oct 8, 2012. I'm looking for recommendations for restaurants and attractions and some space to do some work/programming (coffee shop or coworking space).<br />
<br />
Here is what I've crowd sourced from Twitter so far. Big thanks to <a href="https://twitter.com/johnsheehan">johnsheehan</a>, <a href="https://twitter.com/justinpeck">justinpeck</a>, <a href="https://twitter.com/masteinhauser">masteinhauser</a>, <a href="https://twitter.com/mronge">mronge</a>, <a href="https://twitter.com/Solome33">Solome33</a>, <a href="https://twitter.com/kaufenberg">kaufenberg</a>, <a href="https://twitter.com/matt_krieger">matt_krieger</a>, <a href="https://twitter.com/dberkholz">dberkholz</a>, <a href="https://twitter.com/bassistance">bassistance</a><br />
<br />
<h3>
Attractions / ToDo</h3>
<div class="p1">
</div>
<ul>
<li><a href="http://www.alcatrazcruises.com/index.aspx">Alcatraz</a></li>
<ul>
<li>opt for the <a href="http://www.alcatrazcruises.com/website/audio-tour.aspx">Cellhouse Audio Tour</a> if you have time</li>
</ul>
<li><a href="http://www.nps.gov/muwo/index.htm">Muir Woods </a></li>
<li><a href="http://goldengate.org/">Golden Gate Bridge</a></li>
<li><a href="http://www.computerhistory.org/">Computer History Museum</a></li>
<li><a href="http://www.gocartours.com/">GoCar Tour</a></li>
<ul>
<li>opt for 2 hour version</li>
</ul>
<li>Rent bikes in the wharf, bike across the golden gate to Sausalito then take the ferry back</li>
<ul>
<li>covers a lot of the same ground as GoCar though so maybe would do one or the other</li>
</ul>
<li>Climb up to <a href="http://www.sftravel.com/twinpeakssanfrancisco.html">Twin Peaks</a> (<a href="http://goo.gl/maps/Jpl8p">map</a>) </li>
<ul>
<li>pick a clear day for a nice view</li>
</ul>
</ul>
<div>
<br />
<h3>
Restaurants</h3>
<div class="p1">
</div>
<ul>
<li><a href="http://www.fangrestaurant.com/">Fang Restaurant</a> (<a href="http://goo.gl/maps/1vF3m">map</a>)</li>
<li><a href="http://www.flourandwater.com/">Flour + Water</a> (<a href="http://goo.gl/maps/3qafN">map</a>)</li>
<li><a href="http://www.porkstorecafe.com/">Pork Street Cafe</a> (<a href="http://goo.gl/maps/FdETh">map</a>) [great breakfast]</li>
<li><a href="http://caffesport.ypguides.net/">Cafe Sport</a> (<a href="http://goo.gl/maps/Kc9m0">map</a>)</li>
</ul>
<br />
<h3>
Coffee Shops</h3>
<div class="p1">
</div>
<div class="p1">
</div>
<ul>
<li><a href="http://www.epicentercafe.com/">Epicenter</a> (<a href="http://goo.gl/maps/qhAOu">map</a>)</li>
<li><a href="http://sightglasscoffee.com/">Sight Glass</a> (<a href="http://goo.gl/maps/fO3mT">map</a>)</li>
<li><a href="http://www.bluebottlecoffee.net/">Blue Bottle</a> (<a href="http://goo.gl/maps/uIO0Q">map</a>)</li>
<li><a href="http://fourbarrelcoffee.com/">Fourbarrel Coffee</a> (<a href="http://goo.gl/maps/vnma6">map</a>)</li>
<li><a href="http://www.coffeebar-usa.com/">Coffee Bar</a> (<a href="http://goo.gl/maps/q3gmU">map</a>)</li>
<li><a href="http://www.delapazcoffee.com/">De La Paz Coffee Roasters</a> (<a href="http://goo.gl/maps/afvNA">map</a>)</li>
</ul>
<br />
<h3>
Pubs</h3>
<div>
<ul>
<li><a href="http://www.toronado.com/">Toronado</a> (<a href="http://goo.gl/maps/4DqRn">map</a>)</li>
<li><a href="http://www.magnoliapub.com/">Magnolia</a> (<a href="http://goo.gl/maps/8jZ2q">map</a>)</li>
<li><a href="http://www.alembicbar.com/">Alembic</a> (<a href="http://goo.gl/maps/wa3Pl">map</a>)</li>
<li><a href="http://rosamundesausagegrill.com/">Rosamunde Sausage Grill</a> (<a href="http://goo.gl/maps/HAjKj">map</a>)</li>
<li><a href="http://www.monkskettle.com/">Monk's Kettle</a> (<a href="http://goo.gl/maps/rtUFI">map</a>)</li>
</ul>
</div>
<br />
<h3>
Transportation</h3>
<div class="p1">
</div>
<ul>
<li>Sign up for <a href="https://www.uber.com/">Uber</a></li>
<ul>
<li>sign up for <a href="https://docs.google.com/spreadsheet/viewform?formkey=dFFYQVUtc09nME51Z09jZEY1R1BLenc6MQ">UberX beta wait list </a></li>
</ul>
<li><a href="http://www.zipcar.com/">ZipCar</a></li>
<ul>
<li>membership takes 3 days to a week so sign up in advance</li>
</ul>
<li><a href="http://www.bart.gov/index.aspx">BART</a></li>
<li><a href="http://www.caltrain.com/">Caltrain</a></li>
<ul>
</ul>
</ul>
</div>
<br />
<h3>
Coworking</h3>
<div class="p1">
<ul>
<li><a href="http://www.sandboxsuites.com/">Sandbox Suites</a> (<a href="http://goo.gl/maps/DWm1H">map</a>)</li>
</ul>
</div>
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-48718313688553075212012-09-16T20:23:00.000-05:002012-09-16T20:50:39.047-05:00Best Mug, Cups, and Water Bottle for TechiesHere are the four liquid receptacles that support my freelance web developer career. They're listed in order of usage.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSEWt0-oisBxpeqLZ3GJq40AmLYA9N-MQG5pZdcG__Jz_0OXKQ-kXL9NE4_JOvMf5DjeFXYL_yxex-vtUBHuA_HYcGHV-4gv8hVB804PmrcSQyw9MC_1lJ0wYgGAopDgLvta7JQ-ldroQ/s1600/IMG_1682.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSEWt0-oisBxpeqLZ3GJq40AmLYA9N-MQG5pZdcG__Jz_0OXKQ-kXL9NE4_JOvMf5DjeFXYL_yxex-vtUBHuA_HYcGHV-4gv8hVB804PmrcSQyw9MC_1lJ0wYgGAopDgLvta7JQ-ldroQ/s640/IMG_1682.JPG" width="640" /></a></div>
<div style="text-align: center;">
<span style="font-size: x-small;">(I need to build a special rack for these guys)</span></div>
<br />
For <b>water</b>, I take my <a href="http://www.amazon.com/gp/product/B004UQKK6Y/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B004UQKK6Y&linkCode=as2&tag=cdeutschcom-20">Camelbak Podium Chill Water Bottle</a> everywhere. Home, co-working space, working out, trips. Tip of the hat to <a href="http://blog.donnfelker.com/2012/03/24/waterbottles-for-nerds/">Donn Felker</a> for doing the leg work on finding this excellent bottle. My only complaint is that it "talks" sometimes. If pressure builds up it will start making noise when it leaks out until you give it a little squeeze.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.com/gp/product/B004UQKK6Y/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B004UQKK6Y&linkCode=as2&tag=cdeutschcom-20"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLOsdIzDVUqa_VfAlDXbPGUwbZ5r2gUxGyBSdT9Syo-f69eL4djOa-aeCIzeG1Ki_Gp4m-KcDFHPb8P58U6ynUlwDkB1K8iIkPLalCsYvBiOjTMB9dI9M8egSLXN4IJGhy1Li6kdyK9G4/s320/21zS5HrmHTL._SL160_.jpeg" width="160" /></a></div>
<br />
For <b>coffee</b> this <a href="http://www.amazon.com/gp/product/B00004WHWV/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00004WHWV&linkCode=as2&tag=cdeutschcom-20">Nissan Leak-Proof Travel Mug</a> has been my goto for about 8 years. I own 3 of them and have bought at least 3 more as gifts. When closed this thing seals like no other. As good for road trips as it is for working around your laptop.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.com/gp/product/B00004WHWV/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00004WHWV&linkCode=as2&tag=cdeutschcom-20"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9WjJzbNgBXL5P_bYtpSSqWrJOzIMkp2JCOukU5tXXSPBJGuoQwtzYRmqjyW4JKOsAL9S-HvAPGW0RA1bja0Rh9gK1P4ghVyQaxt7lWmjnGe9OhSaxT3GrjNM7C2YtA3Ab50SnAIY4JZM/s1600/31ZymcGrOvL._SL160_.jpeg" /></a></div>
<br />
<br />
If you don't like the bulky handle, this other <a href="http://www.amazon.com/gp/product/B002PY7AYS/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B002PY7AYS&linkCode=as2&tag=cdeutschcom-20">Travel Mug</a> from Thermos Nissan is a great alternative recommended by my wife.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.com/gp/product/B002PY7AYS/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B002PY7AYS&linkCode=as2&tag=cdeutschcom-20"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9zv7hi-oqI2MycsIulQ6S20zq6qdSZr4Is8R31tcyycEG-fnURFhHKHQv4IU3TBf0qMXsWU9BhcBDyy79lE4sjRC_fwO_ZSF614bLOqacqybdDFRiauyq7pmcSfTURtWm4QSibIWpj6k/s1600/31+VKmIWpjL._SL160_.jpeg" /></a></div>
<br />
<br />
For <b>tea</b>, I have my third Thermos Nissan pick, a <a href="http://www.amazon.com/gp/product/B00004S1CV/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00004S1CV&linkCode=as2&tag=cdeutschcom-20">Tumbler with Infuser</a>. I'm just getting into tea so there are probably some other great options I haven't discovered yet, but I've been really happy with this unit so far.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.com/gp/product/B00004S1CV/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00004S1CV&linkCode=as2&tag=cdeutschcom-20"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi9V8hehSGoBrU0xXrbfhNPU2dv2HofW6vqYmabPO5wmSi2hNl8SBbrLj6ZtYTBGSh9OQgbgOsegWNPIQuGcR673WUQVeC1ziTcbVFV9bWpIcg9_hLWfsVq6ivtLU_CfVgUWuoQqnaXuo/s1600/41MSRK23PBL._SL160_.jpeg" /></a></div>
<br />
<br />
This summer I got addicted to Starbucks' <b>iced coffee</b> with a shot of white moca. Instead of paying $4 each day I decided to try make my own. First I tracked down the <a href="http://www.amazon.com/gp/product/B006KI44I0/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B006KI44I0&linkCode=as2&tag=cdeutschcom-20">white mocha Starbucks uses</a>. Next, since I use a <a href="http://www.amazon.com/gp/product/B000GTR2F6/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B000GTR2F6&linkCode=as2&tag=cdeutschcom-20">Keurig</a> for speed and convenience, I went with these <a href="http://www.amazon.com/gp/product/B004ILKODA/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B004ILKODA&linkCode=as2&tag=cdeutschcom-20">Iced Coffee K-Cups</a>. To complete the experience, my wife found these <a href="http://www.amazon.com/gp/product/B0029DDJEK/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B0029DDJEK">16oz re-usable Starbucks cups</a> with re-usable straws. To make the drink, put a couple of pumps of white chocolate in first, then fill to pretty much the top with ice, set the Keurig to the 8 oz setting, and brew directly onto the ice. The Iced K-Cups are specially formulated to brew stronger then regular K-Cups, so when the ice melts it balances out. Stir it up to blend in the white chocolate. Then I usually add a few more ice cubes if there is space.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.com/gp/product/B0029DDJEK/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=B0029DDJEK"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQjQkhzdJEp6fDZpYmDqfrdIBFwWjVswa-jw4gFFHLExunk_9JtnscLhFiFXUSmdPx5TQHKkdv8sYq2PdCCsQr85V5xG8vQl6Z6iyM4rz1w1tWgSAOrenoPGJUvlPWGKvBIiokKNdgXjs/s1600/41nQqpmehNL._SL160_.jpeg" /></a></div>
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-46230846555581105552012-08-28T19:24:00.001-05:002012-08-28T19:25:15.363-05:00Force Content Types to Json in .NET WebApiI ran into a situation where I couldn't set the Content-Type header in the http request client I was using. (<a href="http://crossrider.com/">Crossrider's</a> <a href="https://crossrider.wiki.zoho.com/Cross-Domain-Requests.html">appAPI.request.post</a>)<br />
<br />
The client was either not setting a <b>Content-Type</b> or defaulting to <b>application/x-www-form-urlencoded</b><br />
<br />
If you put the code below in <b>Application_Start</b> you should be able to force form-urlencoded data to the <b>JsonFormatter</b> and by removing the <b>XmlFormatter</b>, Json will also be the default.<br />
<br />
<pre class="Cpp" name="code">HttpConfiguration config = GlobalConfiguration.Configuration;
foreach (var mediaType in config.Formatters.FormUrlEncodedFormatter.SupportedMediaTypes)
{
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(mediaType);
}
config.Formatters.Remove(config.Formatters.FormUrlEncodedFormatter);
config.Formatters.Remove(config.Formatters.XmlFormatter);
</pre>
Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-26245608918067332392012-08-18T19:41:00.000-05:002013-05-02T13:18:35.351-05:00Using Less and Twitter Bootstrap in ASP.NET MVC4UPDATE 05/02/2013:<br />
<br />
Changed ScriptBundle and StyleBundle to just Bundle, per Andrey Taritsyn:<br />
<blockquote class="tr_bq">
<span style="color: #42474a; font-family: 'Helvetica Neue', arial, sans-serif; font-size: 15px; line-height: 21px;">Bundle Transformer it is not recommended to use together with the StyleBundle and ScriptBundle classes, because these classes already contain transformations (instances of the built-in minifiers: CssMinify and JsMinify). Use a Bundle class.</span></blockquote>
<br />
UPDATE 11/08/2012:<br />
<ol>
<li>Create a new MVC4 <b>Internet Application</b><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56DoE_smf-4D5e60qtFlS1K2h521_CY1UmquG_fB489mXDuKB_LLk8t5odyruHTQRud4nkzn59XEUweU4FN3vN-iJkOf2BXa_2V8bcH1IgG-sKaX-Vjmgm18_uISonFVG-Pds4wcMy_I/s1600/Screen+Shot+2012-08-18+at+7.11.40+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56DoE_smf-4D5e60qtFlS1K2h521_CY1UmquG_fB489mXDuKB_LLk8t5odyruHTQRud4nkzn59XEUweU4FN3vN-iJkOf2BXa_2V8bcH1IgG-sKaX-Vjmgm18_uISonFVG-Pds4wcMy_I/s320/Screen+Shot+2012-08-18+at+7.11.40+PM.png" width="320" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56DoE_smf-4D5e60qtFlS1K2h521_CY1UmquG_fB489mXDuKB_LLk8t5odyruHTQRud4nkzn59XEUweU4FN3vN-iJkOf2BXa_2V8bcH1IgG-sKaX-Vjmgm18_uISonFVG-Pds4wcMy_I/s1600/Screen+Shot+2012-08-18+at+7.11.40+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a></div>
</li>
<li style="clear: both;">Add the following Nuget Packages</li>
<ul>
<li style="clear: both;">Install-Package <a href="http://nuget.org/packages/BundleTransformer.Less">BundleTransformer.Less</a></li>
<li style="clear: both;">Install-Package <a href="http://nuget.org/packages/Twitter.Bootstrap.Less">Twitter.Bootstrap.Less</a></li>
</ul>
<li>Rename <b>/Content/site.css</b> to <b>/Content/site.less</b> </li>
<ul></ul>
<li>Edit <b>BundleConfig.cs</b> in the <b>App_Start</b> folder and update the css file name to site.less like so:<pre class="Cpp" name="code">bundles.Add(new var cssTransformer = new CssTransformer();
var jsTransformer = new JsTransformer();
var nullOrderer = new NullOrderer();
var defaultScriptsBundle = new Bundle("~/bundles/default.js").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-ui-{version}.js",
"~/Scripts/site.js");
defaultScriptsBundle.Transforms.Add(jsTransformer);
defaultScriptsBundle.Orderer = nullOrderer;
bundles.Add(defaultScriptsBundle);
var defaultStylesBundle = new Bundle("~/Content/default.css").Include("~/Content/site.less");
defaultStylesBundle.Transforms.Add(cssTransformer);
defaultStylesBundle.Orderer = nullOrderer;
bundles.Add(defaultStylesBundle);
</pre>
</li>
<li>Add the following to the top of <b>/Content/site.less</b> in order to have access to all of the Bootstrap mixins:<pre class="css" name="code">@import "less/bootstrap.less";
body {
padding-top: 60px;
padding-bottom: 40px;
}
@import "less/responsive.less";
</pre>
<div>
<br /></div>
</li>
</ol>
=================== THE REST OF THIS POST IS OUT OF DATE ==========<br />
<br />
UPDATE 8/20/2012: I've created a <a href="https://nuget.org/packages/Twitter.Bootstrap.Less.MVC4">Nuget package</a> that performs the steps below. I'd suggest reviewing what the package does below and then running:<br />
<b>Install-Package Twitter.Bootstrap.Less.MVC4</b><br />
<br />
ASP.NET MVC4 has a <a href="http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification">great new feature</a> that can bundle and minify your CSS and Javascript files.<br />
<br />
But in order to get <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a> to work it takes a bit more work. Here are the steps that worked for me.<br />
<br />
<ol>
<li>
Create a new MVC4 <b>Internet Application</b>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56DoE_smf-4D5e60qtFlS1K2h521_CY1UmquG_fB489mXDuKB_LLk8t5odyruHTQRud4nkzn59XEUweU4FN3vN-iJkOf2BXa_2V8bcH1IgG-sKaX-Vjmgm18_uISonFVG-Pds4wcMy_I/s1600/Screen+Shot+2012-08-18+at+7.11.40+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56DoE_smf-4D5e60qtFlS1K2h521_CY1UmquG_fB489mXDuKB_LLk8t5odyruHTQRud4nkzn59XEUweU4FN3vN-iJkOf2BXa_2V8bcH1IgG-sKaX-Vjmgm18_uISonFVG-Pds4wcMy_I/s320/Screen+Shot+2012-08-18+at+7.11.40+PM.png" width="320" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh56DoE_smf-4D5e60qtFlS1K2h521_CY1UmquG_fB489mXDuKB_LLk8t5odyruHTQRud4nkzn59XEUweU4FN3vN-iJkOf2BXa_2V8bcH1IgG-sKaX-Vjmgm18_uISonFVG-Pds4wcMy_I/s1600/Screen+Shot+2012-08-18+at+7.11.40+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a></div>
</li>
<li style="clear: both;">Add the following Nuget Packages</li>
<ul>
<li style="clear: both;">Install-Package <a href="http://nuget.org/packages/dotless">dotless</a></li>
<li style="clear: both;">Install-Package <a href="http://nuget.org/packages/Twitter.Bootstrap.Less">Twitter.Bootstrap.Less</a></li>
</ul>
<li>Create an <b>Infrastructure</b> folder and add the following two files: (hat tip to this <a href="http://stackoverflow.com/questions/9593254/mvc4-less-bundle-import-directory">Stackoverflow question</a>)</li>
<ul>
<li><b><a href="https://raw.github.com/crdeutsch/TwitterBootstrapExample/master/TwitterBootstrapExample/Infrastructure/ImportedFilePathResolver.cs">ImportedFilePathResolver.cs</a></b></li>
<li><b><a href="https://raw.github.com/crdeutsch/TwitterBootstrapExample/master/TwitterBootstrapExample/Infrastructure/LessMinify.cs">LessMinify.cs</a></b></li>
</ul>
<li>Rename <b>/Content/site.css</b> to <b>/Content/site.less</b> </li>
<ul>
</ul>
<li>Edit <b>BundleConfig.cs</b> in the <b>App_Start</b> folder and replace the default <b>Content/css</b> bundle with the following:
<pre class="Cpp" name="code">var css = new Bundle("~/Content/css").Include("~/Content/site.less");
css.Transforms.Add(new LessMinify());
bundles.Add(css);
</pre>
<br />
</li>
<li>Add the following to the top of <b>/Content/site.less</b> in order to have access to all of the Bootstrap mixins:
<pre class="css" name="code">@import "less/bootstrap.less";
</pre>
<br />
</li>
</ol>
If you have "shared" .less files from other projects I found importing them in <b>site.less</b> right after boostrap.less to work pretty well. They'll have access to all the mixins.<br />
<pre class="css" name="code">@import "less/bootstrap.less";
@import "less/shared.less";
</pre>
<br />
The completed solution is <a href="https://github.com/crdeutsch/TwitterBootstrapExample">available on Github here</a>
<br />
<br />
If there is a better/easier way to do this please let me know in the comments!<br />
<br />
<br />
<br />
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-69973833296681697012012-08-03T17:05:00.000-05:002012-08-03T17:05:12.747-05:00Passing Cookies to a Node.js REST ClientIn Node.js if you want to pass the current user's <b>Cookies</b> to a <b>REST</b> call your making from the server here's a simple way to do it:<br />
<br />
<pre class="Cpp" name="code">var cookies = _.map(req.cookies, function(val, key) {
return key + "=" + encodeURIComponent(val);</pre>
<pre class="Cpp" name="code">}).join("; ");
rest.get("http://makerocketgonow.com/", {
headers: {
Cookie: cookies,
"Content-Type": "application/json"
}
}).on("complete", function(data) {
return console.log(data);
});
</pre>
<br />
This example uses the popular <a href="https://github.com/danwrong/restler">Restler</a> library, but I assume you could do something similar with other libraries or <a href="http://stackoverflow.com/questions/4579757/how-do-i-create-a-http-client-request-with-a-cookie">without using a library</a>.<br />
<br />
CAUTION: I'm using encodeURIComponent on the cookie value. Ruby on Rails seems to expect their cookies to be encoded like this. On the other hand, I've looked throw a few Node.js libraries that deal with cookies and they don't seem to manipulate the value at all. So you can play with adding or removing encodeURIComponent.<br />
<br />
If you start to get errors when making the REST request, be sure to check the cookie encoding/format versus what Firebug sends on a normal request to the site. Pay particular attention to any special characters.Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-12089235329275479882012-07-16T08:49:00.000-05:002012-07-16T08:54:14.403-05:00Using Mongoid 3 (MongoHQ or MongoLab) on HerokuHere's what you need to get Mongoid working on Heroku, if you're getting errors like:<br />
<span style="color: red;">NoMethodError (undefined method `[]' for nil:NilClass)</span><br />
<br />
Make sure the following is in your gem file (<a href="http://blog.heroku.com/archives/2012/5/9/multiple_ruby_version_support_on_heroku/">reference</a>).<br />
<blockquote class="tr_bq">
source 'http://rubygems.org'<span style="background-color: white;"> </span></blockquote>
<blockquote class="tr_bq">
ruby '1.9.3'<br />
gem 'rails', '3.2.3'</blockquote>
<br />
If you get an error like <span style="color: red;">undefined method `ruby' </span>run the following:<br />
<blockquote class="tr_bq">
gem install bundler --pre</blockquote>
<br />
<span style="background-color: white;">A lot of places have outdate documentation for configuring your mongoid.yml file which may result in the following error:</span><br />
<span style="background-color: white;"><span style="color: red;">No database provided for session configuration: :default</span></span><br />
<div>
<br /></div>
Your mongoid.yml file should look like the following.<br />
<blockquote class="tr_bq">
production:<br />
sessions:<br />
default:<br />
uri: <%= ENV['MONGOHQ_URL'] %><br />
options:<br />
skip_version_check: true<br />
safe: true</blockquote>
The ENV variable above is for MongoHQ. For MongoLab use <b><span style="background-color: white;">ENV['MONGOLAB_URI']</span><span style="background-color: white;"> </span></b><br />
<b><span style="background-color: white;"><br /></span></b><br />
<span style="background-color: white;">Big thanks to the guys in this <a href="http://stackoverflow.com/questions/11216002/why-is-my-mongodb-hosting-uri-settings-for-mongoid-yml-not-working-correctly">StackOverflow thread</a> for helping me put all this together!</span><br />
<b><span style="background-color: white;"><br /></span></b><br />
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-14326544918242392632012-05-13T16:30:00.000-05:002012-05-13T16:30:51.172-05:00Add support for LESS to Node.js connect-assetmanager packageThe <a href="https://github.com/mape/connect-assetmanager/">connect-assetmanager</a> Node.js package allows you to combine multiple javascript and CSS files into one and also do other manipulations like minification.<br />
<br />
It's part of <a href="https://github.com/mape">Mathias Pettersson's (mape)</a> excellent <a href="https://github.com/mape/node-express-boilerplate">node-express-boilerplate</a> template.<br />
<br />
If you're also using <a href="http://lesscss.org/">LESS</a> for CSS here is some code you can add to get connect-assetmanager to process you're LESS files:<br />
<br />
<pre class="Cpp" name="code">var assetsSettings;
assetsSettings = {
js: {
route: /\/static\/js\/[a-z0-9]+\/.*\.js/,
path: "./public/javascripts/",
dataType: "javascript",
files: ["libs/underscore-min.js" "libs/jquery.mobile-1.1.0.min.js", siteConf.uri + "/nowjs/now.js", "site.js"],
debug: siteConf.debug,
stale: !siteConf.debug
},
css: {
route: /\/static\/css\/[a-z0-9]+\/.*\.css/,
path: "./public/stylesheets/",
dataType: "css",
files: ["libs/jquery.mobile-1.1.0.min.css", "style.less"],
debug: siteConf.debug,
stale: !siteConf.debug,
preManipulate: {
"^": [
function(file, path, index, isLast, callback) {
var match;
match = path.match(/\.less$/);
if ((match != null) && match.length > 0) {
return less.render(file, function(e, css) {
return callback(css);
});
} else {
return callback(file);
}
}
]
}
}
};
</pre>
<br />
The import part is the <b>preManipulate</b> line under <b>css</b> but I include my entire <b>assetsSettings</b> from a project to make it easier to understand.Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-13239572463495716412012-05-01T14:17:00.000-05:002012-05-01T14:17:53.896-05:00MonoTouch JsBridge - Communicate with the UIWebViewToday I'm open sourcing <a href="https://github.com/crdeutsch/MonoTouch-JsBridge">JsBridge for MonoTouch</a> which allows for bidirectional communication between the javascript in your UIWebViews and your native C# code in your MonoTouch app. Go directly to <u><a href="https://github.com/crdeutsch/MonoTouch-JsBridge">GitHub</a></u> for the documentation on how to use it.<br />
<br />
This project was inspired by doing a project using <a href="http://www.appcelerator.com/">Appcelerator's Titanium</a>. In fact the javascript used in JsBridge was taken directly from that project, so if you're used to using Titanium you should be right at home using JsBridge.<br />
<br />
At this time it requires <a href="http://docs.xamarin.com/ios/releases/MonoTouch_5/MonoTouch_5.3#MonoTouch_5.3.3">MonoTouch 5.3.3</a>, which as of 5/1/2012 is in Alpha, because JsBridge needs to register a custom url protocol using NSUrlProtocol.<br />
<br />
I'm not 100% satisfied with the implementation of the event listeners on the native side, so I'm open to suggestions on how to make it better. Ideally some day the Xamarin team will implement something like this in a future version. ;)<br />
<br />
I've already submitted my first app to use it the iOS AppStore and it relies heavily on bidirectional communication between javascript and native. The app is a remote control for <a href="http://www.rdio.com/">Rdio's new UI</a>. A nicely executed feature by Rdio (even if it came way after the <a href="http://partyq.us/">chrome extension remote</a> I made for their first UI ;) ), but unfortunately it doesn't work on iOS partially due to the Rdio servers not supporting the Websockets protocol that the UIWebView has. Using JsBridge I was able to implement the WebSocket connection on the native side and override the Rdio javascript calls that use WebSockets and pass them to the native side and vice versa. I'm quite pleased with the results so far. ;)<br />
<br />Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-33596761214100942452012-03-28T18:25:00.000-05:002012-03-28T18:25:44.541-05:00Solved: Video.Js Playback Error in IE9<h3>TL;DR:</h3>Make sure your server (including Amazon CloudFront) is setting the correct mime type when returning the video file.<br />
<br />
For <b>.mp4</b> files the mime type should be <b>video/mp4</b><br />
<br />
<h3>ISSUE:</h3>I spent about an hour baffled why IE9 wouldn't play an H.264 video that Chrome and Firefox played fine.<br />
<br />
The only lead I had was this message output by <a href="http://videojs.com/">Video.js</a> using <b>console.log</b>:<br />
<br />
<div class="p1"><span style="color: red;">Video Error[object Object] </span></div><br />
What's more annoying is that IE9 doesn't let you inspect objects that are output by <b>console.log</b>. To get around that you can install the <a href="http://getfirebug.com/firebuglite">Firebug Lite</a> bookmarklet. Unfortunately in this case the object doesn't give you much more to go on.<br />
<br />
I tried swapping videos and found it worked with the sample Video.js video, which usually indicates a mime type issue (which seems to be a recurring issue with Microsoft products).<br />
<br />
I was using Amazon CloudFront to server the videos (download style as opposed to streaming) and figured I couldn't set the mime type but it turns out you can:<br />
<ol><li>Go into S3 and find your video file.</li>
<li>Right click and select <b>Properties</b></li>
<li>Select the <b>Metadata</b> tab</li>
<li>In this case, set <b>Key</b> = <b>Content-Type</b> and <b>Value</b> = <b>video/mp4</b></li>
<li>Press <b>Save</b> button</li>
</ol>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-31285410330599479472012-02-29T18:45:00.004-06:002012-03-01T10:39:00.391-06:00MonoTouch.Dialog UIPickerIn iOS a UIPicker looks like this:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAO5J3HM7quxcdljJ8nw6_xUmVJ4pmC3KhWxOVH5XsQ6OM9bt7NEoq2Ud2VD9_-GtIogl81DNyVK65LRi2k2ll23SLSVHDfMEzrOAj2vC3hptbjweTedO66zSZmX8Nj32ShYzHz9cR-os/s1600/Screen+Shot+2012-02-29+at+6.50.06+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAO5J3HM7quxcdljJ8nw6_xUmVJ4pmC3KhWxOVH5XsQ6OM9bt7NEoq2Ud2VD9_-GtIogl81DNyVK65LRi2k2ll23SLSVHDfMEzrOAj2vC3hptbjweTedO66zSZmX8Nj32ShYzHz9cR-os/s400/Screen+Shot+2012-02-29+at+6.50.06+PM.png" width="207" /></a></div><br />
<div style="clear: both; text-align: center;"></div>I'm working on an iPhone application that's built using <a href="http://tirania.org/blog/archive/2010/Feb-23.html">MonoTouch.Dialog</a> and after a full day of trying to get the MonoTouch.Dialog compatible Picker in <a href="https://github.com/Clancey/ClanceyLib">ClanceyLib</a> to work, I've decided to package up my work and <a href="https://github.com/crdeutsch/MonoTouch.Dialog-PickerElement">release it on GitHub</a>.<br />
<br />
The main issues with ClanceyLib is that it requires a heavily modified and out of date version of MonoTouch.Dialog. If you try to compile it with the built-in version of MonoTouch.Dialog you'll get the following two errors:<br />
<br />
<i><span style="color: #cc0000; font-size: x-small;">/Users/guivho/Mono/ClanceyLib/ClanceysLib/MT.D/ButtonElement.cs(49,49):</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">Error CS0115: `ClanceysLib.ButtonElement.GetCell(MonoTouch.Dialog.DialogViewController,</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">MonoTouch.UIKit.UITableView)' is marked as an override but no suitable</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">method found to override (CS0115) (ClanceysLib)</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;"><br />
</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">/Users/guivho/Mono/ClanceyLib/ClanceysLib/MT.D/ComboBoxElement.cs(49,49):</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">Error CS0115: `ClanceysLib.ComboBoxElement.GetCell(MonoTouch.Dialog.DialogViewController,</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">MonoTouch.UIKit.UITableView)' is marked as an override but no suitable</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;">method found to override (CS0115) (ClanceysLib)</span></i><br />
<i><span style="color: #cc0000; font-size: x-small;"><br />
</span></i><br />
Ripping out the elements you need from ClanceyLib wasn't as easy as I hoped on the first try but I now have it working along with some other improvements:<br />
<ul><li>Updated it to hide the keyboard or picker when selecting different cells to edit.</li>
<li>Changed so the <b>Items</b> in the Picker list are <b>UIView</b>'s for greater customization.</li>
<li>Actually has a sample of how to use it. ;)</li>
</ul><div>UPDATE 3/1/2012: It works out of the box with the version of <a href="http://docs.xamarin.com/ios/tutorials/MonoTouch.Dialog">MonoTouch.Dialog that is now packaged with MonoTouch</a>. But, it will not dismiss the picker when selecting a different cell. To enable that feature it requires a <a href="https://github.com/crdeutsch/MonoTouch.Dialog">custom version of MonoTouch.Dialog</a> and you'll need to comment in 3 lines of code in <b>PickerElement.cs.</b></div><div><br />
</div><div>I sent a <a href="https://github.com/migueldeicaza/MonoTouch.Dialog/pull/106">pull request</a> to get my minor change to <a href="https://github.com/migueldeicaza/MonoTouch.Dialog">MonoTouch.Dialog</a> included in the core. If/when it's pulled I will update PickerElement.cs to take advantage of it and the dependency on the custom version of MonoTouch.Dialog will be no more. ;)</div><div><br />
</div>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-76554014713332327362012-02-09T09:34:00.000-06:002012-02-09T09:34:27.707-06:00setTimeout Setting Mysterious Callback ParametersI got burned by this twice in the last month.<br />
<br />
Say you want to call the following function after 5 seconds.<br />
<pre class="Cpp" name="code">function doSomething(optionalParam) {
// check if optional param passed in.
if (optionalParam) {
optionalParam.foo(); // this is where the error sometimes happens.
}
// do more stuff.
}
// delay 5 seconds.
setTimeout(doSomething, 5000);
</pre><br />
Periodically I was getting <b>undefined errors</b> when trying to call <b>foo()</b>. After <a href="http://stackoverflow.com/questions/5383479/firefox-settimeoutfunc-ms-sending-default-parameters-to-callback">some googling</a>, it turns out Gecko browsers have <b>setTimeout</b> pass back an extra parameter indicating the "actual lateness" of the timeout in milliseconds.<br />
<a href="https://developer.mozilla.org/en/DOM/window.setTimeout">https://developer.mozilla.org/en/DOM/window.setTimeout</a><br />
<br />
I haven't run into this with other browsers but to avoid the issue it's best to do the following when your callback functions have optional params (Not having optional params would obviously be even safer).<br />
<pre class="Cpp" name="code">// delay 5 seconds.
setTimeout(function() {
doSomething();
}, 5000);
</pre>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-68325190092827242582011-10-25T20:59:00.001-05:002011-10-28T15:51:58.249-05:00Using Siri For Home AutomationI've created a <a href="http://www.twilio.com/">Twilio</a>, <a href="http://nodejs.org/">Node.js</a> mash up that allows me to control appliances and the thermostat in my house using the iPhone 4S's Siri voice recognition.<br />
<br />
Here's a demo of turning on my bedroom fan.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/B9PbhZy_xk0" width="560"></iframe><br />
<br />
How does this work? From Siri to the end result the chain goes:<br />
<ol><li>Siri </li>
<li>Twilio SMS number</li>
<li>Node web application</li>
<li><a href="http://www.perceptiveautomation.com/indigo/index.html">Indigo</a> Web Server</li>
<li><a href="http://www.insteon.net/">Insteon</a> thermostat/appliance</li>
</ol><br />
Let's go through the setup in reverse order in more detail.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Insteon and Indigo</span><br />
<br />
I purchased the following items last year from Amazon to add some basic home automation to my house.<br />
<ul><li><a href="http://www.amazon.com/gp/product/B0052V8SV0/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=217145&creative=399373&creativeASIN=B0052V8SV0">Indigo 4 Pro INSTEON-compatible Home Automation Software for Mac</a> $179.98</li>
<li><a href="http://www.amazon.com/gp/product/B0015ROPTO/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=217145&creative=399369&creativeASIN=B0015ROPTO">ApplianceLinc - INSTEON Plug-in Appliance On/Off Module, 3-Pin</a> $34.99 </li>
<li><a href="http://www.amazon.com/gp/product/B0013ZEQ3S/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=217145&creative=399369&creativeASIN=B0013ZEQ3S">Venstar Thermostat - INSTEON Remote Control Thermostat 7-Day Programmable </a> $199.99 </li>
<li><a href="http://www.amazon.com/gp/product/B002XA8XNQ/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=217145&creative=399373&creativeASIN=B002XA8XNQ">PowerLinc Modem - INSTEON USB Interface (Dual-Band)</a> $79.99 </li>
</ul><br />
I have a Mac Mini I use as a server which is connected to the PowerLinc Modem via USB. The Indigo software communicates two-way with the Insteon devices in my home via the PowerLinc. In addition to a native iPhone app, the Indigo software has both a web interface and <a href="http://www.perceptiveautomation.com/wiki/doku.php?id=indigo_s_restful_urls">RESTful Api</a> you can use to control your devices.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Node.js Web Application</span><br />
<br />
The <a href="http://nodejs.org/">Node.js</a> application is the middle man between Twilio and the Indigo web server. When Twilio <a href="http://www.twilio.com/docs/api/twiml/sms/twilio_request">POSTs</a> the incoming SMS message to the Node app, it parses the message and determines the appropriate Api call to make on the Indigo web server. I wrote some semi-fuzzy logic so the phrases you use don't have to be exact.<br />
<br />
For hosting the Node app I picked <a href="http://devcenter.heroku.com/articles/node-js">Heroku</a> because it's convenient to use and free.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Twilio</span><br />
<br />
Setting up Twilio was super easy. I created a Twilio account, purchased a phone number for $1/month, and entered the Url of my Node app that receives the incoming SMS messages.<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Siri</span><br />
<br />
To make communicating with my Twilio phone number easy I added a contact called "Gladys" (could be anything but I'm a <a href="http://www.amazon.com/gp/product/B00523TZ8I/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=217145&creative=399373&creativeASIN=B00523TZ8I">Portal</a> fan) and associated the Twilio number with her.<br />
<br />
I can now control my appliances using the following commands:<br />
<ul><li><i>Tell Gladys to set thermostat to 73</i></li>
<li><i>Tell Gladys to turn off the bedroom fan</i></li>
</ul><br />
<br />
I originally wanted to turn this into a public <i>Siri to Url</i> web service, but I question the demand for such a thing considering trying to make this "generic" would take a lot of time. So if you're interested in adding Siri control to your own use case and don't have programming skills, I'm <a href="http://makerocketgonow.com/">available for hire</a> and can whip you up something to suite your exact needs. ;)<br />
<br />
UPDATE 10/28/2011:<br />
Big thanks to <a href="http://technabob.com/blog/2011/10/28/siri-home-automation/">technabob</a> for the coverage! He brought up a good point though, this could easily be faked. Here's a screen shot of my Heroku logs with debugging output on the left and Node.js code for the "fuzzy logic" on the right. Not indisputable evidence but I assure you it's working exactly like it does in the video. ;)<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkUUJGirALg_mlW2BpwKVrtDq_acvUG8E0C0kgGYnQITXNVdqfhotiYPxh0CnsW45QXT5zVktGCM1O5S9zRI4PCfJ5ycmmsFlRdfr0ZvTDcCkbfLayKt_iOicgsdF-1rRD5TGfww4Vkzg/s1600/Screen+Shot+2011-10-28+at+3.39.43+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="419" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkUUJGirALg_mlW2BpwKVrtDq_acvUG8E0C0kgGYnQITXNVdqfhotiYPxh0CnsW45QXT5zVktGCM1O5S9zRI4PCfJ5ycmmsFlRdfr0ZvTDcCkbfLayKt_iOicgsdF-1rRD5TGfww4Vkzg/s640/Screen+Shot+2011-10-28+at+3.39.43+PM.png" width="640" /></a></div>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-11448776603788607592011-10-16T11:12:00.000-05:002011-10-16T11:12:07.898-05:00Windows 7 Registry Entry to Search All File ContentsIf you do a search in Windows 7 you may notice that it didn't find some files that you know contain the search terms you are looking for.<br />
This is due to the <b>What to search</b> setting in Windows Explorer under <b>Folder Options </b>-> <b>Search</b> as pictured below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6eRXkpdlDGPOeujfcvMbBFd8HGAxHiflLa29cmOx_U5SPPpsVmr1d-Ql57MvUMlHyDXl2YvqHtPXxFfs6TcqS6s9WquTG1cAwc-WfnyO67F6lHcBv5F0ndwcTOn6J6Su6dIKcLv4w-QY/s1600/Screen+Shot+2011-10-16+at+10.41.05+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6eRXkpdlDGPOeujfcvMbBFd8HGAxHiflLa29cmOx_U5SPPpsVmr1d-Ql57MvUMlHyDXl2YvqHtPXxFfs6TcqS6s9WquTG1cAwc-WfnyO67F6lHcBv5F0ndwcTOn6J6Su6dIKcLv4w-QY/s400/Screen+Shot+2011-10-16+at+10.41.05+AM.png" width="333" /></a></div><br />
If you don't have <b>Always search file names and contents</b> selected Windows will only search the files it has indexed.<br />
<br />
You can change the setting using the UI as shown above but you can also set it by changing the following Registry setting (which is useful if you want to programmatically set if for users):<br />
<br />
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Search\PrimaryProperties\UnindexedLocations]<br />
<br />
"SearchOnly"=dword:00000000<br />
<br />
Originally I tried to change the following key based on <a href="http://weblogs.asp.net/owscott/archive/2008/04/04/enabling-xp-and-windows-server-2003-to-search-all-files-types.aspx">Scott Forsyth's solution</a> for Windows XP and Windows Server 2003 but it didn't work for me on Windows 7:<br />
<br />
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ContentIndex]<br />
<br />
"FilterFilesWithUnknownExtensions"=dword:00000001<br />
<br />
<br />
As a bonus tip, this is how I found where the Windows 7 registry key was.<br />
<ol><li>Open Registry Editor</li>
<li>Right click the registry hive you suspect the setting to be in (usually either HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE) and select <b>Export</b> and save the .reg file (ex: hklm1.reg)</li>
<li>Change the setting via normal means.</li>
<li>Repeat steps 2 and 3 and save the file with a new name (ex: hklm2.reg).</li>
<li>Use a Diff tool such as the one include with <a href="http://tortoisesvn.net/">Tortoise SVN</a> or <a href="http://code.google.com/p/tortoisegit/">Tortoise Git</a> to search for changes.</li>
</ol><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhW3dWyfMo7KILM15y9H5XqaKdToQ_HJkl27tMVb65tgeXaw7noqtnUxGjOyKZUlkhWPFMKlBcUhfFwVASn-jLB8is9tXm6u2faWk57uAYYSh93k7HBF9nXiDWTnCybTOhX4zj-tAERY/s1600/Screen+Shot+2011-10-16+at+10.40.33+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="574" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhW3dWyfMo7KILM15y9H5XqaKdToQ_HJkl27tMVb65tgeXaw7noqtnUxGjOyKZUlkhWPFMKlBcUhfFwVASn-jLB8is9tXm6u2faWk57uAYYSh93k7HBF9nXiDWTnCybTOhX4zj-tAERY/s640/Screen+Shot+2011-10-16+at+10.40.33+AM.png" width="640" /></a></div>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-61553399488297006322011-09-28T09:25:00.001-05:002011-09-28T09:27:39.744-05:00jQuery Mobile Displaying A DialogWhile working on a mobile web app that is using <a href="http://jquerymobile.com/">jQuery Mobile</a> I wanted to display a dialog without making an Ajax call to the server to load it which is the "<a href="http://jquerymobile.com/demos/1.0b3/docs/pages/page-dialogs.html">out of the box</a>" way to do it.<br />
<br />
Initially I couldn't figure out how to do this but after some reading and thinking it's ridiculously easy.<br />
<br />
You have to use a <a href="http://jquerymobile.com/demos/1.0b3/docs/pages/multipage-template.html">multi-page template</a> which means you have more then one jQuery Mobile "page" container. Example:<br />
<pre class="html" name="code"><div data-role="page" data-theme="a">
<div data-role="header" class="header">
<a href="#menu" data-icon="grid" data-theme="b" data-iconpos="notext" data-transition="pop">&nbsp;</a>
<h1>My Web App</h1>
</div>
<div id="map" data-role="content" data-theme="d">
<p>This is my main content</p>
</div>
<div data-role="footer">
<div>
by <a href="http://cdeutsch.com" rel="external">CDeutsch</a>
</div>
</div>
</div>
<!--start menu-->
<div id="menu" data-role="dialog" data-theme="a" data-url="menu">
<div data-role="header" class="header">
<h1>Main Menu</h1>
</div>
<div data-role="content" data-theme="d">
<ul data-role="listview" data-theme="c">
<li><a href="http://blog.cdeutsch.com" rel="external">My Blog</a></li>
<li><a href="http://twitter.com/cdeutsch" rel="external">Twitter</a></li>
</ul>
</div>
</div>
</pre><br />
I'm using a button on the left side of the header to trigger showing the dialog. Just set the <b>href</b> to the id of the dialog (in this case <b>menu</b>) and you're all set. No more repeatedly hitting the server for a frequently used resource.<br />
<br />
See <a href="http://jsfiddle.net/cdeutsch/CaGB4/">this jsfiddle</a> for a working example.Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-89700089574643092012011-09-06T18:48:00.000-05:002011-09-06T18:48:14.646-05:00Entity Framework Code First Error: Could not create constraintWhile using Entity Framework Code First you will run into an error similar to the one below if you create objects that have a circular reference.<br />
<br />
<b><span class="Apple-style-span" style="color: red;">Introducing FOREIGN KEY constraint 'File_Folder' on table 'Filess' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.</span></b><br />
<b><span class="Apple-style-span" style="color: red;">Could not create constraint. See previous errors.</span></b><br />
<b><span class="Apple-style-span" style="color: red;"><br />
</span></b><br />
The fix is pretty simple but not very intuitive.<br />
<br />
Add the following line to your OnModelCreating override of your DbContext:<br />
<br />
<pre class="Cpp" name="code">modelBuilder.Entity<File>().HasRequired(oo => oo.Folder).WithMany(oo => oo.Files).WillCascadeOnDelete(false);
</pre><br />
So it looks something like this:<br />
<br />
<pre class="Cpp" name="code">public class FilesystemDB : DbContext
{
public DbSet<File> Files { get; set; }
public DbSet<Folder> Folders { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<File>().HasRequired(oo => oo.Folder).WithMany(oo => oo.Files).WillCascadeOnDelete(false);
}
}
</pre><br />
For the best information on Entity Framework Code First read <a href="http://weblogs.asp.net/manavi/">Morteza Manavi's blog</a>.Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-88379591679687117932011-08-25T16:21:00.004-05:002011-08-25T16:40:34.200-05:00Remove Duplicates From Rdio PlaylistsThis has driven me nuts ever since I started using <a href="http://click.linksynergy.com/fs-bin/click?id=/V7Z*/6luyc&offerid=221756.10000006&type=3&subid=0" >Rdio</a><img border=0 width=1 height=1 src="http://ad.linksynergy.com/fs-bin/show?id=/V7Z*/6luyc&bids=221756.10000006&type=3&subid=0" > (sign up using this link to support me). I like to listen to other peoples playlists to find new music and if I hear something I like I add the track to my "favorites" playlist. Unfortunately Rdio lets you add the same song multiple times to the same playlist and there isn't an easy way to find and remove duplicates so I end up with Ice Cube's <a href="http://www.rdio.com/#/artist/Ice_Cube/album/Ice_Cube%27s_Greatest_Hits/track/Check_Yo_Self_%28Remix%29_%28%29/">Check Yo Self</a> in my favorites 5 times.<br />
<br />
Here's my solution.<br />
1) <a id="codeOut" href='javascript:(function(){var count=0;function removeDups(){var a=false;$("div.playlist_song_list div.track").each(function(c,d){if(!a){var b=$(this).parents("div.playlist_song_list").attr("sid");if(b){b="p"+b;$("div.playlist_song_list div.track[track_key="+$(this).attr("track_key")+"]").each(function(g,e){if(g>0&&!a){a=true;var f=$(this);R.Api.request({method:"removeFromPlaylist",content:{playlist:b,index:f.parent().index(),count:1,tracks:[f.attr("track_key")]},success:function(){count=count+1;f.parent().remove();removeDups()}})}})}}});if(!a){alert(count+" tracks removed.")}}removeDups();})();'>Install this bookmarklet</a> by dragging it to your bookmarks or right clicking and selecting "add to bookmarks"<br />
2) Browse to the playlist you want to cleanup in Rdio<br />
3) Run the bookmarklet.<br />
<br />
If you're interested in other Rdio hacks be sure to checkout my Rdio remote control <a href="http://partyq.us">PartyQ</a><br />
<br />
<br />
Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-49381623225878109292011-07-30T10:12:00.008-05:002012-10-17T18:30:24.185-05:00OSX Crashes More Then WindowsThere! I said it!<br />
<br />
For the record, all my computer hardware, phones, and tablets have been Apple for years; but I primarily do programming in .NET which means I still need to use Windows.<br />
<br />
I'm on my 3rd Macbook Pro since Sept of 2007 and over that time OSX has consistently crashed more then Windows XP and Windows 7. Up until April of this year, I was primarily booting directly into Windows using Bootcamp and only using OSX 5% of the time and even with 5% use it had more complete lock ups!<br />
<br />
Since April I've started running OSX 100% of the time and run Windows 7 off the Bootcamp partition using Parallels.<br />
<br />
Since making the switch to 100% of the time I'd estimate OSX does a Black Screen of Death on average 3-4 times per month. I had one waiting for me this morning after leaving the computer on over night.<br />
<br />
People think I'm making this up, so I plan to start <a href="http://twitter.com/cdeutsch">tweeting</a> every time it crashes for a historical record.<br />
<br />
Granted I have a ton of software loaded on OSX, I'm running <a href="http://www.parallels.com/">Parallels</a>, and I use a <a href="http://www.amazon.com/gp/product/B002GHBW4S/ref=as_li_ss_tl?ie=UTF8&tag=cdeutschcom-20&linkCode=as2&camp=217145&creative=399369&creativeASIN=B002GHBW4S">Diamond BVU195 USB Display Adapter</a> for a second monitor, BUT other then Parallels these are all things I did on Windows as well so I feel it's a fair comparison.<br />
<br />
I've had Windows get slow, or weird, or need a reboot. But I can't remember the last Blue Screen of Death I've had, I can usually kill enough process where I can shut down the OS gracefully. I can't say the same for OSX.<br />
<br />
I don't plan on switching away from my current setup and I'll be installing Lion soon. I just want people to STFU about how stable OSX is versus Windows, because it's simply not true.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Crash Log</span><br />
<ul>
<li>7/30/2011</li>
<li>8/17/2011 (Milestone: first crash of OSX Lion)</li>
<li>9/8/2011</li>
<li>9/19/2011</li>
<li>9/25/2011</li>
<li>9/30/2011</li>
<li>10/14/2011</li>
<li>11/3/2011</li>
<li>5/25/2012</li>
<li>6/22/2012</li>
<li>8/3/2012 (Milestone: first crash of OSX Mountain Lion)</li>
<li>8/9/2012</li>
<li>8/16/2012</li>
<li>8/17/2012</li>
<li>8/17/2012 (second time in one day, grrr)</li>
<li>8/20/2012</li>
<li>8/22/2012</li>
<li>10/14/2012</li>
<li>10/17/2012</li>
</ul>
Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-21220981168151446962011-07-15T15:18:00.005-05:002011-08-15T14:50:21.178-05:00ASP.NET MVC3 App Using plupload to Upload Directly to Amazon S3UPDATE 8/15/2011:<br />
I can't recommend using this for large files (video files). It's very unreliable. Web size image files and normal email attachment sized files would probably do fine. What I ended up doing to get around it was creating a web app on AppHarbor (which runs on EC2) that I upload the files to and it saves them to S3. Since the AppHarbor app is on a different domain you are still limited to Flash and Silverlight support but you do gain file chunking which brings back some reliability. Alternatively to AppHarbor you could setup your own server on Amazon as well.<br />
<br />
I created a working example of using <a href="http://www.plupload.com/">plupload</a> to upload files directly to Amazon S3 and threw it on github, since the .NET examples I found on the web we're incomplete or broken.<br />
<a href="https://github.com/crdeutsch/MVC3PluploadToAmazonS3">https://github.com/crdeutsch/MVC3PluploadToAmazonS3</a><br />
<br />
The files that are being uploaded do not even touch your web server. They are posted directly to Amazon. At the moment plupload only supports the Flash and Silverlight plugins as far as I can tell.<br />
<br />
The AmazonS3Helper.cs library originated from Cary Abramoff off of this <a href="http://www.plupload.com/punbb/search.php?action=show_user_posts&user_id=6207">plupload forum thread</a>.<br />
<br />
I've made some changed based on iwasrobbed's excellent <a href="https://github.com/iwasrobbed/Rails3-S3-Uploader-Plupload">Ruby on Rails example</a>.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">Usage</span><br />
<br />
Upload the crossdomain.xml found in the root of the site to your Amazon S3 Bucket.<br />
<br />
<pre class="html" name="code"><?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" secure="false" />
</cross-domain-policy>
</pre><br />
Modify the settings in <b>HomeController.cs</b> to use your Amazan credentials and set your S3 bucket.<br />
<br />
<pre class="Cpp" name="code">public ActionResult Index()
{
string acl = "private";
string bucket = "YOUR S3 BUCKET NAME";
string accessKeyId = "YOUR AMAZON ACCESS KEY ID";
string secret = "YOUR AMAZON SECRET ACCESS KEY";
string policy = AmazonS3Helper.ConstructPolicy(bucket, DateTime.UtcNow.Add(new TimeSpan(0, 10, 0, 0)), acl, accessKeyId);
string signature = AmazonS3Helper.CreateSignature(policy, secret);
var model = new PluploadAmazonS3Model()
{
AWSAccessKeyId = accessKeyId,
Policy = policy,
Signature = signature,
Bucket = bucket,
Acl = acl
};
return View(model);
}
</pre><br />
On the View side you could just use Razor to dump the Model variables directly into your javascript, but I decided to use hidden form variables instead in case you want to move the javascript to its own file where embedding Razor syntax won't work.<br />
<br />
Hope this saves somebody else some time!Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-7505704235727430642011-07-01T16:10:00.000-05:002011-07-01T16:11:20.053-05:00ASP.NET & IIS7 Error: Could not load file or assembly 'System.Data.SQLite'This was annoying. I setup an ASP.NET MVC3 web application on a fresh install of Windows 2008 R2 and got the following error:<br />
<div style="color: red;">Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. An attempt was made to load a program with an incorrect format.</div><div style="color: red;"><br />
</div><div style="color: red;"><span style="color: black;">I wasn't even using SQLite in my project; at least that's what I thought. Turns out <a href="http://code.google.com/p/elmah/">ELMAH</a> was trying to load it.</span></div><div style="color: red;"><br />
</div><div style="color: red;"><span style="color: black;">The error is due to trying to load the 32bit SQLite.dll on a 64 bit server.</span></div><div style="color: red;"><br />
</div><div style="color: red;"><span style="color: black;">To fix the error set <b>Enable 32-Bit Applications</b> to <b>True</b> for your <b>Application Pool</b> under <b>Advanced Settings</b>.</span></div><div style="color: red;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhklxQ26-uQpN0enh9G0tQ3hkEF7lfDfmZVhEuOgNYYW980lRNwAKIrzWgIdSQGjLX3A3XPXcEfMsNsH1ZahP3MGWueswIslAkz0eY7Y2T4P3rLoBM3wuAdn5u4UKmpmOBEBJo9M3IET3E/s1600/Screen+shot+2011-07-01+at+4.09.34+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="273" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhklxQ26-uQpN0enh9G0tQ3hkEF7lfDfmZVhEuOgNYYW980lRNwAKIrzWgIdSQGjLX3A3XPXcEfMsNsH1ZahP3MGWueswIslAkz0eY7Y2T4P3rLoBM3wuAdn5u4UKmpmOBEBJo9M3IET3E/s320/Screen+shot+2011-07-01+at+4.09.34+PM.png" width="320" /></a></div><div style="color: red;"><br />
</div><div style="color: red;"><br />
</div><div style="color: red;"><br />
</div><div style="color: red;"><br />
</div>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.comtag:blogger.com,1999:blog-1253809763177644913.post-69868769913022177522011-05-01T10:20:00.000-05:002011-05-01T10:20:43.805-05:00Introducing NodelerAfter over a month of work I'm ready to subject my latest work, <a href="http://nodeler.com/login?code=MakeRocketGoNow">Nodeler</a>, to the criticisms of the first 50 people who sign up using the Invite Code <b>MakeRocketGoNow</b>. ;)<br />
<br />
Here's a video introduction to Nodeler. Otherwise read on...<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="349" src="http://www.youtube.com/embed/ouXB1a0I5cw" width="425"></iframe><br />
<br />
<span class="Apple-style-span" style="font-size: large;">What is it?</span><br />
At it's heart I kind of think of it as a higher level, <a href="http://en.wikipedia.org/wiki/Zero_configuration_networking">zero configuration</a> service (Apple calls theirs <a href="http://en.wikipedia.org/wiki/Bonjour_%28software%29">Bonjour</a>).<br />
<br />
<span class="Apple-style-span" style="font-size: large;">What good does that do me?</span><br />
If you're a developer, it will allow you to register your application or game as a "node" that can request to be paired with other "nodes". A node can be anything from a game node requesting to be paired with a controller node to a video web site node requesting a remote control node.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">You're not a developer?</span><br />
Today, there are three Chrome extensions plus a Pacman game you can try.<br />
<ol><li><b>Nodeler Keyboard</b>: allows you to accept keyboard input on any web page from a remote device.</li>
<li><b>Nodeler Rdio Remote</b>: allows you to remotely control the Rdio player. Play, pause, mute, and skip forward and back are currently supported.</li>
<li><b>Nodeler Amazon Video Remote</b>: allows you to remotely control the Amazon Video On Demand player. Play, pause, skip forward and back are currently supported.</li>
<li><b>Pacman</b>: I've modified <a href="http://twitter.com/daleharvey/">Dale Harvey's</a> excellent <a href="http://arandomurl.com/2010/07/25/html5-pacman.html">HTML5 Pacman</a> app to be controllable via a Nodetroller (what I like to call the applications used to provide input to the above Chrome extensions).</li>
</ol><span class="Apple-style-span" style="font-size: large;">You are a developer?</span><br />
Send me an <a href="mailto:cd@cdeutsch.com">email</a> if you're interested in using the Nodeler API. Once your Nodes are registered and authenticated via OAuth there are currently just two API calls. <b>Node A</b> submits a <b>PairRequest</b> and then <b>Node B</b> calls <b>GetPairRequests</b>. The protocol used to communicate between nodes is up to you. If you need a central communication server I hope to offer the Nodeler Central's Node.js server in the near future. This is what the current nodes use. I'm still working out how I want to charge for usage of the Nodeler Central communication server but I do plan to have a free plan.<br />
<br />
<span class="Apple-style-span" style="font-size: large;">You're still reading and want to know what technologies this was built with?</span><br />
Just C# and Javascript. ;)<br />
<br />
The Nodeler web site and API are hosted at AppHarbor and were built with:<ul><li>ASP.NET MVC3</li>
<li>Entity Framework Code First</li>
<li><a href="https://github.com/crdeutsch/MVC3-Boilerplate">MVC3 Boilerplate</a></li>
<li>DotNetOpenAuth</li>
</ul><br />
The server the Nodes communicate through is built using:<ul><li><a href="http://nodejs.org/">Node.js</a></li>
<li><a href="http://socket.io/">Socket.IO</a></li>
</ul><br />
The Chrome Extensions use:<ul><li><a href="http://jquery.com/">jQuery</a></li>
<li><a href="http://socket.io/">Socket.IO</a></li>
</ul><br />
The iPhone app that I'm just finishing up was built using:<ul><li><a href="http://monotouch.net/">MonoTouch</a></li>
<li><a href="https://github.com/migueldeicaza/MonoTouch.Dialog">MonoTouch.Dialog</a></li>
<li><a href="http://restsharp.org/">RestSharp</a></li>
</ul><br />
<span class="Apple-style-span" style="font-size: large;">How can I find out more?</span><br />
Follow <a href="http://twitter.com/cdeutsch">me</a> or <a href="http://twitter.com/nodeler">Nodeler</a> on Twitter for updates.<br />
<br />
Would love to hear feedback on how I can improve the product!<br />
<br />
<br />
<ol></ol>Christopherhttp://www.blogger.com/profile/03545123838002391970noreply@blogger.com