2015-09-15 34 views
3

我僅在生產環境中發生了一個非常奇怪的問題。 有個例外僅在生產環境中拋出MulticastDelegate異常

「委託給一個實例方法不能有'this'」。

在異常被拋出非常簡單,而且很長一段時間的工作方法,使 這個問題必須在環境中一個不起眼的依賴,或類似的東西...

我使用Azure託管的ASP.NET Web API,並通過AJAX執行控制器的操作方法。

這裏就是拋出異常的代碼:

public class BlacklistService : IBlacklistService 
{ 
    public bool Verify(string blacklist, string message) 
    { 
     if (string.IsNullOrEmpty(blacklist)) return true; 
     var split = blacklist.ToLower().Split(';'); // exception is thrown here 
     return !split.Any(message.Contains); 
    } 
} 

這裏是堆棧跟蹤的相關部分:

at System.MulticastDelegate.ThrowNullThisInDelegateToInstance() 
at System.MulticastDelegate.CtorClosed(Object target, IntPtr methodPtr) 
at MyApp.Business.Services.BlacklistService.Verify(String blacklist, String message) 
at MyApp.Business.Services.ContactMessageFactory.GetVerifiedStatus(String mensagem) 
at MyApp.Business.Services.ContactMessageFactory.GetMailMessage(ContactForm contactForm) 
at MyApp.Business.ContactEmailService.Send(ContactForm contactForm) 

有人能弄清楚這個異常的可能原因是什麼?提前致謝。

+1

請您分享您調用驗證方法的委託部分的代碼嗎? –

回答

4

的事實,實際上messagenull問題奠定。您可以複製這個很容易:

void Main() 
{ 
    Verify("hello", null); 
} 

public bool Verify(string blacklist, string message) 
{ 
    if (string.IsNullOrEmpty(blacklist)) return true; 
    var split = blacklist.ToLower().Split(';'); // exception is thrown here 
    return !split.Any(message.Contains); 
} 

會發生什麼事是message.Contains傳遞給通過該方法組轉換Func<string, bool>構造,它看起來像這樣:

Func<string, bool> func = ((string)null).Contains; 
return !split.Any(func); 

這是什麼原因造成MulticastDelegate去香蕉。你也可以看到,在生成的IL:

IL_0028: ldftn  System.String.Contains 
IL_002E: newobj  System.Func<System.String,System.Boolean>..ctor 
IL_0033: call  System.Linq.Enumerable.Any 

爲了使這種不發生,一定要空檢查的訊息:

public bool Verify(string blacklist, string message) 
{ 
    if (string.IsNullOrEmpty(blacklist)) return true; 
    if (string.IsNullOrEmpty(message)) return false; 

    var split = blacklist.ToLower().Split(';'); // exception is thrown here 
    return !split.Any(message.Contains); 
} 
+0

正確。異常類型讓我困惑。我錯過了方法組中的委託,並期待NullReferenceException。謝謝。 –

+1

爲了澄清這個錯誤,我發現在本地環境中,blacklist參數由於配置而爲空,所以代碼返回true並且工作。 –

+0

@Leonardo很高興解決。 –

1

當消息爲空時失敗。可以使用此

return !split.Any(part => (message != null && message.Contains(part))); 
+2

OP代碼中使用的表單是您發佈的代碼的快捷方式,因此它基本相同。 – jgg99

+0

@ jgg99正確!我的不好,謝謝你指出。編輯。 –

+0

這只是表達同樣事物的另一種語法。我使用了方法組語法而不是lambda。 –

2

具有空this委託是方法string.Contains()用於最後,它使用您的message變量作爲this指針。換句話說,在message爲空的地方有一個呼叫。

+0

正確。異常類型讓我困惑。我錯過了方法組中的委託,並期待NullReferenceException。 –