生成されたプロキシクラスに含まれない属性
-
03-07-2019 - |
質問
.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" />
解決
この状況を解決する手段を提供してくれる人を見つけました:
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" />
他のヒント
== IF ==
これは、 XmlRoot
属性専用です。 XmlSerializer
には、 XmlRoot
属性を指定できるコンストラクターが1つあります。
それを指し示してくれたcsgeroに感謝します。彼のコメントが解決策になるはずです。
XmlSerializer Constructor (Type, XmlRootAttribute)
の新しいインスタンスを初期化します シリアル化できる
XmlSerializer
クラス 指定されたタイプのオブジェクトをXMLに ドキュメント、およびXMLのデシリアライズ 指定のオブジェクトへの文書化 タイプ。また、クラスを指定します XMLルート要素として使用します。