WCF序列化与抽象类

时间:2012-06-28 08:46:16

标签: wcf inheritance serialization abstract-class

我的合约定义如下:

 [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);
    }

此处详细说明了对我的网络服务的调用:

var id = Guid.NewGuid();
var cmdCreate = Build.Cmd1
                     .ForCreationDate(DateTime.Now)
                     .ForDescription("test")
                     .Build(id);

var client = new Ref1.CommandWebServiceClient();

client.Execute(cmdCreate);

生成的消息具有正确的id,因为此信息是抽象类的CommandBase的一部分,但creationdate和description不是xml的一部分。

有什么我省略了吗?

[编辑] 我没有说的一件重要的事情。我不希望我的命令类有任何属性。 [/编辑]

感谢您的阅读,

1 个答案:

答案 0 :(得分:0)

LIke在评论中说,我的命令Cmd1有描述和创建日期的私人制定者。就像使用WCF一样,我使用xmlserializer,有两件事要知道:

必须有一个裸体照片 该物业必须有一个公共二传手才能被序列化。

如果我可以从xml序列化程序到不同的东西来绕过这两个障碍,我现在就会有一个改变。