What exception should be thrown when a mandatory property of a parameter object is null


I use parameter objects to encapsulate the parameters that are passed to my business rules. The rule is created using a context parameter, which may then be modified, then at a later time the rule is executed. Some of the properties of this object are required, otherwise the method would throw a NullReferenceException. However, if I throw an ArgumentNullException, I get a warning saying that the parameter name does not match one of my parameters. What would be the appropriate exception for this situation?

public class GetAttributes : BusinessRuleBase
    private readonly IGetAttributesContext _context;

    public GetAttributes(IGetAttributesContext context)
        _context = context;

    public override void Execute()
        if (_context.AttributeModel == null)
            //Exception would be thrown here
        _context.Attributes = _context.AttributeModel

If you are using Code Contracts and you are willing to publicly expose a HasAttributeModel property, I recommend


Otherwise, you should throw a custom exception that derives from InvalidOperationException here. The method that you are trying to execute is not valid given the object's current state. From the documentation:

The exception that is thrown when a method call is invalid for the object's current state.

Your custom message should say that the instance's AttributeModel is null.

The larger question is, why are you allowing your instances to be in a state where a method could be invoked on them while the object is in an invalid state? You should avoid this, if you can. For example, why isn't GetAttributes checking that context.AttributeModel is not null? You could have

Contract.Requires(context.AttributeModel != null);

as a precondition for this method. However, there is some danger here in that if someone retains a live reference to the referrent of the parameter context, they could destroy the state since you maintain a reference via the private variable _context. Be aware of this, and avoid it if you can.