【问题标题】:WCF Data Service - Proxy mid-tier serviceWCF 数据服务 - 代理中间层服务
【发布时间】:2010-03-24 14:47:42
【问题描述】:

我们正在进行的项目是一个经典的 3 层架构。第 1 层是数据库服务器,第 2 层是应用程序服务,第 3 层是表示层(网站)。

在应用程序服务层中,我有一个项目,其中包括一个实体框架模型和一个基于 WCF 数据服务的服务,该服务公开模型中的实体,例如:

public class DataService : DataService< PortalEntities >

这是一个成熟的 OData 服务,可以通过 URI 进行查询,例如:/dataservice.svc/mytable?$filter=contains(fieldname,’string’)。这对于使用 jQuery 开发任何东西的人来说非常棒,因为他们所要做的就是定义查询。问题是这个服务是中间层,所以外面的世界是看不到的。

我正在尝试的解决方案是在网站上公开另一个 WCF 数据服务,该服务公开由服务引用创建的实体。如果我向中间层服务添加服务引用,它会给我一个数据上下文,该数据上下文正在新的 WCF 数据服务中使用:

public class DataService : DataService< PortalEntities >

我必须覆盖 CreateDataSource:

protected override PortalEntities CreateDataSource()
{
    return new PortalEntities(GetMianModelServiceUri());
} 

新服务确实起到了代理的作用,并且确实返回了暴露的实体(查询.../Services/OData/DataService.svc/tbl_Country 工作正常)。

但是当查询被传递给服务时,例如:.../OData/DataService.svc/tbl_Country?$select=Name,它会抛出一个未实现的异常。

关于如何扩展网站服务以使其支持与中间层服务相同的查询有什么想法吗?

【问题讨论】:

    标签: c# wcf service odata


    【解决方案1】:

    如果您不需要更改数据服务器的形状或功能,您应该能够简单地转发请求和响应,就像透明的 HTTP 代理一样。您可能需要做的唯一区别是调整服务 URL。由于代理服务将具有与真实服务不同的基本 URI,因此有效负载将包含真实服务 URI(在链接等中),这将不起作用。您可以通过为您的真实服务使用自定义主机并对其 URI 撒谎来解决此问题。这是通过 IDataServiceHost2 接口完成的,您从 AbsoluteRquestUri 和 AbsoluteServiceUri 属性返回“新”URI。接口实现的一个很好的示例(尽管用于不同的目的)在这里:http://blogs.msdn.com/b/tom_laird-mcconnell/archive/2010/01/18/using-ado-net-wcf-data-services-for-streaming-infinite-event-result-sets.aspx

    如果你需要改变形状或功能,那么你真的需要真正的分层。

    目前,将一个 WCF 数据服务层叠在另一个之上是相当困难的。 “服务器”生成的 LINQ 表达式树并不总是被“客户端”LINQ 提供程序理解。这就是你遇到的问题。

    有一个原型(更像是一个实验)可以通过重写表达式树在某种程度上使这项工作发挥作用。它是 OData Provider Toolkit 的一部分,您可以在此处下载 http://www.odata.org/developers/odata-sdk#/media/7579/odataprovidertoolkit.zip。 (它位于 AstoriaOverAstoria 项目的 Experimental 文件夹中)。

    但请注意,这实际上只是一个实验,以显示有哪些问题需要解决等等。我绝对建议不要在任何类型的生产环境中使用它。

    【讨论】:

      【解决方案2】:

      我发现可以在 Web 层上公开引用应用层上的服务(而不是直接数据)的服务。这仅适用于目前的查询。我不确定需要什么才能让它用于更新、删除等。有什么想法吗?无论如何,这里有一些说明和代码sn-ps:

      1. 首先在绑定到 edmx 模型的应用层上创建 WCF 数据服务。
      2. 然后在未绑定到 edmx 模型(自定义)的 Web 层上创建 WCF 数据服务。
      3. 在 Web 层服务中创建对应用层服务的服务引用。
      4. 将 Entities 类型传递给 DataService 泛型声明(对于 VB 应该是尖括号,但我无法让它们显示:
      
              Public MyWebTierService 
              Inherits DataService[MyServiceReference.MyAppTierEntities]
      
      1. 为 CreateDataSource() 添加一个覆盖,创建您对应用层的引用:
      
       Protected Overrides Function CreateDataSource() As MyServiceReference.MyAppTierEntities
              Dim ctx = New MyServiceReference.MyAppTierEntities(New Uri("http://yourappservicelocation/AppService.svc/"))
              Return ctx
          End Function
      

      您现在要做的就是创建对服务的引用或将其绑定到您的客户端应用 支持 OData。如果需要,可以添加 JSONP 支持。

      所以,这对查询很有效,但对更新无效,可能是因为类型不同(它们可能看起来相同,但毕竟在不同的程序集中)。因此,Web 层和应用层之间的跟踪丢失了。

      可能我们必须在 Web 层上实现 IUpdatable 来解决这个问题。还不确定,所以任何输入都会有用。

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-02
        • 2011-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多