Только корневой объект по запросу десериализуется при использовании Message.GetBody <> - PullRequest
1 голос
/ 24 апреля 2010

Я пытаюсь создать службу wcf, которая принимает любые входные данные (Action = "*"), а затем десериализует сообщение после определения его типа. В целях тестирования десериализации в настоящее время я жестко кодирую тип для службы тестирования.

Я не получаю ошибок от процесса десериализации, но после десериализации заполняется только внешний объект. Все внутренние поля пусты. Я могу успешно обработать тот же запрос к исходному сервису wcf.

Я десериализирую этот путь, где knownTypes - это список типов ожидаемых типов:

DataContractSerializer ser = new DataContractSerializer(new createEligibilityRuleSet ().GetType(), knownTypes);
createEligibilityRuleSet newReq = buf.CreateMessage().GetBody<createEligibilityRuleSet>(ser);

Вот класс и подклассы объекта запроса. Эти классы генерируются svcutil с использованием подхода сверху вниз из существующего wsdl. Я попытался заменить XmlTypeAttributes на DataContracts и XmlElements на DataMembers без разницы. Это экземпляр CreateEligibilityRuleSetSvcRequest для объекта createEligibilityRuleSet, который является нулевым. Я включил запрос, извлеченный из запроса внизу

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://RulesEngineServicesLibrary/RulesEngineServices")]
public partial class createEligibilityRuleSet
{

private CreateEligibilityRuleSetSvcRequest requestField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = true, Order = 0)]
public CreateEligibilityRuleSetSvcRequest request
{
    get
    {
 return this.requestField;
    }
    set
    {
 this.requestField = value;
    }
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://RulesEngineServicesLibrary")]
public partial class CreateEligibilityRuleSetSvcRequest : RulesEngineServicesSvcRequest
{

private string requestField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]

public string request
{
    get
    {
 return this.requestField;
    }
    set
    {
 this.requestField = value;
    }
}
}

[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateEligibilityRuleSetSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ApplyMemberEligibilitySvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateCompletionCriteriaRuleSetSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CopyRuleSetSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DeleteRuleSetByIDSvcRequest))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://RulesEngineServicesLibrary")]
public partial class RulesEngineServicesSvcRequest : ServiceRequest
{
}

/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(RulesEngineServicesSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateEligibilityRuleSetSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ApplyMemberEligibilitySvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateCompletionCriteriaRuleSetSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CopyRuleSetSvcRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DeleteRuleSetByIDSvcRequest))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://FELibrary")]
public partial class ServiceRequest
{

private string applicationIdField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]

public string applicationId
{
    get
    {
 return this.applicationIdField;
    }
    set
    {
 this.applicationIdField = value;
    }
}
}

Запрос от клиента приходит в теле сообщения, как показано ниже. Получено из сообщения во время выполнения.

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:rul="http://RulesEngineServicesLibrary/RulesEngineServices">
<soap:Header/>
   <soap:Body>
      <rul:createEligibilityRuleSet>
         <request>
            <applicationId>test</applicationId>
            <request>Perf Rule Set1</request>
         </request>
      </rul:createEligibilityRuleSet>
   </soap:Body>
</soap:Envelope>

1 Ответ

2 голосов
/ 24 апреля 2010

Конкретная проблема, с которой вы сталкиваетесь, заключается в том, что DataContract не знает, как обрабатывать неквалифицированные элементы. Но это делает XmlSerializer, и ваши классы правильно отнесены к XmlSerializer.

Таким образом, вы должны использовать XmlSerializer вместо DataContractSerializer для десериализации содержимого тела:

public static T GetBodyWithXmlSerializer<T>(this Message msg)
{
    var ser = new XmlSerializer(typeof(T));
    T o;
    using (var reader = msg.GetReaderAtBodyContents())
    {
        o = (T)ser.Deserialize(reader);
    }
    return o;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...