0

私は次のように定義された契約を持っています:

 [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 つ。コマンド クラスに属性は必要ありません。[/編集]

お読みいただきありがとうございます。

4

1 に答える 1

0

LIkeはコメントの中で、私のコマンドCmd1には説明と作成日のためのプライベートセッターがあったと述べました。WCFを使用するのと同じように、私はxmlserializerを使用していますが、知っておくべきことが2つあります。

シリアル化するには、プロパティにパブリックセッターが必要なヌードコンストラクターが必要です。

これらの2つの障害を回避するために、xmlシリアライザーから別の何かに変更する可能性がある場合は、今すぐ変更する必要があります。

于 2012-07-02T07:13:53.290 に答える