How to Add a Rule to a Best Practice Analyzer Rules File
Date: October 20, 2006
The Microsoft Best Practice Analyzer Engine (MSBPA) is a general-purpose framework that enables the programmatic scanning of particular values inside of objects (e.g., the Windows Registry, XML Files, etc.) and evaluates those values against predefined rules.
If a given rule is evaluated as “true”, engine will display a warning and text as defined in the rules file, notifying the user of the violation of that particular rule.
The one of the biggest strengths of the MSBPA is the ability to quickly and easily add additional rules to a given rule document. A rule is described in a simple XML file that can be located in the “\plugins” directory under the BPA engine directory. The name
of the file will be in the format “<name of analysis plugin>.config.xml”. In the document below, the process for adding a new rule to a preexisting rules document will be described.
Understanding the Rules File Structure
Before we start writing a new rule, it is useful to familiarize yourself with the structure of an XML rules file. To view an example rules file, please download and install the Best Practices Analyzer tool, and open the AspDotNetAnalyzer.config.xml file, which
will be found in the \plugins folder of the main installation directory for the BPA tool (usually %Program Files%\Power Toys for Visual Studio\Best Practices Analyzer\)
The first section in the XML that you will encounter is the configuration section. In the configuration section, the main properties about the rules file are defined, such as what kinds of files or data the analyzer needs to be able to read, the different restrictions
that will be available in the UI, and the definition of all of the inputs that the user must submit to run a scan. For the purpose of just adding a new rule, it is unlikely that you will need to make any changes to this section.
Substitution Rules – What Property are you Trying to Read?
Below the configuration section, a list of substitutions can be defined. The easiest way to think of a substitution is like a variable—you’re defining a shorter, convenient name for something so you can reference it later. Below is an example of a substitution
for a given node in an XML document:
<Setting Key1="XmlProp" Key2="configuration/system.web/pages/@autoEventWireup" Substitution="auto" >
<Rule Name="sWebConfigAutoEventWireup" Query="$." />
Let’s step through the elements in the substitution above step-by-step. A “Setting” node shows that you want to define a substitution. “Key1” and “Key2” elements’ meanings are defined by the object processor associated with the parent “object” of the substitutions.
There are several different object processors, but quite likely the easiest way to determine how to add a new substitution is to look at the rules around it and emulate their style. The “substitution” element defines the name of your substitution—basically,
how do you want to reference this setting later on in the rules file? Finally, the “Rule Name” defines both a name for the substitution rule (all substitution rule names must start with a lower-case “s”) and an XPath “query” that will be evaluated against
the data defined earlier in the substitution. In the example above, the query “$.” will return the value of the property in the XML at the path “configuration/system.web/pages/@autoEventWireup”.
Rules – What Value Should Trigger a Warning?
Now that we have defined a substitution, we need to create an actual BPA rule that will trigger when a scan occurs. To do this, we need to define another rule. Once again, the best way to add an additional rule to the rules document is to emulate a preexisting
rule that exists to evaluate a similar element. Below is a rule that uses the substitution defined above:
<Rule Name="fWebConfigAutoEventWireup" Query="matches('true',lower-case('%auto%'))" Error="Warning" Title="Auto Event Wireup is enabled" Text="It is suggested that Auto Event Wireup be disabled
to enhance performance and increase security."/>
The rule name corresponds with the substitution rule above, but instead of an “s” rule, you can see that we are defining an “f” rule. The most important part of a rule is the query. The query is an XPath expression. Whenever the evaluation of the query returns
a Boolean value of “true”, the rule will be triggered. The “error” property defines the severity of your rule—it can be an “error”, a “warning”, or a “best practice”. The “title” is the heading that will be displayed in the error message in the BPA tool, along
with the “text” that describes what the error is and why the rule was triggered.
Save and Contribute!
Once you have made your changes, go ahead and save the XML rules file, run the BPA tool, and see if your changes worked. It is suggested that you save the original XML rules file in a safe location first, in case you need to revert to it in the future. If your
rule isn’t working, the first thing to check is to go back into the XML that you wrote and study both the form (make sure you have all of your carrots and quotation marks closed) and the XPath function that you are using. Does it evaluate to true? If not,
you shouldn’t see the rule.
If you successfully made the change, and you think that your rule is a good one, share it back to the community and have everybody check out and benefit from your work. Currently, while the application is in beta, the best place to share your new rules is on
the CodePlex discussions for the Best Practices Analyzer (just click on the Discussions tab above and go to the "New Rule Suggestions" discussion board.)
Want to know more? Read up on these more advanced documents, which will give you more detailed guidance on writing rules for the Best Practices Analyzer:
BPA Rules XML Schema and Reference Help File
BPA Advanced Rules Tutorial