Я создаю службу WCF, и у меня много проблем с некоторыми проблемами сериализации. Возможно, есть только 1 способ сделать это, но я хотел бы подтвердить это
Вот мой пример кода:
Контракты
public interface IAtm
{
[DataMember]
double Latitude { get; set; }
[DataMember]
double Longitude { get; set; }
}
[ServiceContract]
public interface IAtmFinderService
{
[OperationContract]
ICollection<IAtm> GetAtms();
}
Реализация услуги:
[KnownType(typeof(Atm))]
[KnownType(typeof(List<Atm>))]
[ServiceKnownType(typeof(Atm))]
[ServiceKnownType(typeof(List<Atm>))]
public class AtmFinderService : IAtmFinderService
{
public ICollection<IAtm> GetAtms()
{
return new List<IAtm>()
{
new Atm() { Latitude = 1, Longitude = 1 },
new Atm() { Latitude = 2, Longitude = 2 }
};
}
}
Я добавил все атрибуты KnownType и ServiceKnownType, потому что думал, что там чего-то не хватает ..
Итак, сейчас я делаю несколько тестов. Я попытался создать консольное приложение, используя метод «добавить ссылку на службу», чтобы VS автоматически создавал прокси. Таким образом, я получаю функцию вроде
object[] GetAtms();
При попытке вызвать это я получаю эту ошибку:
Сообщение InnerException было «Тип
'WCFTest.Atm' с именем контракта данных
«Банкоматы: http://schemas.datacontract.org/2004/07/WCFTest'
не ожидается Рассмотрите возможность использования
DataContractResolver или добавить любые типы
статически не известен в списке
известные типы - например, с помощью
атрибут KnownTypeAttribute или
добавив их в список известных типов
передано в DataContractSerializer. '.
Очень хорошо ... Итак, я думаю, что автоматически сгенерированный код VS - дерьмо. Я сделал следующее изменение в своем сервисе (и всех связанных классах и реализациях):
[OperationContract]
ICollection<Atm> GetAtms();
Так что теперь я возвращаю конкретный тип. После обновления ссылки на сервис, он создает копию класса Atm, его членов и прочее.
После вызова службы, вызов завершается успешно.
Я подумал, что это было плохое поведение, связанное с автоматически сгенерированным кодом, поэтому я попытался создать очень простое приложение хост / клиент. Я запустил консольный хост, прослушивающий некоторый порт, а затем создал клиента, который использует класс ClientBase для вызова службы. Такое же поведение ... если служба реализована с возвращением типа интерфейса, она завершается ошибкой. Если я изменю это, чтобы возвратить конкретный тип, это работает. Я думаю, что у меня есть некоторые проблемы с атрибутами KnownType, я должен пропустить что-то, что не может обработать сериализатор. но я не знаю что.