WCF错误类型无法在服务打开的情况下注册

本文关键字:情况下 注册 服务 错误 类型 WCF | 更新日期: 2023-09-27 18:28:36

目前,我们有一个应用程序,它有一个公开WCF REST服务的服务器应用程序,然后我们有与服务器上的WCF REST服务通信的客户端。目前,我在客户端遇到了一个我无法解决的错误,在谷歌上找不到答案也没有运气。

一旦我从ChannelFactory调用以创建通道,就会引发以下异常。有人知道这个错误意味着什么吗?我在哪里可以找到可以帮助我解决问题的东西?下面也是我们用于从客户端调用服务的通用方法。Fiddler没有表现出任何来自客户的沟通,所以问题直接出在客户身上。服务器和客户端共享相同的通信接口。

    System.InvalidOperationException was caught
  HResult=-2146233079
  Message=New types cannot be registered with serializer manager after the service has been opened.
  Source=System.ServiceModel.Web
  StackTrace:
       at System.ServiceModel.Dispatcher.UnwrappedTypesXmlSerializerManager.RegisterType(Object key, IList`1 types)
       at System.ServiceModel.Dispatcher.SingleBodyParameterXmlSerializerMessageFormatter..ctor(OperationDescription operation, Type parameterType, Boolean isRequestFormatter, XmlSerializerOperationBehavior xsob, UnwrappedTypesXmlSerializerManager serializerManager)
       at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.CreateXmlFormatter(OperationDescription operation, Type type, Boolean isRequestFormatter, UnwrappedTypesXmlSerializerManager xmlSerializerManager)
       at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.CreateClientFormatter(OperationDescription operation, Type type, Boolean isRequestFormatter, Boolean useJson, UnwrappedTypesXmlSerializerManager xmlSerializerManager)
       at System.ServiceModel.Description.WebHttpBehavior.<>c__DisplayClass7.<>c__DisplayClassa.<GetRequestClientFormatter>b__4()
       at System.ServiceModel.Description.WebHttpBehavior.<>c__DisplayClass7.<GetRequestClientFormatter>b__3()
       at System.ServiceModel.Description.WebHttpBehavior.HideReplyMessage(OperationDescription operationDescription, Effect effect)
       at System.ServiceModel.Description.WebHttpBehavior.GetRequestClientFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
       at System.ServiceModel.Description.WebHttpBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
       at System.ServiceModel.Description.DispatcherBuilder.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
       at System.ServiceModel.Description.DispatcherBuilder.BuildProxyBehavior(ServiceEndpoint serviceEndpoint, BindingParameterCollection& parameters)
       at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose)
       at System.ServiceModel.ChannelFactory.CreateFactory()
       at System.ServiceModel.ChannelFactory.OnOpening()
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open()
       at System.ServiceModel.ChannelFactory.EnsureOpened()
       at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via)
       at System.ServiceModel.ChannelFactory`1.CreateChannel()
       at Enterprise.ServiceModel.ChannelFactoryExtensions.ExecuteRequest[TChannel,TResult](ChannelFactory`1 factory, Func`2 readDelegate) in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Enterprise.Common'ServiceModel'ChannelFactoryExtensions.cs:line 115
       at Foo.Service.Client.FooDataMessenger.RetrieveAircraft() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Service.Client'Client'FooDataMessenger.cs:line 699
       at Foo.Service.Client.FooDataMessenger.<ReadAircraft>b__3() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Service.Client'Client'FooDataMessenger.cs:line 95
       at Enterprise.DelegateHelpers.ElapsedFunc[TOut](Func`1 actionDelegate, TOut& result) in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Enterprise.Common'Extensions'DelegateHelpers.cs:line 103
       at Enterprise.DelegateHelpers.ElapsedFuncTrace[TOut](Func`1 actionDelegate, String location, String method, String action) in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Enterprise.Common'Extensions'DelegateHelpers.cs:line 128
       at Foo.Service.Client.FooDataMessenger.ReadAircraft() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Service.Client'Client'FooDataMessenger.cs:line 91
       at Foo.Service.FooServiceClientData.ReadAircraft() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Service.Client'FooServiceClientData.cs:line 215
       at Foo.Config.Data.InternalDatumController.get_Aircraft() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Config.Data'InternalDatumController.cs:line 90
       at Foo.Config.Data.Sync.AircraftDefsSyncView.ReadData() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Config.Data'Sync'FooData'AircraftDefsSyncView.cs:line 81
       at Foo.Synchronization.Databases.Base.SyncProvider.ReadViewData(String viewName, Int32 batchCount) in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Synchronization'Databases'Base'SyncProvider.cs:line 88
       at Foo.Synchronization.Databases.Base.SyncOrchestrator.Synchronize() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Synchronization'Databases'Base'SyncOrchestrator.cs:line 114
       at Foo.Synchronization.Plugin.Synchronizer.Synchronize_FooData() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Synchronization.Plugin'Synchronizer.cs:line 201
       at Foo.Synchronization.Plugin.Synchronizer.Sync() in C:'Users'User 1'Desktop'Foo_TFS'Foo 5.1'Trunk'Foo.Synchronization.Plugin'Synchronizer.cs:line 91
  InnerException: 

通用方法

public static TResult ExecuteRequest<TChannel, TResult>(
                     this ChannelFactory<TChannel> factory,
                     Func<TChannel, TResult> readDelegate)
{
    if (factory == null || readDelegate == null)
    {
        return default(TResult);
    }
    TChannel channel = factory.CreateChannel();
#if DEBUG
    // Changes the timeout to 10 minutes so you can step through server
    // code if you need to without getting a timeout error.
    ((IClientChannel)channel).OperationTimeout = TimeSpan.FromMinutes(10);
#endif
    TResult result;
    try
    {
        result = readDelegate(channel);
    }
    finally
    {
        var client = (IClientChannel)channel;
        if (client.State == CommunicationState.Faulted)
        {
            client.Abort();
        }
        else
        {
            client.Close();
        }
        client.DisposeSafe();
    }
    return result;
}

WCF错误类型无法在服务打开的情况下注册

问题的解决方案在于发布的泛型方法。由于某种原因,因为try/finaly语句中只有正在执行的委托,所以finally从未被执行。该方法的修复方法是使用委托代码在try中移动close,然后在finally中处理通道。以下是经过更正的通用方法。

public static TResult ExecuteRequest<TChannel, TResult>(
                                                           this ChannelFactory<TChannel> factory,
                                                           Func<TChannel, TResult> readDelegate)
    {
        if (factory == null || readDelegate == null)
        {
            return default(TResult);
        }
        TChannel channel = factory.CreateChannel();
#if DEBUG
        // Changes the timeout to 10 minutes so you can step through server
        // code if you need to without getting a timeout error.
        ((IClientChannel)channel).OperationTimeout = TimeSpan.FromMinutes(10);
#endif
        TResult result;
        try
        {
            result = readDelegate(channel);
            var client = (IClientChannel)channel;
            CommunicationState state = client.State;
            if (state != CommunicationState.Faulted)
            {
                client.Close();
            }
            else
            {
                client.Abort();
            }
        }
        catch (Exception)
        {
            ((IClientChannel)channel).Abort();
            throw;
        }
        finally
        {
            ((IClientChannel)channel).DisposeSafe();
        }
        return result;
    }