Search code examples
c#ado.netjsonpwcf-data-services

How can I make a WCF Data Service Query Interceptor return results in JSON?


I currently have a WCF Data service live at www.mywebsite.com. It is a basic service that looks like this:

namespace MyWeb
{
    [JSONPSupportBehavior]
    public class MyDataService : DataService<MyEntities>
    {
        public static void InitializeService(IDataServiceConfiguration config)
        {
            config.UseVerboseErrors = true;
            config.SetEntitySetAccessRule("Entities", EntitySetRights.AllRead);
            ServiceOperationRights.All);
        }
    }
}

Currently, we have live clients out in the wild that make requests by posting ajax calls such as these:

$.ajax({
        url: serverAddress + "MyDataService.svc/Entities?$top=20&$filter=IsConfirmed%20eq%20null&$format=json&$callback=?",
        headers: {
        version: "1.0",
        platform: "a platform"
        },
        timeout: 12000,
        dataType: 'jsonp',
        cache: false,
        context: document.body
})

This works as expected, returning a javascript object containing the required objects in the Entities table.

However, we would like to add some intelligence on the server side that limits what results can be returned from this query. To that end, I have attempted to implement a Query Interceptor in the aforementioned MyDataService class:

[QueryInterceptor("Entities")]
public IQueryable<Entity> OnQueryFares(IQueryable<Entity> query)
{
    return from e in query 
           where DataCheck(e) 
           select e;
}

With the intended logic being that the service will now only return table entries for which DataCheck(e) evaluates to true. This function appears to work. However, when testing with the client, I get the following error:

Web Console(4448): Uncaught SyntaxError: Unexpected token < at
http://www.mywebsite.com/MyDataService.svc/Entities?$top=20&$filter=IsConfirmed%20eq%20null&$format=json&$callback=jQuery17207441281890496612_1340223164872&_=1340223166622:1

This particular error has led me to guess that, for some reason, the returned data from the Query Inspector that I implemented is coming in XML, rather than coming in JSON like the query did before I implemented the interceptor.

I haven't been able to find any instructions on this. How can I enforce a JSON response behavior in a Query Interceptor?


Solution

  • See this for usage of query interceptors: http://msdn.microsoft.com/en-us/library/dd744842.aspx

    I'm surprised the above even starts the service (I suspect it doesn't and you get back an error payload and thus fail to read it, you can try to confirm with for example Fiddler).

    Query interceptor returns a predicate (Expression) which is added into the query before it executes. So you don't get to return a new query, just modify the existing one.

    In the sample above, just modify it like this:

    [QueryInterceptor("Entities")]
    public Expression<Func<Entity,bool>> OnQueryFares()
    {
        return e => DataCheck(e);
    }