次のような単一の Web メソッドを持つ .NET 2 Web サービスがあります。
[WebMethod]
public Common.foobar DoSomething(Common.foobar foo)
foobar クラスは、(.NET 互換 Web 参照ではなく) サービス参照を介して Web サービスを呼び出す .NET 3.5 アプリケーションでも (プロジェクト参照として) 利用できる共通の .NET 2 アセンブリで定義されます。
問題は、サービス参照名前空間に独自の自動生成された foobar の実装が含まれていることです。そのため、プロキシ SOAP クライアントで使用可能な、自動生成された Service Reference メソッドには、次の署名があります。
ServiceReference.foobar DoSomething(ServiceReference.foobar foo)
Web サービスは .NET 2 ベースであり、共通クラスの再利用は WCF のようにサポートされていないため、これは避けられません。
質問は、Common.foobar クラスを WebServiceReference.foobar クラスに複製する簡単で信頼できる方法を知っている人はいますか? または、共通ライブラリで定義されているクラスを使用できる「ハック」を知っている人はいますか? または、誰でも私が木のために木を逃した場所を指摘できますか?それは実際には共通ライブラリクラスを使用することが可能です
編集-いくつかの詳細情報
.NET 2 Web サービス クラスは次のようになります。
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public CommonLibrary.Foobar DoSomething(CommonLibrary.Foobar foo)
{
return new CommonLibrary.Foobar() { Data = "Data in common foobar class", EventCode = 1, MessageId = "mid" };
}
}
呼び出し元のクライアント (.NET 3.5 - .NET サービスへのサービス参照あり) は次のようになります。
static void Main(string[] args)
{
// Create the soap client for the .NET 2 service using the auto generated proxy class
var serviceClient = new NET2WebService_ServiceReference.Service1SoapClient();
//Just checking that there is a project reference to CommonLibrary
var commonFoobar_Request = new CommonLibrary.Foobar()
{
Data = "Common foobar data",
EventCode = 1,
MessageId = "Common foobar message id"
};
// This doesn't work as the Service Reference client does not accept the
// common foobar class.
/*
var commonFoobar_Response = serviceClient.DoSomething(commonFoobar_Request);
Console.WriteLine(commonFoobar_Response.Data);
*/
// This is the proxy class to foobar generated by the Service Reference
var serviceRefFoobar_Request = new NET2WebService_ServiceReference.Foobar()
{
Data = "Common foobar data",
EventCode = 1,
MessageId = "Common foobar message id"
};
// This does work as it does uses the autogenerated Foobar class in the service
// reference
var serviceRefFoobar_Response = serviceClient.DoSomething(serviceRefFoobar_Request);
Console.WriteLine(serviceRefFoobar_Response.Data);
}
共通ライブラリ (これも .NET 2) の foobar クラスは次のようになります。
public partial class Foobar
{
private string dataField;
private int eventCodeField;
private string messageIdField;
public string Data
{
get
{
return this.dataField;
}
set
{
this.dataField = value;
}
}
public int EventCode
{
get
{
return this.eventCodeField;
}
set
{
this.eventCodeField = value;
}
}
public string MessageId
{
get
{
return this.messageIdField;
}
set
{
this.messageIdField = value;
}
}
}
そして、次のようなスキーマから派生します。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Foobar">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Data" type="xs:string"/>
<xs:element name="EventCode" type="xs:int"/>
</xs:sequence>
<xs:attribute name="MessageId" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
最後に、.NET 3.5 クライアントのサービス リファレンス構成ページのスクリーンショットを次に示します。
このスクリーンショットから、サービス構成、つまりクライアント プロジェクトが、私の Foobar クラスの実装を含む CommonLibrary を認識していることがわかります。
上記のすべてが機能することは言及する価値がありますが、実際には foobar クラスはここに投稿されたサンプルよりもはるかに複雑です。したがって、Common.Foobar => ServiceReference.Foobar をリクエストに対して、またはその逆をレスポンスに対して変換するのではなく、フレームワーク全体で Common.foobar を使用できるソリューションを見つけたいと思っています。