комплексные типы ksoap2 и WCF - PullRequest
2 голосов
/ 09 июня 2011

Я отправляю этот запрос на мой веб-сервис WCF с клиентом Android, используя ksoap2:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"><v:Header />
    <v:Body>
        <HelloComplex xmlns="http://tempuri.org/" id="o0" c:root="1">
            <complex i:type="n0:SampleComplexType" xmlns:n0="http://tempuri.org/">
                <Value i:type="d:string">Hello!</Value>
            </complex>
        </HelloComplex>
    </v:Body>
</v:Envelope>

и получите обратно это:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <s:Fault>
            <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode>
            <faultstring xml:lang="pt-BR">
                The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:complex. The InnerException message was 'Error in line 1 position 363. Element 'http://tempuri.org/:complex' contains data from a type that maps to the name 'http://tempuri.org/:SampleComplexType'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'SampleComplexType' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.
            </faultstring>
        </s:Fault>
    </s:Body>
</s:Envelope>

Но когда мое другое приложение (AspNew MVC) вызывает это:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <HelloComplex xmlns="http://tempuri.org/">
            <complex xmlns:a="http://schemas.datacontract.org/2004/07/IssueCenter.Core" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:Value>C#VALUE!</a:Value>
            </complex>
        </HelloComplex>
    </s:Body>
</s:Envelope>

и это работает.

Что можно сделать, чтобы исправить запросы клиентов Android?

Примечания: я знаю о разнице в пространстве имен и уже пытаюсь сделать то же самое.

1 Ответ

0 голосов
/ 27 апреля 2012

Служба не знает, как обращаться с атрибутом типа «ComplexType» в XML, поэтому вам в основном нужно сообщить сериализатору на стороне службы, что он означает. Вы можете сделать это несколькими способами: либо добавить DataContractResolver, который сообщает сериализатору, что означает этот идентификатор неизвестного типа, либо добавить тип (если он существует на стороне службы) в список «известных типов», поэтому что сервис точно знает, что с ним делать. Я думаю, что вы должны использовать DataContractResolver.

В версии 4.0 платформы WCF представила распознаватель контракта данных. Вместо того, чтобы определять набор известных типов «статически» (например, указав типы непосредственно в KnownTypeAttribute, как вы делали до .NET 4), распознаватель контракта данных предоставляет несколько ловушек, которые позволяют вам указывать в тот момент, когда объект является будучи сериализованным или десериализованным, сопоставление между типом CLR и пространством имен / имен в XML, которое будет использоваться для представления этого «неизвестного» типа. Для этого вы просто наследуете от класса DataContractResolver и предоставляете логику отображения.

Я думаю, что это лучшее решение для вас, потому что вы, скорее всего, не хотите создавать фиктивный тип на стороне сервера просто для решения этой проблемы, что вы должны были бы сделать, если бы использовали KnownTypeAttribute. Единственное, что нужно помнить, это то, что распознаватель делает сериализацию медленнее, чем использование «стандартных» функций известных типов (поскольку известные типы являются статическими, они могут кэшироваться, и вызовы не должны выполняться постоянно), поэтому будьте внимательны. что при использовании резольвера дополнительная функциональность имеет цену в плане времени выполнения.

...