Исключение MulticastDelegate вызывается только в производственной среде

У меня очень странная проблема, возникающая только в производственной среде. Исключение имеет сообщение

Msgstr "Делегировать метод экземпляра не может иметь значение" this "".

Метод, в котором генерируется исключение, очень прост и работает в течение длительного времени, поэтому проблема должна заключаться в неясной зависимости в среде или чем-то в этом роде...

Я использую ASP.NET Web API, размещенный в Azure, и метод действия контроллера выполняется через 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)

Кто-то может выяснить возможные причины этого исключения? Заранее спасибо.

3 ответа

Решение

Проблема заключается в том, что message на самом деле null, Вы можете воспроизвести это довольно легко:

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

Делегат, имеющий ноль this это метод string.Contains() используется к концу, который использует ваш message переменная как this указатель. Другими словами, есть звонок, где message нулевой.

Сбой, когда сообщение пустое. Можно использовать это

return !split.Any(part => (message != null && message.Contains(part)));
Другие вопросы по тегам