如何使 WCF 数据服务查询拦截器以 JSON 格式返回结果?

Posted

技术标签:

【中文标题】如何使 WCF 数据服务查询拦截器以 JSON 格式返回结果?【英文标题】:How can I make a WCF Data Service Query Interceptor return results in JSON? 【发布时间】:2012-06-23 01:30:10 【问题描述】:

我目前在www.mywebsite.com 有一个 WCF 数据服务。这是一个看起来像这样的基本服务:

namespace MyWeb

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

目前,我们有一些现场客户通过发布 ajax 调用来发出请求,例如:

$.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
)

这按预期工作,返回一个包含实体表中所需对象的 javascript 对象。

但是,我们希望在服务器端添加一些智能,以限制可以从此查询返回的结果。为此,我尝试在上述MyDataService 类中实现查询拦截器:

[QueryInterceptor("Entities")]
public IQueryable<Entity> OnQueryFares(IQueryable<Entity> query)

    return from e in query 
           where DataCheck(e) 
           select e;

按照预期的逻辑,服务现在将只返回 DataCheck(e) 评估为 true 的表条目。此功能似乎可以工作。但是,在使用客户端进行测试时,我收到以下错误:

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

这个特殊的错误让我猜测,出于某种原因,我实现的查询检查器返回的数据是以 XML 形式出现的,而不是像我实现拦截器之前的查询那样以 JSON 形式出现。

我找不到任何关于此的说明。如何在查询拦截器中强制执行 JSON 响应行为?

【问题讨论】:

你用 Fiddler 跟踪请求和响应了吗? @Pratik Fiddler 似乎假设有问题的客户端是台式电脑,但事实并非如此。 【参考方案1】:

查询拦截器的用法见这里:http://msdn.microsoft.com/en-us/library/dd744842.aspx

我很惊讶上面甚至启动了服务(我怀疑它没有启动,并且您返回错误有效负载,因此无法读取它,您可以尝试使用 Fiddler 进行确认)。

查询拦截器返回一个谓词(表达式),该谓词在执行之前添加到查询中。因此,您无需返回新查询,只需修改现有查询即可。

在上面的示例中,只需像这样修改它:

[QueryInterceptor("Entities")]
public Expression<Func<Entity,bool>> OnQueryFares()

    return e => DataCheck(e);

【讨论】:

非常感谢。这是帮助我的一点:“查询拦截器返回一个谓词(表达式),它在执行之前添加到查询中。所以你不会返回一个新的查询,只需修改现有的查询。”我所寻找的任何地方都没有明确这一点,所以当我尝试使用表达式之前,我以错误的方式进行操作。再次感谢!【参考方案2】:

这是一个扩展版本

[QueryInterceptor("Entities")]
public Expression<Func<Entity,bool>> OnQueryFares()

    // Assuming e has two properties Name and Age. 
    return e => e.Name=="John" && e.Age=23 ;

【讨论】:

以上是关于如何使 WCF 数据服务查询拦截器以 JSON 格式返回结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何以 JSON 形式返回 WCF 服务 POST 响应

WCF 休息服务.. 将数据表转换为 XML

如何在 .NET WCF 中保护 HTTP JSON Web 服务

使 ASP.NET WCF 将字典转换为 JSON,省略“键”和“值”标签

移动应用程序和 Web 服务数据传输(WCF 和 JSON)

如何将 x-www-form-urlencoded post Message 转换为 JSON post Message?