Suppressing Code Analysis Rules

April 15, 2008 at 3:13 pm | Posted in Code Analysis, Visual Studio | Leave a comment

I’ve been using Code Analysis (FxCop) for a few months now and every now and then I come across a CA rule that I my solution violates. In 99% of situations, I comply to all the CA rules. In a previous post, I could not satisfy the CA1304 rule. Spelling checks is also another area where CA rules fail all the time.

The process that I use for checking in code to TFS ensures that Code Analysis is run before hand and that the project setting “Treat Warnings as Errors” is set to true. This means that the CA rules that I want to ignore fail my project build.

There are several ways to get around this:

1. Don’t use CA – not an option for me.
2. Don’t treat warnings as errors – not an option for me.
3. Apply a Suppression “In Source”- an option.
4. Apply a Suppression in “Project Suppression File (GlobalSuppression.cs) – an ideal option.

The last two options are my choice. Suppressing a CA rule places an attribute in code that informs FxCop to ignore the rule and therefore not raise a Warning or an Error.

Example Rule Failures

The following CA rules came up as Warnings for my solution. Both Suppress options are available. CA1304 gives two suppression options where as CA2210 (strong name key required) only allows a Project suppression because it is applied only at the assembly level. For a full list of the CA rules shipped with each version of VS/FxCop see this post.

image

In Source Suppression

When available, a CA rule can suppressed in the source code where the rule failed. Use the SuppressMessageAttribute to disable the CA rule.

[SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo",
MessageId = "System.ServiceModel.FaultReason.#ctor(System.String)")]
public void ProvideFault(Exception error,
MessageVersion version,
ref Message fault)
{
// Return a 'ServiceFault' Fault Contract
ServiceFault faultDetail = new ServiceFault("An error occured");

// Construct FaultException with Fault Contract and FaultReason
FaultException<ServiceFault> faultException =
new FaultException<ServiceFault>(faultDetail,
new FaultReason("FaultReasonText"));
}

The benefit of applying the rule override in the source, is that code reviewers can easily see where the attribute has been placed. An additional file is is not required. The disadvantages is that you must apply the the attribute for every rule failure even if they are the same failures across multiple operations in the same code file and multiple code files. It also dirties the code with an messy attributes.

Project Suppressions

When selecting the Project Supressions File option, the SuppressMessageAttribute is placed in the projects GlobalSuppressions.cs file – Visual Studio will create one automatically. The attribute has overrides which allows you to target the exact place of the rule failure such as a class, method, field, namespace etc.

In my example, I have suppressed botth CA2210 and CA1304 rules in the GlobalSuppressions.cs. Visual Studio generates the code.

// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
//
// To add a suppression to this file, right-click the message in the
// Error List, point to "Suppress Message(s)", and click
// "In Project Suppression File".
// You do not need to add suppressions to this file manually.

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage(
"Microsoft.Design",
"CA2210:AssembliesShouldHaveValidStrongNames")]

[assembly:
SuppressMessage(
"Microsoft.Globalization", "CA1304:SpecifyCultureInfo",
MessageId = "System.ServiceModel.FaultReason.#ctor(System.String)",
Scope = "member",
Target = "Wcf.Demo.Service.ErrorHandler.#ProvideFault(System.Exception,System.ServiceModel.Channels.MessageVersion,System.ServiceModel.Channels.Message&)"
)]

Notice the the CA1304 suppression contains Scope and Target properties. This can be changed so that the suppression is scoped to a wider code base such a a namespace.

The benefits of project suppressions is cleaner code, less duplication of the SuppressMessage attribute and easier to remove if failure is fixed. It’s also easier to code review as all failure overrides are in the one place. The only disadvantage that I can see is that there is an additional code file.

My preference is to always use project suppressions. In the near future , I will discuss some of the processes of how I use Code Analysis.

Advertisements

CA1304 – Must specify CultureInfo when using FaultReason

April 9, 2008 at 12:36 pm | Posted in Code Analysis, Visual Studio, WCF | 1 Comment

Today I came across the following issue when running Code Analysis over my WCF Error Shielding solution.

CAError

Because I have “Treat Warnings as Errors” enabled for all projects, Code Analysis fails.

Rory Primrose has recently blogged a very nice Error Handling solution which have implemented in a WCF service. As soon as I implemented the solution and specified to return a custom Fault Contract, WCF returned an exception indicating that the “FaultReason” was not provided. So I constructed a new FaultReason, and passed it in to the FaultException(Fault, FaultReason).

The FaultReason class contains a set of System.ServiceModel..::.FaultReasonText objects, each of which contains a description of the fault in a specific language.

Sample

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)

{

// Return a ‘ServiceFault’ Fault Contract

ServiceFault faultDetail = new ServiceFault(“An error occured”);


// Construct FaultException with FaultContract and FaultReason

FaultException<ServiceFault> faultException =

new FaultException<ServiceFault>(faultDetail, new FaultReason(“FaultReasonText”));


MessageFault
messageFault = faultException.CreateMessageFault();

fault = Message.CreateMessage(version, messageFault, faultException.Action);

}

I compiled the code in Debug which was successful. I then switched on Code Analysis and it raised CA1304 : Microsoft.Globalization. The Code Analysis rule made sense to ensure I was using CultureInfo for the reason text.

However, the FaultReason does not provide any ‘public‘ constructor overrides to accept the CultureInfo. It does however provide an internal FaultReason(string text, CultureInfo cultureInfo) constructor.

FaultReason

After the help of Rory who confirmed with David Kean from the Code Analysis Team that this was a bug, I submitted feedback to Microsoft Connect.

You can keep track of this bug here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=337431&wa=wsignin1.0

In the meantime, I have suppressed this CA rule in my GlobalSupressions.cs for the project.

Blog at WordPress.com.
Entries and comments feeds.