Типы, скрываемые в прокси сервиса WCF? - PullRequest
1 голос
/ 23 декабря 2011

В моем решении Visual Studio есть три проекта:

  1. «Ядро» содержит несколько типов.
  2. «Служба WCF» использует все типы в «Ядре»в методах обслуживания.
  3. «Тестовый клиент» - это тестовое клиентское приложение, в котором есть только набор тестового кода.

Когда я использую свою службу WCF в своем тестовом клиенте, все выглядити прекрасно работает. Прокси для методов службы сгенерирован, так что я могу передавать параметры с правильным типом, таким как Core.BusinessObj. Однако, когда я использую ту же службу WCF из Core, генерируемый прокси требует, чтобы те же самые методы службы передавались какthis: ServiceProxy.BusinessObj. Это вызывает проблему, так как я хочу создать объект типа Core.BusinessObj и передать его моему сервису независимо от того, где этот сервис используется. Я уверен, что это как-то связано со ссылкой на мой сервис WCFв том же проекте, где определены все типы, но не может понять, как правильно определить пространства имен.

вы знаете, что я делаю не так?

Ответы [ 3 ]

1 голос
/ 23 декабря 2011

Вы не делаете ничего плохого - так работает WCF!

Когда вы создаете сервис, вы определяете методы сервиса и параметры (и их типы данных), которые ожидают эти сервисы. Это упаковано на стороне сервера и обычно предоставляется через обмен метаданными (MEX).

Когда клиент приходит и создает прокси на стороне клиента для вашего сервиса, все, на что он может положиться - это биты и кусочки в метаданных - описание методов сервиса (имена, параметры) и описание того, что XML будет выглядеть так, как будто он перемещается между клиентом и сервером.

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

Клиент создает новых типов на стороне клиента , которые будут иметь одинаковую «площадь присутствия XML» (такую ​​же структуру в сериализованном XML) - но это все, что он может сделать. Вот почему вы получаете типы, которые очень похожи - но они отличаются (обычно в другом пространстве имен). Это также причина, по которой у вас не должно быть никакой функциональности (кода) в ваших контрактах данных на стороне сервера - вы не можете сериализовать функциональность через сообщения XML .....

Теперь, если вы управляете обоими концами коммуникационного провода (и сервером, и клиентом) и записываете их обоих в .NET, вы можете воспользоваться «ярлыком» для повторного использования типов. По сути, вам нужно сделать то, что вы сделали - поместить все типы и интерфейсы в отдельную сборку («Ядро»). Далее: до вы создаете свой прокси WCF на стороне клиента, убедитесь, что клиентский проект ссылается на эту "базовую" сборку. Когда вы создаете прокси на стороне клиента WCF со ссылкой на сборку «Core», вы можете сказать WCF «повторное использование типов в ссылочных сборках» - если у вас включен этот параметр (он включен по умолчанию), то, если ваши ссылочные сборки уже содержат тип данных, который соответствует потребностям клиента WCF, затем этот тип (из вашей сборки «Core») будет использоваться повторно (вместо созданного нового).

enter image description here
WCF - Добавить справочник услуг - Дополнительные параметры

0 голосов
/ 23 декабря 2011

Я построил решение, как вы описали. И это проходит тест без проблем. В моем решении сейчас 3 проекта

  1. Core
  2. WCFService
  3. TestClient

Project Core имеет один класс "BusinessObj"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Core
{
    [Serializable]
    public class BusinessObj
    {
        public int id { get; set; }
    }
}

В проекте WCFService имеется веб-служба с именем «Service1» (ссылка на Core была добавлена)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WCFService
{
    public class Service1 : IService1
    {
        public Core.BusinessObj GetBusinessObj()
        {
            return new Core.BusinessObj()
            {
                id = 1
            };
        }
    }
}

Тестовый проект, TestClient имеет один модульный тест "UnitTest1" (ссылка на Core была добавлена) (добавлена ​​сервисная ссылка на Service1)

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestClient.ServiceReference;
using Core;

namespace TestClient
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Service1Client ServiceProxy = new Service1Client();

            BusinessObj x = ServiceProxy.GetBusinessObj();
            Assert.IsTrue(x.id == 1, "Something's wrong dude!!!");

        }
    }
}

Я думаю, "используя Core;" отсутствует в вашем TestClient

0 голосов
/ 23 декабря 2011

Убедитесь, что ваш Core.BusinessObj поддерживает сериализацию

(Пример, предполагая его для .NET 4)

[Serializable]
public class BusinessObj 

Убедитесь, что ваш сервис работает нормально (без ошибок)

Обновление справочной службы (после успешного построения службы)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...