私は次のように定義された契約を持っています:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class CommandWebService : ICommandWebService
{
public ExecuteResponse Execute(CommandBase command)
{
...
}
}
コマンドベースが抽象クラスである場合:
[Serializable]
[KnownType("GetKnownTypes")]
public abstract class CommandBase : Message, ICommand
{
public static Type[] GetKnownTypes()
{
var types = from asm in AppDomain.CurrentDomain.GetAssemblies()
from type in asm.GetTypes()
where typeof(CommandBase).IsAssignableFrom(type) && !type.IsAbstract
select type;
return types.ToArray();
}
}
これらを別のプロジェクトで使用して、WCF サービスをインスタンス化しました。
var bus = RabbitHutch.CreateBus("host=localhost"); ;
var commandHandler = new CommandHandlerService();
var projectionHandler = new ProjectionHandlerService();
var commandWebService = new CommandWebService(bus, commandHandler, projectionHandler);
using (var commandServiceHost = new ServiceHost(commandWebService))
{
commandServiceHost.Open();
Console.WriteLine("service started");
var quitFlag = false;
while (!quitFlag)
{
var keyInfo = Console.ReadKey();
quitFlag = keyInfo.Key == ConsoleKey.C
&& keyInfo.Modifiers == ConsoleModifiers.Control;
}
}
次の serviceModel を使用します。
<system.serviceModel>
<bindings/>
<services>
<service name="CommandService.CommandWebService" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:1338/MyApp"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
contract="CommandService.ICommandWebService"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
以下を追加および削除しましたが、問題は変わりません。
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="CommonDomain.CommandBase, CommonDomain, Version=1.4.0.0, Culture=neutral">
<knownType type="MyNamespace.Cmd1, MyNamespace, Version=1.0.0.0, Culture=neutral"/>
<knownType type="MyNamespace.Cmd2, MyNamespace, Version=1.0.0.0, Culture=neutral"/>
<knownType type="MyNamespace.Cmd3, MyNamespace, Version=1.0.0.0, Culture=neutral"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
そうすることでうまくいきます。サービスが開始され、コンソール アプリケーションでそれを参照できます。これにより、次の参照が得られます。
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="Contabilita.ICommandWebService")]
public interface ICommandWebService
{
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICommandWebService/Execute", ReplyAction="http://tempuri.org/ICommandWebService/ExecuteResponse")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyNamespace.Cmd1))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyNamespace.Cmd2))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyNamespace.Cmd3))]
MyConsole.Ref1.ExecuteResponse Execute(Common.CommandBase command);
}
私のWebサービスへの呼び出しの詳細は次のとおりです。
var id = Guid.NewGuid();
var cmdCreate = Build.Cmd1
.ForCreationDate(DateTime.Now)
.ForDescription("test")
.Build(id);
var client = new Ref1.CommandWebServiceClient();
client.Execute(cmdCreate);
この情報は CommandBase の抽象クラスの一部ですが、作成日と説明は xml の一部ではないため、結果のメッセージには正しい ID が含まれます。
私が省略したものはありますか?
[編集] 言い忘れた重要なことを 1 つ。コマンド クラスに属性は必要ありません。[/編集]
お読みいただきありがとうございます。