2013-09-27 40 views
1

我有2个项目,项目1有一个参考项目2MessageHeader第二次通话失败?

项目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); 
} 

到目前为止好,没有问题,运行和usernamen /密码,可以在服务被读取。

项目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也将连接到相同的服务,但与本文中的第一个代码。

到目前为止好,没问题。

问题 两种服务方式,然后再次触发(第二次),但这次不需要上面的代码,因为它已经在上一个循环中完成,所以这个时候我们直接做服务方法请求而不创建任何代理类或通道函数。

结果是发送的邮件上的标题在服务上第二次缺失?

如果我删除了项目1(带代理的那个)所做的服务调用,那么会不会有问题?

编辑1:

如果我只运行服务调用项目1没有那么它会工作得很好,如果我只运行服务调用项目2确实它也将工作正常。问题是在执行Project 2调用时,Project 1调用,然后再次返回到Project 2调用。

如果我运行它周围的其他方法,项目1项目2然后项目1再次它也将失败同样的问题(第三个项目1个呼叫)?

编辑2:

我使用在这两种情况下OperationContext.Current.OutgoingMessageHeaders,它是只设置在第一次调用每个项目,也许禅师都使用相同的背景?

+0

当GetMyFactory结束它超出范围并且没有人引用它时,可能OperationContextScope正在被GC回收。这可以解释为什么中间调用可以工作,但是1分钟后(或者在GC退出范围引用之后立即失败)。 – jlvaquero

+0

嗨,你可能是对的,我已经更新我的文章,并解释它好一点。如果OperationContextScope是问题,我应该如何处理?我像这样decleared:private static OperationContextScope _Scope;所以它不应该被处置? – Banshee

+0

我不认为问题出在GetMyFactory中,问题可能出现在项目1的Connect方法中。 – Banshee

回答

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成为 Current属性返回的那个。当OperationContextScope被丢弃时, 原始的OperationContext被恢复。

+0

我已经运行了一些更多的测试,如您在编辑帖子中看到的那样。即使没有恶意,也会丢失标题。因此,如果我再次运行Project1,Project2和Project1,那么Project1的调用将会丢失heder。如果反而运行Project2,Project1和Project1再次显示相同的问题?第一次运行项目服务调用时,它将被立即执行。所以我的猜测是,第二次服务电话将清除第一次服务电话设置的设置。但是,当他们处于不同的项目中时,这是可能的,而且渠道是以不同的方式创建的,我不明白。 – Banshee

+0

我在这两种情况下使用OperationContext.Current.OutgoingMessageHeaders,也许它们实际上使用相同的上下文,这就是为什么它第三次失败? – Banshee

+0

我对此一无所知,但我认为您需要为每个客户端调用创建一个新的作用域并设置标题,而不是在创建客户端时创建一次。 –