Use base class as parameter for WCF Service

后端 未结 1 1732
醉酒成梦
醉酒成梦 2021-01-26 13:43

I have a multi-project solution. One Project is providing a DLL containing multiple classes.

One of those classes is WorkerTemplate. Two other classes inher

相关标签:
1条回答
  • 2021-01-26 14:22

    The error message tells you what to do:

    The InnerException message was 'Type 'DV_BII30.ExecSQLWorker' with data contract name 'ExecSQLWorker:http://schemas.datacontract.org/2004/07/DV_BII30' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.'. Please see InnerException for more details. ---> System.Runtime.Serialization.SerializationException: Type 'DV_BII30.ExecSQLWorker' with data contract name 'ExecSQLWorker:http://schemas.datacontract.org/2004/07/DV_BII30' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

    You have a couple of possibilities to solve this issue.

    1. Add to your WorkerTemplate class the KnownTypeAttribute

      [DataContract]
      [KnownType(typeof(ExecSQLWorker))]
      [KnownType(typeof(CopyWorker))]
      public class WorkerTemplate
      {
          //Properties and stuff
      }
      
    2. If you can change the IPQWService interface, take a look here

    3. You can use a DataContractResolver

      public class SharedTypeResolver : DataContractResolver
      {
          public override bool TryResolveType(Type dataContractType, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
          {
              if (!knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace))
              {
                  XmlDictionary dictionary = new XmlDictionary();
                  typeName = dictionary.Add(dataContractType.FullName);
                  typeNamespace = dictionary.Add(dataContractType.Assembly.FullName);
              }
          }
      
          public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
          {
              return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null) ?? Type.GetType(typeName + ", " + typeNamespace);
          }
      }
      

      The Resolver accepts every type you use in your service. But you have to add the resolver to your Client endpoint and server endpoint. Like this:

      Host = new ServiceHost(typeof(MyService));
      
      ContractDescription cd = Host.Description.Endpoints[0].Contract;
      foreach (var operation in cd.Operations)
      {
          operation.Behaviors.Find<DataContractSerializerOperationBehavior>()
                  .DataContractResolver = new SharedTypeResolver();
      }
      
    0 讨论(0)
提交回复
热议问题