none
POSTでxmlデータの送受信について RRS feed

  • 質問

  • ASP.NETでxmlデータを受信しているのですが、うまく受け取れません。

    受け取りはXMLで、返しはJSONなのですが、何が足りないのか教えていただきたいです。

    Restlet Clientでテストを行っているのですが、「400 Bad Request」で返ってきます。

    内容としては、「使用してルート名が 'DOCUMENT'、ルート名前空間が '' である XML 本文のシリアル化を解除できません 。XML に対応する型が、サービスの既知の型のコレクションに追加されていることを確認してください。」と返ってきています。

    よろしくお願いいたします。

    呼び出し

    <ServiceContract()>
    Public Interface IR_Test_001    
    <OperationContract()> 
       <WebInvoke(Method:="POST", RequestFormat:=WebMessageFormat.Xml, ResponseFormat:=WebMessageFormat.Json, UriTemplate:="GetReceiveData")>    
    Function GetReceiveData(i_objReq As WCF_Test_001_REQ) As WCF_Test_001_RES
    End Interface

    リクエストの型

    <DataContract(Name:="WCF_Test_001_REQ")>
    Partial Public Class WCF_Test_001_REQ
    
        <XmlRoot("DOCUMENT")> _
        Public Class DOCUMENT
    
            <XmlElement("HEADERINFO")> _
            Public HEADERINFO As HEADERINFO
    
            <XmlElement("MEISAIINFO")> _
            Public MEISAIINFO As MEISAIINFO
        End Class
    End Class
    
    Public Class HEADERINFO
        <XmlElement("ID")> _
        Public ID As ID
    End Class
    
    Public Class MEISAIINFO
        <XmlElement("IDNAME")> _
        Public IDNAMEAs IDNAME
    End Class

    XMLデータ
    <?xml version="1.0" encoding="UTF-8"?>
    <DOCUMENT>
     <HEADERINFO>
      <ID CODE="A"/>
     </HEADERINFO>
     <MEISAIINFO>
      <IDNAME NAME="A"/>
     </MEISAIINFO>
    </DOCUMENT>



    • 編集済み hisai 2019年9月12日 1:45
    2019年9月12日 1:27

回答

  • 何点か問題がありそうです。

    まず、WCFサービスでXMLのシリアライズに使用される既定のシリアライザはDataContractSerializerです。このシリアライザはXmlElement等のSystem.Xml.Serialization名前空間で定義されているXmlElementAttribute等の属性を使用しません。またXML属性からのデシリアライズをサポートしていません。

    System.ServiceModel.XmlSerializerFormat属性を(DataContract属性と同時に?)定義した場合、シリアライザにXmlSerializerを使用させることができるという記述を見ました。CODE="A"やNAME="A"のようなXML属性値の解析が必須であれば試してみてはいかがでしょうか(私は挙動を確認していませんので、もしかしたらできないかもしれません)。

    XmlSerializerを使用できる&使用するとして、まだ問題があります。

    WCF_Test_001_REQクラスとDOCUMENTクラスの両方を定義するのは不適切です。どちらか1つで十分です。

    WCF_Test_001_REQクラスを使用するのであれば、<XmlRoot("DOCUMENT")>を付けて、HEADERINFOおよびMEISAIINFOを直接持たせるようにします。

    DOCUMENTクラスを使用するのであれば、WCF_Test_001_REQクラスを消して、GetReceiveDataの引数も直接DOCUMENTで受け取るようにします。

    // IDクラス及びIDNAMEクラスについては記載がないのでコメントできません。

    • 回答としてマーク hisai 2019年9月17日 1:30
    2019年9月12日 2:21

すべての返信

  • 何点か問題がありそうです。

    まず、WCFサービスでXMLのシリアライズに使用される既定のシリアライザはDataContractSerializerです。このシリアライザはXmlElement等のSystem.Xml.Serialization名前空間で定義されているXmlElementAttribute等の属性を使用しません。またXML属性からのデシリアライズをサポートしていません。

    System.ServiceModel.XmlSerializerFormat属性を(DataContract属性と同時に?)定義した場合、シリアライザにXmlSerializerを使用させることができるという記述を見ました。CODE="A"やNAME="A"のようなXML属性値の解析が必須であれば試してみてはいかがでしょうか(私は挙動を確認していませんので、もしかしたらできないかもしれません)。

    XmlSerializerを使用できる&使用するとして、まだ問題があります。

    WCF_Test_001_REQクラスとDOCUMENTクラスの両方を定義するのは不適切です。どちらか1つで十分です。

    WCF_Test_001_REQクラスを使用するのであれば、<XmlRoot("DOCUMENT")>を付けて、HEADERINFOおよびMEISAIINFOを直接持たせるようにします。

    DOCUMENTクラスを使用するのであれば、WCF_Test_001_REQクラスを消して、GetReceiveDataの引数も直接DOCUMENTで受け取るようにします。

    // IDクラス及びIDNAMEクラスについては記載がないのでコメントできません。

    • 回答としてマーク hisai 2019年9月17日 1:30
    2019年9月12日 2:21
  • Hongliangさん、解答ありがとうございました。

    問題点が多かったため、JSONで受け取るように変更を行いました。

    2019年9月17日 1:33