Служба данных WCF - Прокси-сервер среднего уровня - PullRequest
1 голос
/ 24 марта 2010

Проект, над которым мы работаем, представляет собой классическую трехуровневую архитектуру. Уровень 1 - это сервер базы данных, уровень 2 - службы приложений, а уровень 3 - уровень представления (веб-сайт).

На уровне сервисов приложений у меня есть проект, который включает модель структуры сущностей и службу на основе служб данных WCF, которая предоставляет сущности в рамках модели, например ::100100

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, он выдает не реализованное исключение.

Есть идеи, как расширить сервис веб-сайта, чтобы он поддерживал те же запросы, что и сервис среднего уровня?

Ответы [ 2 ]

1 голос
/ 15 июня 2010

Если вам не нужно изменять форму или функциональность сервера данных, вы сможете просто перенаправлять запросы и ответы, как прозрачный HTTP-прокси. Единственное отличие, которое вам может понадобиться - настроить URL службы. Поскольку прокси-служба будет иметь базовый URI, отличный от реального сервиса, полезная нагрузка будет содержать URI реального сервиса (в ссылках и т. Д.), Которые не будут работать. Вы можете обойти это, используя собственный хост для вашей реальной службы и лгать ему о его URI. Это делается через интерфейс IDataServiceHost2, вы возвращаете «новый» URI из свойств AbsoluteRquestUri и AbsoluteServiceUri. Хороший пример реализации интерфейса (хотя для другой цели) здесь: 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. (находится в папке Experimental, проект AstoriaOverAstoria).

Но, пожалуйста, имейте в виду, что на самом деле это всего лишь эксперимент, показывающий, какие проблемы нужно решить, и так далее. Я определенно рекомендую НЕ использовать его в любой производственной среде.

0 голосов
/ 13 октября 2011

Я нашел возможным выставить службу на веб-уровне, которая ссылается на службу (не на данные напрямую) на уровне приложения. Это работает только для запросов на данный момент. Я не уверен, что нужно, чтобы заставить его работать для обновлений, удалений и т. Д. Любые идеи кто-нибудь? Во всяком случае, вот некоторые инструкции и фрагменты кода:

  1. Сначала вы создаете службу данных WCF на уровне приложений, привязанную к вашей модели edmx.
  2. Затем создайте Службу данных WCF на веб-уровне, не привязанном к модели edmx (настраиваемой).
  3. Создание ссылки на службу в службе веб-уровня на службу уровня приложения.
  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.

Итак, это прекрасно работает для запросов, но не для обновлений, вероятно, потому что типы не одинаковы (они могут выглядеть одинаково, но в конце концов находятся в разных сборках). Таким образом, отслеживание теряется между веб-уровнями и уровнями приложений.

Возможно, для решения этой проблемы нам нужно реализовать IUpdatable на веб-уровне. Пока не уверен, поэтому любой ввод будет полезен.

Надеюсь, это поможет

...