Я создаю службу WCF, и у меня возникают проблемы с некоторыми проблемами сериализации. Возможно, есть только один способ сделать это, но я хотел бы подтвердить это Здесь мой пример кода:
контракты
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, я должен упустить что-то, что сериализатор не может обработать. но я не знаю, что.