gpt4 book ai didi

.net - 使用IErrorHandler和TCP消息安全性会导致超时

转载 作者:行者123 更新时间:2023-12-04 17:28:15 26 4
gpt4 key购买 nike

我有一个附带自定义IServiceBehavior的WCF服务,该服务用于在客户端返回特定的错误。当我使用TCP消息安全性启用此代码时,我会收到服务超时。

在下面,您可以看到完整的客户端和服务器代码以重现该错误。

服务器代码:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;
使用System.ServiceModel;
使用System.ServiceModel.Description;
使用System.ServiceModel.Dispatcher;
使用System.ServiceModel.Channels;

命名空间TestWCFServer
{
班级计划
{
静态void Main(string [] args)
{
Console.WriteLine(“ SERVER”);

NetTcpBinding绑定=新的NetTcpBinding();
binding.Security.Mode = SecurityMode.Message; //如果删除此行,则代码有效!

Uri地址=新的Uri(“ net.tcp:// localhost:8184 /”);

//创建ServiceHost。
使用(ServiceHost主机=新的ServiceHost(typeof(HelloWorldService)))
{
host.AddServiceEndpoint(typeof(IHelloWorldService),绑定,地址);

host.Description.Behaviors.Add(new MyErrorhandlerBehavior());

host.Open();

Console.WriteLine(“服务已准备就绪,位于地址{0}”);
Console.WriteLine(“ Press to stop the service。”);
Console.ReadLine();

//关闭ServiceHost。
host.Close();
}
}
}



[服务合约]
公共接口IHelloWorldService
{
[运营合同]
字符串SayHello(字符串名称);
}

公共类HelloWorldService:IHelloWorldService
{
公共字符串SayHello(字符串名称)
{
如果(名称==空)
抛出新的ArgumentNullException(“ name”);

返回string.Format(“ Hello,{0}”,名称);
}
}

class MyErrorhandlerBehavior:IServiceBehavior,IErrorHandler
{
#region IServiceBahvior
公共无效AddBindingParameters(ServiceDescription serviceDescription,ServiceHostBase,serviceHostBase,System.Collections.ObjectModel.Collection端点,BindingParameterCollection bindingParameters)
{
}

公共无效ApplyDispatchBehavior(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
{
foreach(serviceHostBase.ChannelDispatchers中的ChannelDispatcher chanDisp)
{
chanDisp.ErrorHandlers.Add(this);
}
}

公共无效Validate(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
{
}
#endregion

#region IErrorHandler成员
公共布尔HandleError(异常错误)
{
返回true;
}

公共无效ProvideFault(异常错误,MessageVersion ver,参考消息msg)
{
FaultException fe =新的FaultException(error.Message);
MessageFault故障= fe.CreateMessageFault();
msg = Message.CreateMessage(ver,fault,“ net.tcp:// localhost:8184 / fault”);
}
#endregion
}
}


客户代码:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;
使用System.ServiceModel;
使用System.ServiceModel.Channels;
使用System.ServiceModel.Description;
使用System.ServiceModel.Dispatcher;

命名空间TestWCFClient
{
班级计划
{
静态void Main(string [] args)
{
Console.WriteLine(“ CLIENT”);

尝试
{
NetTcpBinding绑定=新的NetTcpBinding();
binding.Security.Mode = SecurityMode.Message; //如果删除此行,则代码有效!

Uri地址=新的Uri(“ net.tcp:// localhost:8184 /”);
EndpointAddress端点=新的EndpointAddress(地址);

HelloWorldServiceClient客户端=新的HelloWorldServiceClient(绑定,端点);

Console.WriteLine(“正在使用有效参数调用客户端...”);
Console.WriteLine(client.SayHello(“ Davide”));
Console.WriteLine(“ OK”);

Console.WriteLine(“正在使用无效参数调用客户端...”);
Console.WriteLine(client.SayHello(null)); //当“安全性”设置为“消息”时,此调用导致超时
Console.WriteLine(“ OK”);
}
抓住(例外)
{
Console.WriteLine(ex.Message);
}


Console.WriteLine(“按Enter退出”);
Console.ReadLine();
}
}


[服务合约]
公共接口IHelloWorldService
{
[运营合同]
字符串SayHello(字符串名称);
}

类HelloWorldServiceClient:System.ServiceModel.ClientBase,IHelloWorldService
{
公共HelloWorldServiceClient(System.ServiceModel.Channels.Binding绑定,System.ServiceModel.EndpointAddress地址):
基地(装订,地址)
{}

公共字符串SayHello(字符串名称)
{
返回base.Channel.SayHello(name);
}
}
}


如果我删除了客户端和服务器上的binding.Security.Mode = SecurityMode.Message;行,则可以正确翻译该异常,并且客户端可以毫无问题地看到它。

在WCF日志上,我看到以下消息:
没有为带有'net.tcp:// localhost:8184 / fault'操作的消息指定签名消息部分。
安全协议无法保护传出消息。

关于如何解决此问题的任何想法?似乎我必须对错误消息进行签名/加密,但是我不知道如何...
如果我使用传输安全性,则代码将按预期工作。

谢谢!

最佳答案

响应可能有点晚,但是我遇到了同样的问题,并且发现了:

您需要在接口方法中与FaultContract一起定义OperationContract。看看here

同样,您的故障合同对象也需要具有与动作名称空间相同的名称空间。

Sooooooooooo很痛苦,但终于想通了,现在可以工作了。

关于.net - 使用IErrorHandler和TCP消息安全性会导致超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3650846/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com