返回接口类型时服务中断-序列化问题?

时间:2019-05-08 08:52:21

标签: c# wcf serialization service interface

我的系统由以下部分组成:

  • 通过代理与服务进行通信的客户端脚本
  • 实现服务合同的服务
    此服务通过使用/引用Session.dll和SessionContracts.dll(均从不同的命名空间编译)来创建会话

服务代码运行,但是代理在返回时中断(System.ServiceModel.CommunicationObjectFaultedException)。参见下面的代码(可能与返回接口类型有关吗?):

请注意,在这种情况下,通道会中断,但是如果我返回null而不是会话,则它不会中断。

namespace SessionContracts  
{  
    public interface ISessionBase
    {
        void Connect();
    }
}

namespace SessionNameSpace  
{  
    [DataContract]  
    //    [KnownType(typeof(SessionBase))]     // Needed???
    [KnownType(typeof(ISessionBase))]  
    public class SessionBase : ISessionBase  
    {  
        public SessionBase() 
        {  
        }     
        public void Connect()  
        {  
        }  
    }  
}  

namespace Device.ServiceContract
{
    [ServiceContract(Namespace = "http://Device.Service", CallbackContract = typeof(IDeviceServiceCallback))]
    public interface IDeviceService
    {
        [OperationContract]
        ISessionBase CreateSession(Uin16 id);
    }
}

// This code works, but break within the Proxy on return
namespace Device.Service
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
                     ConcurrencyMode = ConcurrencyMode.Multiple)]

    public class DeviceService : IDeviceService
    {
        public DeviceService() { }

        ISessionBase CreateSession(Uin16 id) // Id not used for now
        {
            return new SessionBase();
        }
    }
}

// Proxy breaking on return
namespace Device.Proxy
{
    public class DeviceProxy : IDeviceService
    {
        public readonly IDeviceService _channel = null;

        private DeviceProxy()
        {
            // Channel factory stuffs here…
        }
    }

    private static DeviceProxy _instance = null;
    public static DeviceProxy Instance() => _instance ?? (_instance = new DeviceProxy());

    public ISessionBase CreateSession(UInt16 id)
    {
        ISessionBase a = _channel?.CreateSession(id);   // This line breaks
        return a;
    }
}    

编辑,添加例外详细信息:

  

服务器未提供有意义的回复;这可能是由于合同不匹配,会话过早关闭或服务器内部错误引起的。

Server stack trace:  
   at System.ServiceModel.Channels.CommunicationObject.ThrowIfFaulted()  
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)  
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)  
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:   
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)  
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)  
   at Device.ServiceContract.IDeviceService.CreateSession()  
   at Device.Proxy.DeviceProxy.CreateSession() in E:\...\Device.Proxy\DeviceProxy.cs:line 71  
   at Client1.Program.Main(String[] args) in E:\...\Client1\Program.cs:line 97  

1 个答案:

答案 0 :(得分:0)

我认为服务合同中的CreateSession需要更多地了解所支持的会话类型(必须使用ServiceKnownType)。如果没有完成,服务将无法知道如何序列化此类数据。

这里缺少什么:

namespace Device.ServiceContract
{
    [ServiceContract(Namespace = "http://Device.Service", CallbackContract = typeof(IDeviceServiceCallback))]
    public interface IDeviceService
    {
        [OperationContract]
        [ServiceKnownType(typeof(SessionBase))]
        ISessionBase CreateSession(Uin16 id);
    }
}