2

.Net 3.0 と VS2005 を使用。

問題のオブジェクトは WCF サービスから消費され、レガシ API の XML にシリアル化されます。したがって、TestObject をシリアル化するのではなく、[XmlRoot] 属性が欠落している .TestObject をシリアル化していました。ただし、子要素のすべての [Xml*] 属性は、生成されたプロキシ コードに含まれていたため、問題なく機能しました。そのため、すべての子要素は正常に機能しましたが、生成されたプロキシ コードに [XmlRoot] 属性が含まれていなかったため、外側の要素は正常に機能しませんでした。[XmlRoot] 属性を含む元のオブジェクトは、手動で正常にシリアル化されます。

生成されたプロキシ クラスも正しくシリアル化されるように、プロキシ コードに [XmlRoot] 属性を含めることはできますか? それができない場合は、[XmlType] を使用する必要があると思いますが、他のコンポーネントを変更する必要があるため、前者を優先します。また、自動生成されたプロキシ クラスを手動で編集する必要も避けたいと考えています。

サンプル コードを次に示します (クライアントとサービスを同じアプリに含めました。これは迅速でテスト目的のためです。サービス参照コードをコメント アウトし、アプリの実行中にサービス参照を追加してから、サービス コードのコメントを外して実行します。 .)

namespace SerializationTest {  
  class Program {  
    static void Main( string[] args ) {  

        Type serviceType = typeof( TestService );  
        using (ServiceHost host = new ServiceHost(   
            serviceType,   
            new Uri[] {   
                new Uri( "http://localhost:8080/" )  
            }  

        ))
        {

            ServiceMetadataBehavior behaviour = new ServiceMetadataBehavior();  
            behaviour.HttpGetEnabled = true;  
            host.Description.Behaviors.Add( behaviour );  

            host.AddServiceEndpoint( serviceType, new BasicHttpBinding(), "TestService" );  
            host.AddServiceEndpoint( typeof( IMetadataExchange ), new BasicHttpBinding(), "MEX" );  


            host.Open();  

            TestServiceClient client = new TestServiceClient();  
            localhost.TestObject to = client.GetObject();  

            String XmlizedString = null;  
            using (MemoryStream memoryStream = new MemoryStream()) {
                XmlSerializer xs = new XmlSerializer( typeof( localhost.TestObject ) );  
                using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream)) {
                    xs.Serialize( xmlWriter, to );  
                    memoryStream = (MemoryStream)xmlWriter.BaseStream;  
                    XmlizedString = Encoding.UTF8.GetString( memoryStream.ToArray() );  
                    Console.WriteLine( XmlizedString );  
                }    
            }    
        }

        Console.ReadKey();  
    }  
}  

[Serializable]  
[XmlRoot( "SomethingElse" )]  
public class TestObject {  

    private bool _worked;  

    public TestObject() { Worked = true; }  

    [XmlAttribute( AttributeName = "AttributeWorked" )]  
    public bool Worked {  
        get { return _worked; }  
        set { _worked = value; }  
    }  
}  

[ServiceContract]  
public class TestService {  

    [OperationContract]  
    [XmlSerializerFormat]  
    public TestObject GetObject() {  
        return new TestObject();  
    }  
  }  
}  

これが生成する Xml を次に示します。

<?xml version="1.0" encoding="utf-8"?>
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" AttributeWorked="true" /> 
4

2 に答える 2

1

== もしも ==

これはXmlRoot属性専用です。には、属性XmlSerializerを指定できるコンストラクターが 1 つあります。XmlRoot

それを指摘してくれた csgero に感謝します。彼のコメントが解決策になるはずです。

XmlSerializer Constructor (Type, XmlRootAttribute)

XmlSerializer指定した型のオブジェクトを XML ドキュメントにシリアル化し、XML ドキュメントを指定した型のオブジェクトに逆シリアル化できるクラスの新しいインスタンスを初期化し ます。また、XML ルート要素として使用するクラスも指定します。

于 2009-06-23T08:56:39.243 に答える
-1

この状況を解決する手段を提供する人を見つけました:

Matevz Gacnik のウェブログ

のそのアプローチを使用してXmlAttributeOverrides、次のように記述しました。

    private static XmlSerializer GetOverridedSerializer()
    {
        // set overrides for TestObject element
        XmlAttributes attrsTestObject = new XmlAttributes();
        XmlRootAttribute rootTestObject = new XmlRootAttribute("SomethingElse");
        attrsTestObject.XmlRoot = rootTestObject;

       // create overrider
       XmlAttributeOverrides xOver = new XmlAttributeOverrides();
       xOver.Add(typeof(localhost.TestObject), attrsTestObject);

       XmlSerializer xSer = new XmlSerializer(typeof(localhost.TestObject), xOver);
       return xSer;
    }

そのメソッドをProgram例のクラスに入れ、次の行を に置き換えますMain()

        //XmlSerializer xs = new XmlSerializer(typeof(localhost.TestObject));
        XmlSerializer xs = GetOverridedSerializer();

そして、実行して結果を確認します。

これが私が得たものです:

<?xml version="1.0" encoding="utf-8"?><SomethingElse xmlns:xsi="http://www.w3.o
rg/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Attribu
teWorked="true" />
于 2008-10-07T03:48:32.437 に答える