This is the online documentation for PostSharp 4.3.
Download PDF or CHM. Go to v4.3 or v5.0
Localizing Contract Errors

You can customize all texts of exceptions raised by built-in contract. This allows you to localize error messages into different languages.

Contracts use the ContractLocalizedTextProvider class to obtain the text of an error message. This class follows a simple chain of responsibilities pattern where each provider has a reference to the next provider in the chain. When a message is queried, the provider either returns a message or passes control to the next provider in the chain.

Each message is identified by a string identifier and can refer to 4 basic arguments and additional arguments specific to a message type. For general information about message arguments please see remarks section of LocationContractAttribute. For identifier of a particular message and its additional arguments, please see remarks section of contract classes in PostSharp.Patterns.Contracts.

This topic contains the following sections:

Localizing a built-in error message

Following steps illustrate how to override an error message of a given contract:

To override a contract error message:

  1. Declare a class that derives from ContractLocalizedTextProvider and implement the chain constructor.

    C#
    public class CzechContractLocalizedTextProvider : ContractLocalizedTextProvider
    {
        public CzechContractLocalizedTextProvider(ContractLocalizedTextProvider next)
          : base(next)
        {
        }
    
    }
  2. Implement the GetMessage(String) method. In the next code snippet, we show how to build a simple and efficient dictionary-based implementation.

    C#
    public class CzechContractLocalizedTextProvider : ContractLocalizedTextProvider
    {
          private readonly Dictionary<string, string> messages = new Dictionary<string, string>
                                        {
                                            {RegularExpressionErrorMessage, "Hodnota {2} neodpovídá regulárnímu výrazu '{4}'."},
                                        };
    
        public CzechContractLocalizedTextProvider(ContractLocalizedTextProvider next)
          : base(next)
        {
        }
    
        public override string GetMessage( string messageId )
        {
            if ( string.IsNullOrEmpty( messageId ))
                throw new ArgumentNullException("messageId");
    
            string message;
            if ( this.messages.TryGetValue( messageId, out message ) )
            {
                return message;
            }
            else
            {
                // Fall back to the default provider.
                return base.GetMessage( messageId );
            }
        }
    }
    Note Note

    If you need to support several languages, you can make your implementation of the GetMessage(String) method dependent on the value of the CultureInfo.CurrentCulture property. You can optionally store your error messages in a managed resource and use the ResourceManager class to access it and manage localization issues. The design of PostSharp Code Contracts is agnostic to these decisions.

  3. In the beginning of an application, create a new instance of the provider and set the current provider as it's successor.

    C#
    public static void Main()
    {
        ContractLocalizedTextProvider.Current = new CzechContractLocalizedTextProvider(ContractLocalizedTextProvider.Current);
    
        // ...
    }
Localizing custom contracts

Once you have configured a text provider, you can use it to localize error messages of custom contracts. In the following procedure, we will localize the error message of the example contract described in Creating Custom Contracts.

To localize a custom contract:

  1. Edit the code contract class (NonZeroAttribute in our case) and replace the implementation of the GetErrorMessage() method by a call to the GetMessage(String) method. Pass a unique message identifier to this method.

    protected override string GetErrorMessage()
     {
         return ContractLocalizedTextProvider.Current.GetMessage("NonZeroErrorMessage");
     }
  2. Edit your implementation of the LocalizedTextProvider class and include the message for your custom contract:

    C#
    private readonly Dictionary<string, string> messages = new Dictionary<string, string>
      {
         {RegularExpressionErrorMessage, "Hodnota {2} neodpovídá regulárnímu výrazu '{4}'."},
         {"NonZeroErrorMessage", "Value {2} must have a non-zero value."}
      };