6

I'm writing what I'm referring to as a POJ (Plain Old JSON) WCF web service - one that takes and emits standard JSON with none of the crap that ASP.NET Ajax likes to add to it.

It seems that there are three steps to accomplish this:

  1. Change "enableWebScript" to "webHttp" in the endpoint's tag
  2. Decorate the method with [WebInvoke(ResponseFormat = WebMessageFormat.Json)]
  3. Add an incantation of [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] to the service contract

This is all working OK for me - I can pass in and am being returned nice plain JSON.

If I remove the WebInvoke attribute, then I get XML returned instead, so it is certainly doing what it is supposed to do. But it strikes me as odd that the option to specify JSON output appears here and not in the configuration file. Say I wanted to expose my method as an XML endpoint too - how would I do this? Currently the only way I can see would be to have a second method that does exactly the same thing but does not have WebMethodFormat.Json specified. Then rinse and repeat for every method in my service? Yuck.

Specifying that the output should be serialized to JSON in the attribute seems to be completely contrary to the philosophy of WCF, where the service is implemented is a transport and encoding agnostic manner, leaving the nasty details of how the data will be moved around to the configuration file.

Is there a better way of doing what I want to do? Or are we stuck with this awkward attribute? Or do I not understand WCF deeply enough?

Mike Chamberlain
  • 39,692
  • 27
  • 110
  • 158

1 Answers1

6

I haven't fully tested this out yet, BUT, I took a look at WebMessageFormat in reflector and where it was used in code.

There is a attribute of the webHttp element called defaultOutgoingResponseFormat that can be set to "Json" or "Xml".

    <behaviors>
      <endpointBehaviors>
        <behavior name="ServicesJSONEndpointBehavior">
          <webHttp defaultOutgoingResponseFormat="Json"/>
        </behavior>
</behaviors>

I've run into the same issue and typically crufted work-arounds after searching online without much info.

I'll give it a shot with multiple configured endpointBehaviors and report back.

UPDATE 6/5/2011

FYI -- I've ditched vanilla WCF with all its hair-pulling scenarios like this that should be simple, in favor of ServiceStack ( http://servicestack.net/ ). If you're looking to put together a standard REST style / document-oriented service over HTTP that out-of-the-box supports JSON / XML / CSV (and in the future protocol buffers) and that allows you to put together clean MVC-style routes with ease, give ServiceStack a hard look. There are a number of things that ServiceStack will handle rather easily and cleanly that always turn out to be a major PITA due to some wonky configuration issue or similar in standard WCF. ServiceStack uses it's own JSON serializer, which as an added bonus, outperforms DataContractJsonSerializer and JSON.NET as Demis mentions below.

Ethan J. Brown
  • 2,308
  • 3
  • 20
  • 27
  • Yup, this is the correct answer. I just verified in a WCF project that I'm working on. Of note, the WebScriptEnablingBehavior class has the same property -- but if you try to tack defaultOutgoingResponseFormat="Xml" on to the enableWebScript element, the service will return a 0 byte response. The default is set to "Json" under the hood somewhere and if you override it in config (which doesn't show up in Intellisense btw), then BUST. – Ethan J. Brown May 26 '10 at 19:35
  • Haha... no problem. WCF is a beast to deal with at times. – Ethan J. Brown May 27 '10 at 13:26
  • hallelujah, this is the first place on the entire internet that gave the alternative to or hardcoded [WebInvoke] that we've all be desperately searching for. – JeremyWeir Jun 03 '11 at 06:17
  • Actually ServiceStack uses it's own ServiceStack.Text JSON serializer which is 3x faster than JSON.NET and 3.6x faster than WCF's DataContractJsonSerializer :) – mythz Jun 06 '11 at 10:09
  • 1
    Demis -- whoops, sorry for the misinfo. Having not looked at that part of your code, I thought you were piggy-backing on JSON.NET. Thanks for the clarification ;0 – Ethan J. Brown Jun 06 '11 at 18:12
  • +1 I didn't initially believe that WCF could be this bad, but I now agree that "ditch WCF with all its hair-pulling scenarios like this that should be simple" is stellar advise – Andomar Jul 25 '11 at 11:35