tag:blogger.com,1999:blog-9270765837761797042024-03-13T21:40:58.395-07:00Wayne's (Geek) WorldRandom experiences and thoughts from my more technical side...Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-927076583776179704.post-21124584566419150232011-07-30T19:31:00.000-07:002011-07-30T19:32:29.140-07:00AirPlay from OS X Lion iTunes to Apple TV 2<div class="separator" style="clear: both; text-align: left;">
One day, shortly after getting a brand new Apple TV 2, I wanted to use Airplay to play music from iTunes on my iMac to both the iMac speakers and through TV via Apple TV. Seems easy enough....start playing some tunes, then select both the iMac and the Apple TV from iTunes' speaker selection menu. Right?.....wrong!</div>
<br />
When I selected Apple TV on the speakers menu, I got a popup saying "Connecting to 'Apple TV'...". It stayed up for a few seconds, then went away -- but no music on the TV. What the ? I tried again with no luck...this time noticing that the Apple TV selection in the iTunes speaker selection menu had a lock icon next to it. I assume that means I need to enter the Apple TV's Airplay password...but I haven't been prompted for it.<br />
<br />
After googling for awhile I came across this <a href="http://www.soyo123.com/2010/11/itunes-10-wont-connect-to-apple-tv-with.htm">blog post</a> which described how <a href="http://en.wikipedia.org/wiki/IPv6">IPv6</a> settings in OS X affected (i.e. completely freakin' broke) AirPlay from iTunes to Apple TV. The solution outlined in the blog post was to go into <strong>System Preferences » Network</strong>, and in the settings for your network connection (i.e. AirPort, Ethernet, etc.) set <strong>Configure IPv6</strong> to "Off" in the <strong>Advanced...</strong> menu.<br />
<br />
This solution was going along fairly smoothly right up to the point where there wasn't an "Off" option in the Configure IPv6 menu. The only visible options were "Automatically", "Manually" and "Link-local only". Uh oh...what now?<br />
<br />
Well, it turns out that the OS X Lion update changed things a bit here. The "Off" option is no longer available. So how do you disable IPv6? You "hack it" of course. As I found in <a href="https://discussions.apple.com/thread/3202188?start=0&tstart=0">this forum post</a>, although the "Off" option is no longer visible through the System Preferences user interface, it is still a valid option. Here's how you get it back (Warning: this involves command line geek stuff...not for the faint of heart):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<ol>
<li>Open Terminal</li>
<li>Type <span style="font-family: 'Courier New', Courier, monospace;">cd /Library/Preferences/SystemConfiguration</span></li>
<li><span style="font-family: inherit;">Type</span><span style="font-family: 'Courier New', Courier, monospace;"> sudo vi preferences.plist</span><span style="font-family: inherit;">. This opens the </span><span style="font-family: 'Courier New', Courier, monospace;">preferences.plist</span><span style="font-family: inherit;"> file in an old-school Unix text editor called <a href="http://en.wikipedia.org/wiki/Vi">vi</a>.</span></li>
<li><span style="font-family: inherit;">Hit the "a" key. This puts vi in "insert mode".</span></li>
<li><span style="font-family: inherit;">Using the arrow keys, navigate to the section in the file that looks similar to below <span style="text-decoration: underline;">for the network connection you're using</span> (i.e. AirPort, Ethernet, etc.), and change whatever value is there to "__INACTIVE__".<br /><br /><span style="font-family: Courier; font-size: 12px;"><key>IPv6</key></span><br /><span style="font-family: Courier; font-size: 12px;"><dict></span><br /><span style="font-family: Courier; font-size: 12px;"> <key>ConfigMethod</key></span><br /><span style="font-family: Courier; font-size: 12px;"> <string><span style="color: red; font-size: 12px;"><strike>Automatic</strike></span><span style="color: #1c9800;"><b>__INACTIVE__</b></span></string></span><br /><span style="font-family: Courier; font-size: 12px;"></dict></span></span></li>
<li>Hit the "Esc" key. This gets you out of "insert mode" in vi and back into "command mode".<span style="font-family: inherit;"></span></li>
<li>type "wq" and hit "Enter". This saves your changes and quits vi.</li>
<li>Reboot.</li>
<li>You're IPv6 should now be disabled!</li>
</ol>
<div style="text-align: center;">
</div>
<div style="text-align: center;">
<div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;">
</div>
<div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px;">
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkOMQE0FuAXYB8LsY3PcbzmmAqBfi2IJsTly6ql43nuRO66pbJNkw7l6Mp3PGhzMwA4WaqTrpg4hJr8uDez27Qioe7Z2AV6GzfhGXc28api2OSGLVj0d7joCwNfebb8kgU_YwcCMZIsic/s1600/Screen%252BShot%252B2011-07-28%252Bat%252B9.54.07%252BAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkOMQE0FuAXYB8LsY3PcbzmmAqBfi2IJsTly6ql43nuRO66pbJNkw7l6Mp3PGhzMwA4WaqTrpg4hJr8uDez27Qioe7Z2AV6GzfhGXc28api2OSGLVj0d7joCwNfebb8kgU_YwcCMZIsic/s640/Screen%252BShot%252B2011-07-28%252Bat%252B9.54.07%252BAM.png" width="640" /></a></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: left;">
At this point, your iTunes to Apple TV should now work as expected. When you try to select Apple TV as a "speaker" for AirPlay you <u>will</u> get prompted for the Apple TV's password...which never happened before the fix.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Enjoy, and again thanks to the dudes from these two posts for showing me the light:</div>
<div style="text-align: left;">
<a href="http://www.soyo123.com/2010/11/itunes-10-wont-connect-to-apple-tv-with.html">http://www.soyo123.com/2010/11/itunes-10-wont-connect-to-apple-tv-with.html</a></div>
<div style="text-align: left;">
<a href="https://discussions.apple.com/thread/3202188?start=0&tstart=0">https://discussions.apple.com/thread/3202188?start=0&tstart=0</a></div>
<div style="text-align: left;">
<br /></div>Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.com1tag:blogger.com,1999:blog-927076583776179704.post-53100516098884939152010-04-19T16:00:00.001-07:002010-04-19T16:00:58.136-07:00Backblaze vs. Mozy – Online Backup for Mac<p>One day while watching my 4 year old and 2 year old “play” with my iMac’s external hard drives (one for <u>all</u> of our photos, videos and music and the other for <a href="http://en.wikipedia.org/wiki/Time_Machine_%28Apple_software%29" target="_blank">Time Machine</a>) the idea struck me that I should maybe start thinking about an online backup solution.</p> <p>From my extensive initial research (i.e. a couple radio commercials and a quick scan of Google’s sponsored links) it seemed that the two big players were <a href="http://carbonite.com/" target="_blank">Carbonite</a> and <a href="http://mozy.com/" target="_blank">Mozy</a>.  Upon further review, it turned out that Carbonite did not support external hard drives.  What?!?!!  Bu-bye Carbonite.  Hello Mozy.</p> <p>After a relatively painless install of the Mozy Mac client, I selected about 2GB worth of files to backup (2GB is Mozy’s free version limit) and let it do its thing.  In less time than I expected, all of the files were backed up to Mozy’s online servers.  That’s when things started to unravel.</p> <p>I went to <a href="http://mozy.com" target="_blank">Mozy.com</a> to see if my files were actually there.  It did show the 2GB of files, but it also said “No backups have been performed”.  What?  I just did a backup…and it says right there that 2GB of my files are there.  I submitted a ticket with Mozy support and they said that it’s a bug and their engineers are working on it.</p> <p>In spite of the issue on Mozy’s website, the 2GB backup went smoothly enough that I anted up the $5/month and set out to backup the whole enchilada which is around 200GB.  I selected the drives and folders to backup and let it do its thing.  For 5 days I watched as Mozy cranked along at about 10GB a day backing stuff up.  Then, once it got to around 50GB or so it just stopped backing up and started hogging a lot of CPU.  I stopped the backup and restarted, restarted my Mac and tried again.  No love…just stuck at 50GB…and eating up a lot of my CPU.</p> <p>Well, at this point I wasn’t very happy and decided to see if there were any other options.  I stumbled across David Peterson’s <a href="http://blog.petersendidit.com/post/mozy-vs-backblaze/" target="_blank">blog post</a> on the subject, and after reading it..wished I would have found it sooner.  Looks like I wasn’t the only one having issues with Mozy.  I took David’s advice and downloaded <a href="http://www.backblaze.com/" target="_blank">Backblaze</a>. </p> <p>Backblaze was easy to install, select what you want to backup, and get going.  My experience was that of Mr. Petersons’….it really wasn’t that much of an experience at all.  I throttled bandwidth usage down during the day, then cranked it at night for the initial upload.  It ended up taking about 2 weeks to backup the full 200GB of content with no issues!</p> <p>Since the initial backup, I configured Backblaze to only use a low percentage of bandwidth and backup continuously (as opposed to scheduled backups)….and I haven’t noticed it since…the way backup should be.</p> <p>Winner: Backblaze</p> Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.com0tag:blogger.com,1999:blog-927076583776179704.post-71766803778938669182010-03-13T13:50:00.001-08:002010-03-13T13:50:52.849-08:00iPhone Stuck On Apple Logo?<p>Had this problem today where I tried to download an app on to my wife’s iPhone.  The app never finished downloading and showed a “Loading” progress bar of about 50%.  After waiting about 10 minutes or so, with the progress bar still at 50%, I decided to try to reboot the phone.  Power off….power on….Apple logo…..stuck there for an hour.  Uh oh.</p> <p>Luckily I stumbled across <a href="http://forums.macrumors.com/showthread.php?t=334220" target="_blank">this forum post</a> which contained the instructions below.</p> <p><em><strong><font color="#800000">WARNING</font></strong></em>: This will allow you to <u>restore</u> the iPhone…which means that hopefully you have a backup, otherwise this will restore the phone to its out-of-the-box condition (i.e. none of your photos, music, contacts or apps will be on the phone)  If you do have a backup, you’ll be able to restore to the backed-up state. As far as I can tell from what I’ve seen out on the internet, once your phone gets the “stuck on Apple logo” issue, restoring the phone is the only solution.  With that said….here’s how to fix it:</p> <blockquote> <ol> <li>Do a hard reset on the phone, hold the sleep/wake button + the home button until it turns off then release before it turns back on. </li> <li>Plug the dock into the compute and have iTunes running. </li> <li>HOLD the home button on the iPhone, while holding it, connect the iPhone onto the dock and CONTINUE to hold the home button until the CONNECT TO ITUNES DISPLAY APPEARS. </li> <li>iTunes will recognize this and ask if you would like to restore it. Click restore. Then choose to restore from BACKUP! This will take a few minutes. It will fix the problem. Your iPhone will be up and running as normal and all your contacts, sms, bookmarks, settings, etc. will be intact. The only thing that will be erased is the music. But you can easily add that all back right. </li> </ol></blockquote> Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.com0tag:blogger.com,1999:blog-927076583776179704.post-69094064339356449112010-03-13T09:18:00.001-08:002010-03-13T09:18:45.625-08:00Adding Custom SOAP Headers in WCF<p>Where I work, all of our internal published web services are proxied using <a href="http://www-01.ibm.com/software/integration/datapower/" target="_blank">IBM’s DataPower SOA Appliances</a>.  One of the requirements for services that want to leverage the infrastructure is that all requests and responses to the service must contain a custom header which contains parameters like “MessageID” for correlation, “SiteID” for location information, etc.  For SOAP based services, this information must be transmitted in the SOAP header.  For the purposes of this article, let’s say we need to include an object like the following into the SOAP header of every service operation.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:eb0387d9-a43e-4968-9d0a-14e35bfa7ec0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">[DataContract]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> CustomHeader
{
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Name </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">customHeader</span><span style="color: #800000;">"</span><span style="color: #000000;">;
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Namespace </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">http://mycompany.com</span><span style="color: #800000;">"</span><span style="color: #000000;">;
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">const</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> OperationContextKey </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">CustomSoapHeader</span><span style="color: #800000;">"</span><span style="color: #000000;">;
[DataMember]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> MessageID { </span><span style="color: #0000FF;">get</span><span style="color: #000000;">; </span><span style="color: #0000FF;">set</span><span style="color: #000000;">; }
[DataMember]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> SiteID { </span><span style="color: #0000FF;">get</span><span style="color: #000000;">; </span><span style="color: #0000FF;">set</span><span style="color: #000000;">; }
}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>Back in the ASMX days adding headers like this to a service method was as easy as adding a <a href="http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapheader.aspx" target="_blank">SoapHeader</a> attribute to your <a href="http://msdn.microsoft.com/en-us/library/byxd99hx%28VS.71%29.aspx#vbtskusingwebmethodattributetransactionoption" target="_blank">WebMethod</a>. Simple.  In the WCF world, not so simple.</p>
<p>There are 3 issues to be addressed:</p>
<ol>
<li>We need some way to inject the custom header into the WSDL so the service clients are aware of it and can generate client proxies accordingly.  </li>
<li>We need some method to read and process the custom header from the request.</li>
<li>We need some way to roundtrip the header back to the client.</li>
</ol>
<p>In our case, we’d like to specify whether the custom header should be included at the service contract level, so an <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.icontractbehavior.aspx" target="_blank">IContractBehavior</a> seems like a good place to start.  We also know that we’ll be processing the request and reply messages, so we’re going to need an <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.aspx" target="_blank">IDispatchMessageInspector</a> too.  </p>
<p>Let’s start with the message inspector.  The responsibility of this class is to extract the header from incoming messages, store it in the OperationContext in case the service needs to use it (i.e. for logging purposes), and roundtrip it into the reply message.</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:96c74336-babf-4080-96be-058069b3fd87" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> Retrieves and stores the custom header from requests and roundtrips it into responses.
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;">
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> CustomHeaderMessageInspector : IDispatchMessageInspector
{
</span><span style="color: #0000FF;">object</span><span style="color: #000000;"> IDispatchMessageInspector.AfterReceiveRequest(</span><span style="color: #0000FF;">ref</span><span style="color: #000000;"> Message request, IClientChannel channel, InstanceContext instanceContext)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Grab the header from the request
</span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO: Handle missing or invalid header</span><span style="color: #008000;">
</span><span style="color: #000000;"> CustomHeader header </span><span style="color: #000000;">=</span><span style="color: #000000;"> header </span><span style="color: #000000;">=</span><span style="color: #000000;"> request.Headers.GetHeader</span><span style="color: #000000;"><</span><span style="color: #000000;">CustomHeader</span><span style="color: #000000;">></span><span style="color: #000000;">(CustomHeader.Name, CustomHeader.Namespace);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Stash the header in the OperationContext so the service code can reference it if necessary</span><span style="color: #008000;">
</span><span style="color: #000000;"> OperationContext.Current.IncomingMessageProperties[CustomHeader.OperationContextKey] </span><span style="color: #000000;">=</span><span style="color: #000000;"> header;
</span><span style="color: #008000;">//</span><span style="color: #008000;"> The object returned from this method is passed as the "correlationState" parameter to the BeforeSendReply
</span><span style="color: #008000;">//</span><span style="color: #008000;"> method. We can use this to "echo" back the header to the caller.</span><span style="color: #008000;">
</span><span style="color: #000000;"> </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> header;
}
</span><span style="color: #0000FF;">void</span><span style="color: #000000;"> IDispatchMessageInspector.BeforeSendReply(</span><span style="color: #0000FF;">ref</span><span style="color: #000000;"> Message reply, </span><span style="color: #0000FF;">object</span><span style="color: #000000;"> correlationState)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> correlationState should be the CustomHeader (passed to this method from AfterReceiveRequest)
</span><span style="color: #008000;">//</span><span style="color: #008000;"> If an exception occured before or during the header processing, this may be null.</span><span style="color: #008000;">
</span><span style="color: #000000;"> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (correlationState </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Get the custom header object passed in on the request</span><span style="color: #008000;">
</span><span style="color: #000000;"> var headerObject </span><span style="color: #000000;">=</span><span style="color: #000000;"> (CustomHeader)correlationState;
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Build the MessageHeader object from our custom header</span><span style="color: #008000;">
</span><span style="color: #000000;"> var headerMessage </span><span style="color: #000000;">=</span><span style="color: #000000;"> MessageHeader.CreateHeader(CustomHeader.Name, CustomHeader.Namespace, headerObject);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Inject our custom header into the reply.</span><span style="color: #008000;">
</span><span style="color: #000000;"> reply.Headers.Add(headerMessage);
}
}
}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p></p>
<p>Now that we have the inspector, we’ll need to create an attribute and implement <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.icontractbehavior.aspx" target="_blank">IContractBehavior</a> so we can attach this inspector to the desired service contracts.</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9ade109e-83b0-49ea-b81a-e30a21720d56" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> Apply this attribute to service contracts to implement CustomHeader processing.
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;">
</span><span style="color: #000000;">[AttributeUsage(AttributeTargets.Interface)]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> CustomMessageHeaderAttribute : Attribute, IContractBehavior, IWsdlExportExtension
{
</span><span style="color: #0000FF;">void</span><span style="color: #000000;"> IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Attach the message inspector to the endpoint.</span><span style="color: #008000;">
</span><span style="color: #000000;"> var inspector </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> CustomHeaderMessageInspector();
dispatchRuntime.MessageInspectors.Add(inspector);
}
</span><span style="color: #0000FF;">void</span><span style="color: #000000;"> IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO: Inject the custom header into the WSDL</span><span style="color: #008000;">
</span><span style="color: #000000;"> }
</span><span style="color: #008000;">//</span><span style="color: #008000;"> All other interface methods are not used and have been omitted for brevity...</span><span style="color: #008000;">
</span><span style="color: #000000;">}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>At this point, the custom header is usable, but with one problem.  It’s not defined in the WSDL, so the service clients might not “know” about it.  To add the header to the wizard, we just need to implement the ExportContract method of the <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.iwsdlexportextension.aspx" target="_blank">IWsdlExportExtension</a> interface that we left as a “TODO” in the code above.</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5568f70c-b101-40f6-8c39-1f2fd3044e5f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">void</span><span style="color: #000000;"> IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Build the custom header description</span><span style="color: #008000;">
</span><span style="color: #000000;"> var headerDescription </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> MessageHeaderDescription(CustomHeader.Name, CustomHeader.Namespace);
headerDescription.Type </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">typeof</span><span style="color: #000000;">(CustomHeader);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Loop through all the operations defined for the contract and add custom SOAP header to the WSDL</span><span style="color: #008000;">
</span><span style="color: #000000;"> </span><span style="color: #0000FF;">foreach</span><span style="color: #000000;"> (OperationDescription op </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> context.Contract.Operations)
{
</span><span style="color: #0000FF;">foreach</span><span style="color: #000000;"> (MessageDescription messageDescription </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> op.Messages)
{
messageDescription.Headers.Add(headerDescription);
}
}
}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>Now we have a fully defined and working header.  To tell a service contract to implement the custom header, we just add our custom attribute to the contract definition.</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:dc56e7f9-f885-477e-82be-2208989eaf0e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">[ServiceContract]
[CustomMessageHeader]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">interface</span><span style="color: #000000;"> IMyServiceContract
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Service definition here....</span><span style="color: #008000;">
</span><span style="color: #000000;">}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>Of course this was a very basic implementation for a specific need, but this approach could be extended to create a more “generic attribute” that you could specify header type as a parameter or allow for updating the header values to return in the reply (similar to how the “old school” <a href="http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapheader.aspx" target="_blank">SoapHeader</a> attribute worked).</p> Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.com3tag:blogger.com,1999:blog-927076583776179704.post-24936128759319265422010-03-01T14:06:00.001-08:002010-03-13T08:25:29.124-08:00Adding WSDL Documentation to your WCF Services<p>Back in the good ol’ days of ASMX web service development, adding documentation to the WSDL of your service was as simple as providing the desired info in the <em>Description</em> property of the <em>WebMethod</em> attribute:</p> <p></p> <p></p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:31eaa67f-ba4d-475f-ac10-b2fe619daf8b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">[WebMethod(Description</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">This method always returns 'Hello World!'</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> HelloWorld()
{
</span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Hello World!</span><span style="color: #800000;">"</span><span style="color: #000000;">;
}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>This injected something like the following into your WSDL which allows web service clients and tools to give the consumer a little more information about a service or method.</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5c0bbcd2-ce5b-4d7a-acdf-d50c43a97eb9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;"><</span><span style="color: #800000;">wsdl:operation </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">="Hello World"</span><span style="color: #0000FF;">></span><span style="color: #000000;">
</span><span style="color: #0000FF;"><</span><span style="color: #800000;">wsdl:documentation</span><span style="color: #0000FF;">></span><span style="color: #000000;">This method always returns 'Hello World'!</span><span style="color: #0000FF;"></</span><span style="color: #800000;">wsdl:documentation</span><span style="color: #0000FF;">></span><span style="color: #000000;">
</span><span style="color: #0000FF;"><</span><span style="color: #800000;">wsdl:input </span><span style="color: #FF0000;">... </span><span style="color: #0000FF;">/></span><span style="color: #000000;">
</span><span style="color: #0000FF;"><</span><span style="color: #800000;">wsdl:output </span><span style="color: #FF0000;">... </span><span style="color: #0000FF;">/></span><span style="color: #000000;">
</span><span style="color: #0000FF;"></</span><span style="color: #800000;">wsdl:operation</span><span style="color: #0000FF;">></span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>Now fast forward to the new services world of WCF…and its mantra of “I’m uber-powerful, but everything that used to be easy is no longer easy”. There is no out-of-the-box way to inject descriptions into your WSDL in WCF.  Can’t believe it? Neither could I…but there is hope.  </p>
<p>WCF was built to allow extensibility to almost everything, including WSDL generation. For this particular problem, we need to look at contract behaviors (<a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.icontractbehavior.aspx" target="_blank">IContractBehavior</a>), operation behaviors (<a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.ioperationbehavior.aspx" target="_blank">IOperationBehavior</a>), and the <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.iwsdlexportextension.aspx" target="_blank">IWsdlExportExtension</a> interface.  Armed with these we can develop a behavior which allows you to specify WSDL descriptions for a service or operation in much the same way as the old ASMX days.  Below is the code for a WsdlDocumentation attribute which does just this:</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:547cba49-7f74-4872-9d79-a0554b3d00f5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> Attribute which injects wsdl:documentation elements into the WSDL.
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><remarks></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> This attribute can be applied to the service contract and it's methods.
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></remarks></span><span style="color: #808080;">
</span><span style="color: #000000;">[AttributeUsage(AttributeTargets.Interface </span><span style="color: #000000;">|</span><span style="color: #000000;"> AttributeTargets.Method)]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> WsdlDocumentationAttribute : Attribute, IContractBehavior, IOperationBehavior, IWsdlExportExtension
{
</span><span style="color: #0000FF;">private</span><span style="color: #000000;"> ContractDescription _contractDescription;
</span><span style="color: #0000FF;">private</span><span style="color: #000000;"> OperationDescription _operationDescription;
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> Initializes a new instance of WsdlDocumentationAttribute.
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><param name="text"></span><span style="color: #008000;">Text to inject into the WSDL.</span><span style="color: #808080;"></param></span><span style="color: #808080;">
</span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> WsdlDocumentationAttribute(</span><span style="color: #0000FF;">string</span><span style="color: #000000;"> text)
{
</span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Text </span><span style="color: #000000;">=</span><span style="color: #000000;"> text;
}
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"><summary></span><span style="color: #008000;">
</span><span style="color: #808080;">///</span><span style="color: #008000;"> Text to inject into the WSDL for the target element.
</span><span style="color: #808080;">///</span><span style="color: #008000;"> </span><span style="color: #808080;"></summary></span><span style="color: #808080;">
</span><span style="color: #000000;"> </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Text { </span><span style="color: #0000FF;">get</span><span style="color: #000000;">; </span><span style="color: #0000FF;">set</span><span style="color: #000000;">; }
</span><span style="color: #0000FF;">void</span><span style="color: #000000;"> IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> This is either for a service contract or operation, so set documentation accordingly.</span><span style="color: #008000;">
</span><span style="color: #000000;"> </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (_contractDescription </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Attribute was applied to a contract.</span><span style="color: #008000;">
</span><span style="color: #000000;"> context.WsdlPortType.Documentation </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Text;
}
</span><span style="color: #0000FF;">else</span><span style="color: #000000;">
{
</span><span style="color: #008000;">//</span><span style="color: #008000;"> Attribute was applied to an operation.</span><span style="color: #008000;">
</span><span style="color: #000000;"> Operation operation </span><span style="color: #000000;">=</span><span style="color: #000000;"> context.GetOperation(_operationDescription);
</span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (operation </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
{
operation.Documentation </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Text;
}
}
}
</span><span style="color: #0000FF;">void</span><span style="color: #000000;"> IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
_contractDescription </span><span style="color: #000000;">=</span><span style="color: #000000;"> contractDescription;
}
</span><span style="color: #0000FF;">void</span><span style="color: #000000;"> IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
_operationDescription </span><span style="color: #000000;">=</span><span style="color: #000000;"> operationDescription;
}
</span><span style="color: #008000;">//</span><span style="color: #008000;"> **** All other interface members are not used and have been removed for brevity</span><span style="color: #008000;">
</span><span style="color: #000000;">}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>To use this new attribute, we just apply it to a service contract and/or method…</p>
<div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f2400240-eba6-4d6b-acd5-424a934835ca" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#F4F4F4;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">[ServiceContract(Name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">MyService</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
[WsdlDocumentation(</span><span style="color: #800000;">"</span><span style="color: #800000;">Description of MyService</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">interface</span><span style="color: #000000;"> IMyService
{
[OperationContract]
[WsdlDocumentation(</span><span style="color: #800000;">"</span><span style="color: #800000;">This method always returns 'Hello World!'</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> HelloWorld()
{
</span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Hello World!</span><span style="color: #800000;">"</span><span style="color: #000000;">;
}
}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>
<p>Voila, the descriptions show up in the WSDL!</p>Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.com3tag:blogger.com,1999:blog-927076583776179704.post-62932164547302862972010-03-01T10:54:00.001-08:002010-03-01T10:58:53.271-08:00Quicken Essentials for Mac – WTF Intuit?!?!!<p><img title="QuickenEssentialsForMac" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 10px 10px 0px; border-right-width: 0px" height="115" alt="QuickenEssentialsForMac" src="http://lh4.ggpht.com/_Q82bDbX76Qc/S4wObMvTAhI/AAAAAAAAAA8/xF_RqM63c1o/QuickenEssentialsForMac%5B9%5D.jpg?imgmax=800" width="115" align="left" border="0" /> I downloaded (and paid the $69.99) for <a href="http://quicken.intuit.com/personal-finance-software/mac-personal-financial-software.jsp" target="_blank">Quicken Essentials for Mac</a> yesterday.  My thinking was<em>..”My God, it’s taken them forever to come out with this thing..it must be freakin’ awesome”.</em></p> <p>Now I realized that they had not yet integrated Bill Pay into the product….I guess in order to complete the rest of the alleged awesomeness in time for the February 2010 ship date, they deemed it a non-essential feature.  OK….fair enough, I can pay all my bills online at the payees’ sites anyway…so I can live without this feature.</p> <p>So, after a painless checkout & download process from the Intuit online store, I installed it. I didn’t get past the 2nd step on the “Setup your accounts” wizard before finding out that they don’t support Wells Fargo for transaction downloads.  That’s not a typo…<a href="https://www.wellsfargo.com/" target="_blank">Wells Fargo</a>, the 3rd largest bank in the United States is not supported.  Are you kidding me?  That’s like putting out TurboTax with 1040EZ support missing.  What’s even more perplexing is that they do support Wells Fargo on their (free) Quicken Online product.</p> <p>So after less than 5 minutes of using the product….I’m uninstalling it and trying to get my money back.</p> <p>I would expect more from the “leader” in personal finance software products.</p> <p>WTF Intuit?!?!!</p> Waynehttp://www.blogger.com/profile/04127530222401852336noreply@blogger.com1