質問

I have a net.tcp WCF service and its client, each in one assembly and sharing another assembly containing the service interface and DTOs.

The client is implemented as a proxy to the service using a Channel instantiated through ChannelFactory:

public ServiceClient : IService
{
   IService _channel;

   public ServiceClient()
   {
      _channel =  new ChannelFactory<IService>("NetTcp_IService")
         .CreateChannel();
   }

   public DTO ServiceMethod()
   {
       return _channel.ServiceMethod();
   }
}

public class DTO
{
   public IList<int> SomeList;
}

As expected, the SomeListfield of the DTO returned by the client is an array but I would like it to be converted by WCF to a List. As you may suspect from the described set-up, I don't use svcutil (or the Add Service Reference dialog for that matter), so I can't use configureType.

I don't want to modify the client proxy to instantiate the List and modify the received DTO in my client proxy because the actual implementation uses a command processor using interfaces resolved through dependency injection at run-time to avoid coupling - and this solution would do the opposite, by requiring the client to perform know service commands.

Therefore, I'm currently using the work-around which modifies the DTO to internally create the List instance:

public class DTO
{
   private IList<int> _someList;
   public IList<int> SomeList
   {
      get { return _someList; }
      set {
         if (value != null)
            _someList = new List<int>(value);
         else
            _someList = new List<int>();
      }
   }
}

However, I'd rather avoid this. So the question is:

How can I configure the WCF deserialization so that the array is converted to the expected List?

Is there any way to configure the deserialization through the binding either in the App.config or from code upon Channel creation? Maybe through ImportOptions.ReferencedCollectionTypes or CollectionDataContract?

役に立ちましたか?

解決

There are 4 ways:

  1. Convert data to List in your save methods on Client side

  2. Change property type:

    public IList<int> SomeList;
    

    to

    public List<int> SomeList;
    
  3. Approach you have shown above (changing type on assigment).

  4. Implement IDataContractSurrogate. But you will have to apply a behaviour on client side.
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top