我有一个非常奇怪的问题,只发生在生产环境中。 该例外有消息
"委托实例方法不能为空''"。
抛出异常的方法非常简单,并且工作了很长时间,所以 问题必须是环境中的模糊依赖,或类似的东西......
我使用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)
有人可以找出导致此异常的可能原因吗?提前谢谢。
答案 0 :(得分:4)
问题在于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);
}
答案 1 :(得分:2)
具有空this
的委托是用于结尾的方法string.Contains()
,它使用您的message
变量作为this
指针。换句话说,在message
为空的情况下进行了调用。
答案 2 :(得分:1)
失败。可以用这个
return !split.Any(part => (message != null && message.Contains(part)));