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。创建响应()?但它没有成功。

Visual Studio中的代码分析问题

阅读本文以了解"Dispose Pattern"。此外,阅读这篇文章,看看什么时候应该处理对象。在您的特定情况下,当调用方仍有对函数的引用时,将参数处理为函数看起来像是一种反模式

为了解决您收到的警告,requestMessage.CreateErrorResponse(...)创建了一个实现IDisposableHttpResponseMessage。在方法返回之前,这已经超出了范围(因为没有对其进行引用)。这意味着代码分析工具看到该对象上的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需要允许这种处理模式。