Visual Studio中的代码分析问题
本文关键字:问题 代码 Studio Visual | 更新日期: 2023-09-27 18:00:46
请找到以下代码:
private static void HandleValidationError(ILogger logger, HttpRequestMessage requestMessage, HttpStatusCode statusCode, string message)
{
logger.LogError(LoggingSources.API, message);
throw new HttpResponseException(requestMessage.CreateErrorResponse(statusCode, message));
}
}
我得到以下CA问题:
CA2000在丢失作用域之前处置对象In方法'ControllerHelper。HandleValidationError(ILogger,HttpRequestMessage,HttpStatusCode,string)',对象'HttpRequestMessageExtensions。CreateErrorResponse(requestMessage,statusCode,message)'未沿所有异常路径进行处理。呼叫系统IDisposable。对对象进行处置'HttpRequestMessageExtensions。CreateErrorResponse(requestMessage,statusCode,message)',然后所有对它的引用都已超出范围任务。应用网状物API控制器帮助器.cs 106
上述函数的调用方是:
public static void CheckForValidDelimitedIntegerInput(ILogger logger, HttpRequestMessage request, char delimiter, string input)
{
if (!string.IsNullOrEmpty(input))
{
try
{
string[] idList = input.Split(delimiter);
for (int i = 0; i < idList.Length; i++)
{
int result;
if (!int.TryParse(idList[i], out result) || result <= 0)
{
HandleValidationError(logger, request, HttpStatusCode.BadRequest, InvalidIntegerOrShort);
}
}
}
catch (HttpResponseException)
{
throw;
}
}
else
{
HandleValidationError(logger, request, HttpStatusCode.BadRequest, InvalidParameter);
}
}
我尝试了stackoverflow之前的帖子Do I need to dispose a HttpResponseException from Request。创建响应()?但它没有成功。
阅读本文以了解"Dispose Pattern"。此外,阅读这篇文章,看看什么时候应该处理对象。在您的特定情况下,当调用方仍有对函数的引用时,将参数处理为函数看起来像是一种反模式
为了解决您收到的警告,requestMessage.CreateErrorResponse(...)
创建了一个实现IDisposable
的HttpResponseMessage
。在方法返回之前,这已经超出了范围(因为没有对其进行引用)。这意味着代码分析工具看到该对象上的Dispose
从未被调用。
编辑:
要解决此问题,只需删除using
指令,并按如下方式简化代码。
private static void HandleValidationError(ILogger logger, HttpRequestMessage requestMessage, HttpStatusCode statusCode, string message)
{
logger.LogError(LoggingSources.API, message);
throw new HttpResponseException(requestMessage.CreateErrorResponse(statusCode, message));
}
这似乎对我有效。不过,这将把处理对象留给调用者。
编辑:
啊哈!我发现了这个堆栈溢出的帖子,这似乎正是你的问题。为了完整性,它基本上说您不需要处理HttpResponseMessage
对象。但是,如果您使用构造函数,则已经抑制了此警告,因此您不需要自己抑制它。
试试这个:
private static void HandleValidationError(ILogger logger, HttpRequestMessage requestMessage, HttpStatusCode statusCode, string message)
{
logger.LogError(LoggingSources.API, message);
throw new HttpResponseException(new HttpResponseMessage(statusCode){
ReasonPhrase = message
});
}
注意:因为我无法重现这个问题,所以我无法测试以确保它有效。
经过一些分析,我终于找到了答案。
private static void HandleValidationError(ILogger logger, HttpRequestMessage requestMessage, HttpStatusCode statusCode, string message)
{
logger.LogError(LoggingSources.API, message);
using (var errorResponse = requestMessage.CreateErrorResponse(statusCode, message))
{
throw new HttpResponseException(errorResponse);
}
}
这将解决CA问题。我还要感谢约翰的帮助。
使用using
会导致500内部服务器错误。
我的解决方案是RegisterForDispose
,所以它变成了:
var errorResponse = requestMessage.CreateErrorResponse(statusCode, message));
this.request.RegisterForDispose(errorResponse);
throw new HttpResponseException(errorResponse);
您仍然需要抑制CA2000警告,但我相信这是正确的处理方式,因此CA2000需要允许这种处理模式。