2015-07-02 36 views
1

请找到下面的代码:代码分析问题

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问题:

损失范围在方法 “ControllerHelper.HandleValidationError前

CA2000释放对象( ILogger,HttpRequestMessage, HttpStatusCode,string)',对象 'HttpRequestMessageExtensions.CreateErrorResponse(requestMessage, statusCode,message)'没有沿着所有异常路径设置。调用 System.IDisposable.Dispose在对象 'HttpRequestMessageExtensions.CreateErrorResponse(requestMessage, statusCode,message)'之前的所有引用都不在 范围内。 Tasks.Application.Web.API ControllerHelper.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); 
      } 
     } 

我试过计算器早些时候发布Do I need to dispose an HttpResponseException from Request.CreateResponse()?但它没有发挥出来。

+2

你不需要在'finally'块中调用Dispose。它被包裹在一个'使用'中,它会被丢弃。 – Jonesopolis

+0

是的,我知道。但是我仍然遇到同样的CA问题。 – Varun

+2

你确定要在方法中处理'requestMessage'吗?它正在通过;调用方法不应该处理生命周期吗? –

回答

0

最后经过一些分析,我找到了答案。

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问题。我也想感谢约翰的帮助。

+2

以后处理他的异常时,你是否仍然可以访问'errorResponse'?如果是这种情况,那么当它尝试访问已处理的对象时,可能会引发异常。 –

+1

嗯,但这种情况下,我不会在这里适用。 – Varun

1

阅读this article了解“配置模式”。此外,请阅读this post以查看何时应处理对象。在你的特定情况下,它看起来像一个anti-pattern为一个函数处置一个参数,当调用者仍然有一个参考。

为了解决您收到的警告,requestMessage.CreateErrorResponse(...)创建了一个HttpResponseMessage,它实现了IDisposable。在方法返回之前,这是超出范围的(因为没有引用它)。这意味着代码分析工具看到这个对象上的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)); 
} 

这似乎适用于我。尽管如此,这将留下将对象配置给调用者。

编辑:

啊哈!我发现这个stack overflow post这似乎是你的确切问题。为了完整性,它基本上说你不需要处理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 
    }); 
} 

注:因为我不能重现这个问题我无法进行测试,以确保此工作。

+0

谢谢你的回复。是否有任何其他解决方案,而不是在Suppression文件中抑制此错误? – Varun

+0

它不工作。我使用呼叫者功能更新了问题。如果您有任何问题,请告知我 – Varun

+0

您是否收到与以前相同的代码分析错误? –

1

使用using会导致500内部服务器错误。

我的解决办法是RegisterForDispose所以它变成了:

var errorResponse = requestMessage.CreateErrorResponse(statusCode, message)); 
this.request.RegisterForDispose(errorResponse); 
throw new HttpResponseException(errorResponse); 

您仍需要压制CA2000警告,但我相信这是处置方法得当,所以CA2000需要允许本Dispose模式。