2013-12-20 2 views
0

Я пытаюсь использовать API WeatherBug (WSDL - here). Я пытаюсь узнать кое-что о WCF.Применить KnownTypeAttribute к типу объекта?

Я использовал svcutil.exe для создания классов из WSDL по приведенной выше ссылке.

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

var proxy = new WeatherBugWebServicesSoapClient(); 
var stations = proxy.GetStationListByUSZipCode("97211", UnitType.English, "myapikey"); 

я в конечном итоге получаю NetDispatcherFaultException:

Форматировщика бросил исключение при попытке десериализации сообщения: Там была ошибка при попытке десериализации параметра http://api.wxbug.net/:GetStationListByUSZipCodeResponse. Сообщение InnerException было «Ошибка в строке 1 позиция 352. Элемент « http://api.wxbug.net/:anyType »содержит данные от типа, который сопоставляется с с именем« http://api.wxbug.net/:ApiStationData ». В десериализаторе есть никаких сведений о любом типе, который соответствует этому имени. Рассмотрите возможность использования DataContractResolver или добавьте тип, соответствующий «ApiStationData» , в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления его в список известных типов , переданных DataContractSerializer. '. Дополнительную информацию см. В InnerException .

Оказывается, что я должен получить обратно объект типа ArrayOfAnyType, объявленный как это (порожденную svcutil.exe):

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
[System.Runtime.Serialization.CollectionDataContractAttribute(Name = "ArrayOfAnyType", Namespace = "http://api.wxbug.net/", ItemName = "anyType")] 
public class ArrayOfAnyType : System.Collections.Generic.List<object> { 
} 

массив выглядит, как она должна быть коллекция ApiStationData , который объявлен как это:

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name = "ApiStationData", Namespace = "http://api.wxbug.net/")] 
public partial class ApiStationData : object, System.Runtime.Serialization.IExtensibleDataObject { 

Из того, что я читал на различных веб-страниц, я думаю мне нужно добавить KnownTypeAttribute до класса Object, поскольку ArrayOfAnyType является List<object>. Я не думаю, что это возможно, хотя (или правильно) ...

Это также странно, что исключение упоминания http://api.wxbug.net/:anyType, но не определение anyType в SvcUtil сгенерированный код (который почему я сделав предположение о ArrayOfAnyType).

Любые предложения по решению этой проблемы?

ответ

2

KnownTypeAttribute использовано по контракту с данными, не тип цели - это было бы действительно непрактичным по многим причинам. Проверьте Пример раздел here для применения.

Из-за того, что кажется в вашем случае, договор с данными не знает тип ApiStationData, поэтому добавление [KnownType(typeof (ApiStationData))] к вашему контракту на данные должно решить проблему.

+0

Мне все еще не ясно, где следует применять «KnownType». Пример показывает, что он применяется к предку, но предком 'ApiStationData' является объект.Почти все классы, созданные svctool, имеют 'DataContactAttribute', поэтому, когда вы говорите, что это должно быть добавлено к контракту данных, что именно вы имеете в виду? – Steve

+1

Должен быть тот, который содержит свойство ArrayOfAnyType, или я думаю, что это может быть и сам 'ArrayOfAnyType'. –

+1

Работал как шарм. Я на самом деле думал, что я это пробовал, но, видимо, я этого не сделал. Спасибо за помощь. Следующий вопрос, который я, вероятно, выясню в какой-то момент, - это то, почему WSDL не располагает достаточной информацией для svctool, чтобы понять, что это необходимо, или почему svctool недостаточно умен, чтобы понять это. Или, это просто WCF, что не относится к другим языкам ... Больше узнать, что делает его забавным :) – Steve

Смежные вопросы