Yavor Georgiev

Yavor is a Product Manager at goextend.io, a startup that makes in-product extensibility and integrations painless for SaaS developers. Previously at Hulu and Microsoft Azure.

JsonValue guts and glory

29 October 2010

As part of the new set of WCF features at http://wcf.codeplex.com, we’re porting a feature that has existed in Silverlight to the framework. JsonValue is the base abstract class for a set of types that you can use to work with JSON data in a weakly-typed way: JsonPrimitive, JsonArray, and JsonObject. The idea here is similar to how you use XElement to work with XML data: you don’t need to pre-generate a strong type to deserialize into.

Basics

We start with a JSON string, and we parse it easily in one line.

~~~ javascript string customers = @” [ { “ID” : “538a868a-c575-4fc9-9a3e-e1e1e68c70c5”, “Name” : “Yavor”, “DOB” : “1984-01-17”, “OrderAmount” : 1e+4, “Friends” : [ “007cf155-7fb4-4070-9d78-ade638df44c7”, “91c50a40-7ade-4c37-a88f-3b7e066644dc” ] }, { “ID” : “007cf155-7fb4-4070-9d78-ade638df44c7”, “Name” : “Joe”, “DOB” : “1983-02-18”, “OrderAmount” : 50000, “Friends” : [ “91c50a40-7ade-4c37-a88f-3b7e066644dc” ] }, { “ID” : “91c50a40-7ade-4c37-a88f-3b7e066644dc”, “Name” : “Miguel”, “DOB” : “1982-03-19”, “OrderAmount” : 25.3e3, “Friends” : [ “007cf155-7fb4-4070-9d78-ade638df44c7” ] } ]”;

Read More

WCF and JavaScript clients at PDC 2010

26 October 2010

As you may have heard from @gblock WCF is making some significant new investments around HTTP to make sure HTTP-based services are first-class within our stack. As part of this effort, we are renewing our focus on JavaScript clients and jQuery in particular. To learn more, check out Glenn’s PDC10 talk:


Building Web APIs for the Highly Connected Web
Friday 10/26/10, 9:00 AM-10:00 AM (GMT-7)
In person: Kodiak Room / Microsoft Campus Redmond, WA
Live stream: http://player.microsoftpdc.com/Session/17a9e09f-4af1-4ef3-8a5a-ebf1e9bd9c8e 

And to leave you with a little teaser… join us for the talk to find out more!

~~~ csharp WebClient client = new WebClient(); string result = client.DownloadString(“http://search.twitter.com/search.json?q=%23PDC10”);

Read More

Getting the WebOperationContext of a HTTP response in Silverlight

20 October 2010

This came up as a question from a customer today: how do you get details of the HTTP response message that a WCF proxy in Silverlight received? If you thought of  OperationContext and WebOperationContext, you’re on the right track, but you have only half of the story.

In Silverlight, in order to get to these context objects, you have to switch from the event-based async pattern to the more complex Begin/End-based async pattern. Within that pattern, you need to instantiate an OperationContextScope and call the End* method inside that scope, before you can access the context objects themselves. Check out this code snippet:

~~~ csharp public MainPage() { Service1 proxy = new Service1Client() as Service1; proxy.BeginDoWork(new AsyncCallback(Callback), proxy); }

Read More

Speaking at Silverlight Firestarter

13 October 2010

Silverlight Firestarter

Folks, I’ll be speaking on WCF at the Silverlight Firestarter event in December. It’s a one day, global, live streamed and on demand event keynoted by Scott Guthrie. The focus of the event will be to demonstrate that over the last 3 releases Silverlight has grown up to be a very powerful platform for creating engaging experiences on the web/Desktop/phone.

Please click the link to the left to register - it’s free!

Any thoughts on particular web services topics you want me to cover?

Read More

Integrating WCF Routing with RIA Services

23 August 2010

Recently we have had a few customers ask us how WCF RIA Services integrates with the WCF Routing features shipped in .Net 4. I spent some time over the last week building a prototype and learning about the issues you encounter in this scenario.

The sample source code is available here for download. Please keep in mind that in order for the sample works, you need the AdventureWorksLT database deployed to your local SQL Server Express instance… and don’t forget to update the connection string in Web.config!

First, let’s go over the scenarios where a router may be needed:

  • Deployment in a DMZ: In this enterprise deployment scenario, a DMZ is used to separate the untrusted network (usually the Internet) from the application/data tier (where a domain service may live). In this case all the router does is pipe traffic from a public Internet address to a private address in the trusted subnet. There is no smartness required on the part of the router and at this point it is just doing HTTP in/HTTP out piping with very little regard as to the message payload.
  • Content-based routing: In this case the router needs to open up the incoming message and make a decision, based on some information in that message, which endpoint to route the message to. This can be part of the DMZ scenario, but it is not required to enable it.

In the DMZ scenario, the WCF router may be overkill (correct me if I’m wrong). The WCF router is content-based, which means can decode incoming messages and make decisions based on different filters. Unless you are using the content routing features, a simpler router such as IIS’ Application Request Routing will offer better performance and probably be easier to set up. Sandrino Di Mattia has a really good write-up about how to do this.

With this disclaimer out of the way, here is how I got RIA Services working with the WCF content-based router.

First hurdle: binary-encoded POX

In order to offer optimal wire size, RIA Services uses WCF’s binary encoder combined with plain old XML (referred to as POX, in contrast to SOAP). In WCF terms that means the BinaryMessageEncodingBindingElement needs to be configured with MessageVersion.None. However if you try that yourself, you’ll notice that the current implementation of the encoder does not allow that. RIA Services uses a private version of the encoder. So in my sample, I provide my own implementation of the binary encoder, which supports plain XML. Here is the binding that the router needs to understand RIA Services traffic.

Binding binaryPoxBinding = new CustomBinding( 
   new RiaBinaryMessageEncodingBindingElement(), 
   new HttpTransportBindingElement { 
      ManualAddressing = true, 
      MaxReceivedMessageSize = int.MaxValue
   } 
);

Second hurdle: switching to HTTP POST

Domain services use HTTP GET requests by default on their queries. GET offers caching benefits over POST, which are particularly relevant in the case of domain services, where large data sets with static data may be retrieved frequently.

Unfortunately, I could not figure out a way to get the WCF router to successfully route a GET request. Speaking to the team who designed the router, it seems SOAP scenarios took precedence to REST scenarios when they did the work, and since SOAP does everything over POST, the other HTTP verbs all get turned to POSTs. This is unfortunate, however it is easy to tell the domain service to switch to using only POST:

QueryAttribute(HasSideEffects = true)]
public IQueryable GetCustomers()

Final hurdle: URI query strings

Along the same lines as the previous issue, the WCF router will ignore anything that comes in the URI after the endpoint name. This is unfortunate, as domain services expect the name of the query to come in the URI. WCF extensibility comes to the rescue, and by plugging in a simple message inspector, we can correct the address of outgoing messages.

public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) 
{ 
   // This ensures that the router will correctly roundtrip URI query string parameters
   object via; 
   if (request.Properties.TryGetValue("Via", out via)) 
   { 
      string query = (via as Uri).AbsolutePath.Replace(_routerAddress.AbsolutePath, "");
      UriBuilder builder = new UriBuilder(_clientAddress);
      builder.Path += query;
      request.Headers.To = builder.Uri; 
   } 
   return null; 
}

These three fixes are included in the sample project. Once the fixes are applied, we can start taking advantage of the capabilities of the router. By default we plug in a filter that matches all incoming messages.

rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);

However nothing prevents us from using some more sophisticated filters such as the XPathMessageFilter. Using that filter, we could look for specific elements inside the domain service message and route to different services based on that.

Hope this is useful to folks out there!
-Yavor

Read More