Исключение 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)));