WebService、WebMethod、および継承
-
03-07-2019 - |
質問
Webサービスコンテキストでは、クラスMammalを継承する次のクラスがあります。 Mammalクラスはプロキシで定義されます。そのクラスの定義を変更することはできません。クライアント側でクラスMammalにメソッドを追加する必要があるため、Mammalを継承してGiraffeを作成しました。
namespace TestApplication
{
public class Giraffe : Mammal
{
public Giraffe()
{
}
}
}
Mammal型のオブジェクトを予期するWebMethodを呼び出すと、Giraffeが予期されていないことを通知する次の例外が発生します。
Error: System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Giraffe was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write6_Tender(String n, String ns, Tender o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write12_PaymentRequestAuthorization(String n, String ns, PaymentRequestAuthorization o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write13_PaymentRequestAuthorization(Object o)
--- End of inner exception stack trace ---
回避策はありますか? XmlIncludeを実際に追加することはできません...
解決
メソッドを追加するには、部分クラスを使用する必要があります。 (正しい名前空間などで)2番目のクラスファイルを追加してみてください:
partial class Mammal {
public void ExtraMethod() {...}
}
partial
キーワードは、クラスを複数のファイルに分割できるようにコンパイラーに指示します-コード生成シナリオに最適です。ただし、すべてのファイルに partial
キーワードが必要です。メンバーは単純に結合されます(独自の微妙な動作を持つC#3.0の部分メソッドを除きます)。 wsdl.exe(またはその他)にこれが含まれていることを希望しています!
他のヒント
変更できないクラスにメソッドを追加する場合は、拡張メソッドを作成します。
public static class MammalExt {
public static void ExtraMethod(this Mammal mammal) {...}}
哺乳類がプロキシ生成クラスである場合、部分クラスである必要があります。
XmlIncludeを使用する必要があります。それはあなたの唯一の選択です。シリアライズを行うためのコードを生成する必要があるため、シリアライズするクラスをシリアライザーに通知する必要があります。
これを書いている間、GiraffeにIXmlSerializableを実装することで逃げるかもしれないと思いましたが、それはさらに作業です。
正しい答えは、実際には部分クラスを使用することです。クライアントプロジェクトを開いてWeb参照を生成すると、Visual StudioはWSDLを解析し、 Mammal
というクラスを生成します。このクラスはクライアントプロジェクトにのみ表示されるため、サーバー側のことを心配する必要はありません。
MyWebServiceというWeb参照があるとします。次に、 MyWebService.Mammal
というクラスがあります。このクラスにメンバーを追加するには、これを含む新しいソースファイルを作成するだけです。
namespace MyWebService {
public partial class Mammal {
public void ExtraMethod() { ... }
}
}
Mammal
を返すWebサービスのメソッドを呼び出すと、Web参照コードにより、「改善された」の新しいインスタンスが作成されます。哺乳類クラス、およびワイヤ上のxmlからインスタンスに値をコピーします。