2013-09-27 199 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

我對此一無所知,但我認爲您需要爲每個客戶端調用創建一個新的作用域並設置標題,而不是在創建客戶端時創建一次。 –