我有2个项目,项目1有项目2的参考。
Project 1 正在使用带有代理类的简单服务引用来连接服务。为了能够在标头中发送用户名/密码,在此代理类上使用以下代码:
public static void Connect()
{
_Myclient = new MyService.MyIntegrationClient();
_Scope = new OperationContextScope(_Myclient.InnerChannel);
IntegrationHeader ih = new IntegrationHeader
{
UserName = Properties.Settings.Default.MyUserLogin,
Password = Properties.Settings.Default.MyUserPassword
};
MessageHeader untyped = MessageHeader.CreateHeader("SecurityToken", "ns", ih);
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
}
到目前为止一切顺利,运行没问题,可以在服务上阅读用户名/密码。
项目2 正在使用channelFactory来连接到同一服务。创建频道和添加messageheader的代码如下所示:
public static IMyIntegration GetMyFactory(string userName, string password)
{
IMyIntegration client;
OperationContextScope operationContextScope;
IntegrationHeader integrationHeader;
ConfigurationChannelFactory<IMyIntegration> factory;
MessageHeader messageHeader;
integrationHeader = new IntegrationHeader { UserName = userName, Password = password };
messageHeader = MessageHeader.CreateHeader("SecurityToken", "ns", integrationHeader);
factory = new ConfigurationChannelFactory<IMyIntegration>("BasicHttpBinding_IMyIntegration", ConfigHelper.MyConfiguration, null);
client = factory.CreateChannel();
operationContextScope = new OperationContextScope((IClientChannel)client);
if (OperationContext.Current.OutgoingMessageHeaders.Count < 1)
OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);
return client;
}
这就是IntegrationHeader的样子:
[DataContract()]
public class IntegrationHeader
{
[DataMember]
public string UserName;
[DataMember]
public string Password;
}
项目1 将首先在项目2 中运行一个方法,该方法将(使用上面的代码)连接到服务上的服务方法。完成此操作后,项目1 也会建立与同一服务的连接,但使用此帖子中的第一个代码。
到目前为止一切顺利,没问题。
问题 然后再次触发两个服务方法(第二次),但这次不需要上面的代码,因为它已经在prev循环上完成,所以这次我们直接执行服务方法请求而不创建任何代理类或channelFactories。
结果是第二次在服务上丢失了已发送消息的标题?
如果我删除项目1 (带有代理的服务)进行的服务调用,那么会没有问题吗?
修改1:
如果我只运行 Project 1 所做的服务调用,那么它会正常工作,如果我只运行 Project 2 的服务调用,它也会工作得很好。问题在于进行Project 2调用,Project 1调用,然后再次回到Project 2调用。
如果我以相反的方式运行它,项目1 ,项目2 然后项目1 ,它也将在同样的问题上失败(第三个项目1电话)?
编辑2:
我在两种情况下都使用OperationContext.Current.OutgoingMessageHeaders,它只在每个项目的第一次调用时设置,也许是在使用相同的上下文?
答案 0 :(得分:0)
我的猜测是,在第二次通话时(暂停一分钟后),操作处理OperationContextScope。
这将导致OperationContext.Current在创建范围之前返回操作上下文的前一个实例,该实例不包含任何标头。
解决此问题的方法是将OpertationContextScope初始化移出工厂方法:
var client = GetMyFactory("username", "password);
using (operationContextScope = new OperationContextScope((IClientChannel)client))
{
OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);
client.DoSomething()
....
}
来自MSDN:
创建OperationContextScope时,当前的OperationContext 存储,新的OperationContext成为由。返回的 目前的财产。当处理OperationContextScope时, 原始的OperationContext已恢复。