Archive for the ‘WCF’ Category

Cross-Domain Calls for a WCF Service

As I develop more services for mobile devices (and mobile web in particular), cross-domain calls are becoming more frequent. Essentially, a cross-domain call happens when a web page uses JavaScript to access resources at a different URL. This can be as complex as hosting services completely separate from the app in another web site, or in another subdomain or on another port, and also can happen simply because the web page is calling a service over SSL.

The problem occurs because the browser only trusts calls from the exact same domain, unless the server says that it trusts your domain (or all domains). This is by design.

So the resolution is to have the server tell the clients what domains it trusts for cross-site calls. Seems simple, but of course there is more to it than that.

When the browser detects a cross-domain call, it behaves differently if your service is configured correctly. If you were expecting your JavaScript code to perform a POST to a REST URL, that is no longer what happens, at least initially. Instead of performing the POST, the browser actually sends an OPTIONS verb call to your REST URL. This is called a preflight request. Your service needs to respond to the preflight request containing the OPTIONS verb and let the browser know which parameters are acceptable on a cross-site call. If everything matches up and your client is in an allowed domain, then the browser performs the original POST that you expected and everything continues on normally.

If your service is not configured correctly, the browser doesn’t cooperate and you don’t see anything at all. Again, this is by design.

Configuring The Service

From an HTTP point of view, what we need to do in code is add the following name/value headers to our HTTP responses:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Max-Age

The first, Access-Control-Allow-Origin, needs to be added to any request so the browser knows to use the OPTIONS verb for cross-site calls, which just error out otherwise with an XmlHttpReqeust Error 101 in JavaScript. The other three need to be added in response to the OPTIONS verb request. 

The Access-Control-Allow-Origin header can be added with one or more values. If you expect any client anywhere to call your services, like Google Maps does, you want to add * for the value, allowing all callers. Otherwise, the most secure way to use Access-Control-Allow-Origin is to set it for the specific domains you want to accept. Say your services are at https://service.yoursitehere.com, and your client site is http://www.yousitehere.com, you want to set the value to http://www.yoursitehere.com.

The code adds the Access-Control-Allow-Methods header to tell the browser which HTTP verbs your calls will accept as cross-domain.

By adding the Access-Control-Allow-Headers header, you control exactly which HTTP headers are allowed in the actual request which follows the preflight request.

The Access-Control-Max-Age header tells the browser how long to cache the preflight call result before doing it again during this browser session. I set this long to avoid multiple preflight requests.

In my case, I’m using configuration-less WCF services as described here. In my experience much of the pain with WCF in the past has been with the complex configurations, and this option circumvents that problem substantially.

The C# Code

So this is how it’s done programmatically, in Global.asax in my case:

 protected void Application_BeginRequest(object sender, EventArgs e)
 {
  HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin" , ”http://www.yoursitehere.com”);

 if (HttpContext.Current.Request.HttpMethod == "OPTIONS" )
 {
 //These headers are handling the "pre-flight" OPTIONS call sent by the browser
 HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods" , "GET, POST" );
 HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers" , "Content-Type, Accept" );
 
 
 HttpContext.Current.Response.AddHeader("Access-Control-Max-Age" "1728000" );
 HttpContext.Current.Response.End();
 }
 }
 

I put it Global.asax in order to avoid having each request handle multiple verbs and calling the handler in each service call. The downside to this is that any non-service request also gets the additional header and processing as well. For me, there are only service requests in this app so this is not a big deal.

The Client

I’ve regularly used jQuery to access services from client HTML code. It’s not complicated, the important parts are formatting the call to send JSON properly in response to our preflight request, which includes the dataType, contentType and data parameters to the $.ajax call.

 $.ajax({
 url: "https://www.yoursitehere.com/person/add",
 type: "POST" ,
 dataType: "json" ,
 contentType: "application/json" ,
 data: JSON.stringify(personObject),
 success: function (data) {
 //Process success here 
 },
 error: function (jqXHR, textStatus, errorThrown) {
 //process errors here 
 }
 });
 

Tools

If you are debugging REST services, you need some good tools. I have used Fiddler, the Chrome Developer Tools (the Network panel in particular) and the Chrome app Advanced REST Client Application successfully.

References

This post is the basis of the fix I’m describing

W3C description of how the HTTP process works

FireFox and CORS, also a lot of good info on HTTP headers

A 64-bit 32-bit Dilemma

I recently ran into an interesting situation that I was able to solve through code. The project was to create a document migration tool, something I’ve done many times, so it seemed pretty straightforward. I was moving documents and metadata from a 3rd party content management system to SharePoint 2007. I was developing on a 32-bit OS on a machine provided by my client. The source system had an API, albeit 32-bit COM. There was some example code in their SDK for VB6, so at least there was something. It was easy enough to create a .Net wrapper to that COM DLL and figure out the API. The SharePoint code was not too difficult either, something I’ve done before. In this case I had to use the API, not the web services because I wanted to keep the original file created/modified dates from the source system. You can’t set those using the web services. Therefore, the tool is forced to run on the SharePoint server (this is important factor for the upcoming dilemma). Luckily the source system was accessible remotely.

Works on My Machine

Of course, in my dev environment everything works great. So I copy my app to a SharePoint server to test in an environment more like production. It crashes immediately with a COM exception:

 Retrieving the COM class factory for component with CLSID {FDD9199A-1BB4-4433-B9E1-D550D3118676} failed due to the following error: 80040154.

What?? After a little research I determine the problem: the SharePoint server is 64-bit. My .Net code was compiled for any CPU, so it ran as 64-bit on the server, while it was 32-bit on my dev box. When compiled for 64-bit, it can’t access the 32-bit COM DLL (there might be a solution for this, I didn’t find it). I went back, and forced the code to compile for 32-bit. The app soared right past the error for the COM DLL, but came to a screeching halt when trying to access the SharePoint API. If SharePoint is installed on a 64-bit server, the code has to run compiled for 64-bit in order to access the API. Now you see the dilemma. I have to use a 32-bit only COM DLL and a 64-bit app for accessing SharePoint. I can’t skirt the issue using the SharePoint web services because I need functionality only available in the API.

My Solution

I decided on using two applications, one compiled for 32-bit which accesses the source system and fetches the data, and a second one compiled for 64-bit to access the SharePoint API. Five years ago I probably would have done the same thing, and write the data to an XML file from the first app, and then launch the second app and read the data from the file. There were hundreds of thousands of documents to migrate, all that disk access would be a performance killer. But now that I have WCF, I could do this much more elegantly.

32-64solution[1]

The 32-bit app contained the UI, and was able to use the 32-bit COM DLL to fetch documents and metadata. Once it had a logical set of data in memory, it used WCF with named pipes as the transport protocol to pass the data structure to the second app. The second app was 64-bit, and launched by the first app as a process using the System.Diagnostics namespace. It communicated just fine with the SharePoint API. The second app had no GUI, but I kept the console window for writing messages and to provide a way to manually exit the app in case things went awry. The first app kept a handle on the process that launched the second app, so that when a user closed the first app, it could close the second app for  the user.

WCF was a good fit for this dilemma. The only issue I encountered was managing the message size, because WCF expects you to configure a maximum size for that. Of course configuring WCF is not that easy, but you only have to do it once. I was pleased that I could make a mex endpoint in the 64-bit app, and then use Visual Studio to make a Service reference to it from the 32-bit app, and the configuration comes out for named pipes even though the mex endpoint was http. Another feature I didn’t know but managed to discover. In the end, the process is seamless to the user, and does what I need without much disk access to slow it down.

Posted on:
Posted in .Net 3.5, SharePoint, WCF | Comments Off on A 64-bit 32-bit Dilemma

eBooks on CodePlex

Wriju has a gread roundup of eBooks/guidance available on CodePlex.

Getting Started with WCF and REST

Now that WCF has support for REST in .Net 3.5, it’s time to get learning….


WCF REST Starter Kit


A Guide to Designing and Building RESTful Web Services with WCF 3.5

A bunch of screencasts by Aaron Skonnard

WCF and REST from the PDC

Dan RigsbyREST support in WCF

Posted on:
Posted in .Net 3.5, WCF | Comments Off on Getting Started with WCF and REST

Speaking at West Michigan Dot Net User Group – WCF

I will be speaking on July 17th on Windows Communication Foundation. See the West Michigan .NET Users Group site for details.

Posted on:
Posted in .Net 3.0, Speaking, WCF | Comments Off on Speaking at West Michigan Dot Net User Group – WCF

Even More WCF Links

Articles by Juval Lowy


Aaron Skonnard’s Wiki


WCF Developer Center on MSDN

Posted on:
Posted in .Net 3.0, WCF | Comments Off on Even More WCF Links

Speaking at West Michigan Day of .Net

I will be speaking at the West Michigan Day of .Net on May 19th in Grand Rapids, MI at Davenport University.

My talk is Introduction to WCF. WCF is certainly the understated pillar of .Net 3.0. There is a ton of great content all day long, and best of all it’s FREE! This is a great opportunity, don’t miss out.

WM Day of .Net May 19, 2007 - I'll be there!

Posted on:
Posted in Speaking, WCF | Comments Off on Speaking at West Michigan Day of .Net

More Good WCF Links

The Server Side .Net has a good WCF link aggregation.

Posted on:
Posted in WCF | Comments Off on More Good WCF Links

WCF Presentation

I am giving a presentation March 15th at the Greater Lansing User Group .net about Windows Communication Foundation.

If you have worked with web services at all you will really appreciate WCF. Come by and check it out.

Posted on:
Posted in Speaking, WCF | Comments Off on WCF Presentation

WCF Link List

Architecture Overview


MSDN Forum


WCF Tools


Contract Versioning


Terminology


Integrating WWF and WCF


WCF Developer Home


WCF Team Blog

Posted on:
Posted in .Net 3.0, WCF | Comments Off on WCF Link List