WCF and host header cage match, part 2

As you may recall from my previous post, I recently discovered the situation where WCF gets ticked off (understandably so) when its presented with multiple base-addresses to use from IIS as a result of multiple host headers.  So I thought I had solved my problem, and from my limited testing, it certainly appeared that way.  However, what I failed to properly test was actually *using* both host headers (doh!).  My solution in that post essentially selected one of the host headers and gave that dude the red carpet treatment, essentially ignoring the other.  Bad idea.  The final fix was pretty simple, and can be found in this guy’s article.  The downside to this approach is a hard-coded set of absolute URL’s, but that is livable.  I’m sure we could get fancier with our service host factory and register these endpoint addresses at runtime eliminating this hard-coded aspect, but for me, this is fine for the current project.

FYI, you’ll also see info *in the cloud* regarding the <baseAddressPrefixFilter> configuration section, but from my understanding, that still only assists with selecting *which* base address you want to use, but not if you want *all* the base addresses to work.

Tales from the WCF webHttpBinding crypt…

Hey, works on my machine!  Doh!  This is what I murmured at my machine last Saturday as I *quickly* applied some technical house-cleaning on a small side project.  Not so fast….

OK, so I had this project for a client that *started* out with one or two pages that needed to add items to a shopping cart whose state was on the server in a session.  Simple.  So, a simple ajax approach was in order, using asp.net’s support for generating a simple client-site proxy which sits on top of their [client-side] network stack [which sits on top of xmlhttprequest].  I opted for the ever-simple (and surprisingly unknown)  web method approach, and dropped a few[WebMethod] attributes on each method in the each page’s code-behind.  Voila, insta-ajax.  For a small project such as this, a simple and pragmatic approach. I enable PageMethods on my ScriptManager:

<asp:ScriptManager ID=”ScriptManager1″ runat=”server” EnablePageMethods=”True”></asp:ScriptManager>

I also have my simple business entity that will flow over the wire [ala JSON] as such:

[Serializable()]
[DataContract]
public class ShoppingCartItem
{
  [DataMember]
  public int ID{ get; set; }
  [DataMember]
  public string Name{ get; set; }
  [DataMember]
  public string Description{ get; set; }

}

With the web method and script manager, the lovely javascript proxy does its magic on the client for a nice clean “typed” ajax experience (flows over the wire in JSON format).  On the client I simply have a call to PageMethods.MyServerSideWebMethodNameHere(shoppingCartItemArray,onSuccessJavascriptCallback,onOopsJavascriptCallback), and all is good.

Fast forward a few months and change request #1 comes along, with sufficient argument for *more* pages.  Hm…my solution of page methods looks less sassy as “page method x Number of pages=yuck”.  Eek, starting to get pretty lame, even if the WebMethods are one-liners into a session-backed shopping cart.  This is a really small app, and I’m tossing out low estimates, so in the sake of billable time, i rock out a few more copy/paste WebMethods, but riddled with guilt by now.

A few more months pass before request #2 is in.  OK, enough is enough.  We all know there are zillions of ways to send json or angle bracket requests over the wire via ajax, so I decide its time for a handler, and WCF really is the recommended approach for Microsoft’s network stack ambitions.  In about 10 minutes, I move my [shamefully redundant] code from [one of my] WebMethods, plop it into the WCF service class.  I change my client-side calls from “PageMethods.blah….” to “[wcf server namespace].[wcs service name].blah….” and we’re cooking with gas in no time.  Oh, I also made sure my script manager referenced the wcf service and disabled page methods.  Shame on me, I should have done this for request #1 months back…

I wrap up my changes, and toss the code onto the client’s server and WCF turns into the devil.  First stop, “WCF: This collection already contains an address with scheme http” message.  One quick hit to Bing Google yields a few hits, including this dude’s solution.  Basically, you have to remember, that WCF is steeped in theory of being agnostic of its host, and as such, when a specific host, like IIS in this case, barfs up several base addresses, WCF doesn’t know what the heck to do.  So, that article’s solution is fine, except, I changed it slightly to have a configurable host name that we look up with a very simple linq-to-object query (I’m sure there are other ways to do this too, so don’t just take these solutions at face-value if you have a larger problem to solve):

image

For my machine, that app setting was the name of my machine, while on the production machine it was something like “foo.com”.  Not pulling ordinally as the article suggests shields from changing host header information in the iis metabase and makes the code more durable.  The next issue was with the client failing with an HTTP 404 (I used the ever-awesome FireFox javascript debugger “Firebug” to look further…highly recommend it).  I decided to make sure I could ping the service.  Yep, no problem.  Then i pinged the service with the /js switch, which the client-side code will use to snag a client-side proxy to talk to the service.  DOH!  No dice.  Hey, this worked on my machine!  30 seconds of googling yields one article describing the issue, and it appears related to Sharepoint being installed, yadda yadda.  At this point, I was essentially eating this time from a client-servicing standpoint after no quick resolution via that article, so I simply pulled down the proxy for my 1-method client wrapper, and replaced my service reference in the script manager with the javascript proxy instead:

<asp:ScriptManager ID=”ScriptManager1″ runat=”server”>
   
<scripts>
       
<asp:ScriptReference Path=”~/OrderSamplesProxy.js” />               
   
</scripts>
</asp:ScriptManager>

 

I tweaked the output of that proxy javascript to make sure the path to the .svc file was properly relative.  After that, i was good to go.  Not quite ten minutes, but now I’ve taken a few WCF bruises, but the code is better, and the [ajax] world seems right.  Really at some point, i need to circle back and fully address the /js issue.  I was very hesitant to get too experimental since the client’s test server *is* the production server as well, with Sharepoint happily consuming chugging along on it.

Perhaps you’ve encountered such things or may find this useful.

.Net user group meeting notes

Tonight’s .net user group meeting featured Glen Gordon from Microsoft.  He did a presentation on Mix 09 highlights.  The vast majority of information was about Silverlight 3.  Quick rundown:

 

Silverlight and Blend 3.0 goodness:

  • New functionality to assist with easing effects to provide a more natural look/feel.  You can do this today with Spline KeyFrames in Silverlight 2.0, but this should make such an effect easier to develop.
  • SaveFilterDialog – allows end-users to save files from your SL application.  Your code won’t know where the location because SL lives in the sandbox, and will be provided a [system.io] Stream with which to write (thus still blissfully unaware of the actual physical location).
  • Sketch Flow in Blend is just plain beauty.  In short, this allows designers/developers to “mock” up applications in a way that communicates the non-functional state that an app *should* be in during development.  Under the hood, it can still be real/valid XAML, but the appearance is sort of like hand-writing with regard to look/feel further emphasizing to clients the need to think about the app’s functionality and *not* the font color of a label 😉    .  Additional goodies include end-user feedback ability; users can interactively view the SL mockup using a tool known as the “Sketch Flow Player” and actually submit annotations and feedback).  Sweetness!
  • Behaviors within Blend 3.0 are an extensible way to package up functionality that can be expressed by a designer in Xaml.  Awesome.
  • There is a feature in Blend 3.0 which allows basically mocked up data to show in SL controls within the design experience to see more “life like” representations of the UI.
  • Source Code control in Blend (no brainer here)
  • INTELLISENSE IN BLEND (no more toggling back to VS## for that!)
  • Easier navigation functionality in SL 3.0 for “page to page”.
  • Plenty of other nuggets too (ex: I think much of the controls in the SL toolbox become full citizens of SL 3).

 

Other notables:

  • Cool info on the Mobile Tagging with Microsoft.  There is a Tag Application named “gettag.mobi” which can read bar-code-looking images containing encoded information.  Ballance downloaded the app onto his IPhone, aimed it at the Tag Glen had on the screen, and voila.  Very cool.  More info
  • Here’s my tag:
    Jason's_tag_2009633133
  • New tool from Microsoft allows comparing pages in different browsers, even if you don’t have those different browser versions locally.  It’s called “Super Preview Test”.  More info
  • .Net RIA services is a technology to assist n-tier development, such as propagating server-side validation to the client, and other goodies like integrating authentication and roles with technologies such as silverlight.  This is not a silverlight-specific technology, and in fact is slated to be useful for ajax development, asp.net, and even within services.
  • Azure came up.  Yeah, Microsoft’s answer to cloud computing.  Not much came out of this one.  Hmmmmm
  • Web Platform installer – This tool simplifies packing up application dependencies into a single package.  More Info
  • Windows 7 releases October 27
  • Silverlight 3.0 should release late summer of this year