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;
}
问题的解决方案在于发布的泛型方法。由于某种原因,因为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;
}