Forcing JSON returned??

Topics: Web Api
Jul 20, 2011 at 1:35 PM

Hi there,

 

I have just switched over to JSON.NET and it seems to be working great..  I serialize my C# objects  to a STRING (contains JSON) and return it as part of a WebGet.

 

The problem being is that it can have a return type of = xml where the string is contained within XML if i don't specify the Content-Type on the requesting header.

 

I have tried forcing JSON by setting the Request and Response format on WebGet. It still returns my json wrapped inside a XML if i don't send along the Content-Type in the header.

 

I was wondering what the standard is for FORCING the return of JSON on a method?

 

I found this, but is this acceptable??? i certainly don't want to reinvent the wheel

 

I basically use JSON.NET to serialize my objects to a json string like so

 

           string json = JsonConvert.SerializeObject(
                myobject,
                Formatting.Indented,
                new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });

 

 

return WebOperationContext.Current.CreateTextResponse (json,
   
"application/json; charset=utf-8", Encoding.UTF8);


Any help or guidance gratefully accepted :-)
 
Jul 20, 2011 at 2:04 PM

1) You don't need to do the JSON formatting on the operation. The WCF Web API already as a JSON formatted that will operate on the response pipeline

2) By default, there are two enabled formatters: XML and JSON. If you always want to return JSON, independent of the Accept header, remove the first XML one. One way is using a HttpOperationHandlerFactory

    internal class MyFactory : HttpOperationHandlerFactory
    {
        protected override Collection<HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
        {
            var coll = base.OnCreateRequestHandlers(endpoint, operation);
            if (operation ...)
            {
                Formatters.Remove(Formatters.XmlFormatter);
            }
            return coll;
        }
    }
 

Jul 20, 2011 at 4:08 PM

Thanks!   But where do i need to pass in my new "MyFactory" ????

 

Here is my mapping i have currently i presume i need to pass it in somehwere? 

 

 RouteTable.Routes.MapServiceRoute<ContactsResource>(
                "contacts"HttpHostConfiguration.Create().SetResourceFactory(new ContactsResourceFactory()));
Coordinator
Jul 20, 2011 at 4:15 PM

You actually don't need to create a custom factory. If you look on the configuration class (cast it to HttpHostConfiguration) it exposes a factory. You can directly manipulate the formatter collection off of that factory.

Jul 20, 2011 at 4:32 PM

ahh ok Glenn, thanks!   But i would need to create a new HTTPHostConfiguration for each resource factory (i.e. contacts, users, etc etc) and then cast each one to HTTPHostConfig and make changes to the Formatters and then in turn add to the mapserviceroute?

 

Coordinator
Jul 20, 2011 at 6:02 PM

No, normally you create the host config once and reuse it across all your routes.

What you would probably do here is create your own derived HttpHostConfiguration class. In the ctor you would then access the factory hanging off it to set the formatter.

Glenn

Jul 21, 2011 at 3:07 AM

Thanks a lot, got everything i need now, gonna have a play!