2

SonarCube shows me error "Update this implementation of 'ISerializable' to conform to the recommended serialization pattern" for the following exception implementation:

[Serializable]
public class UnrecoverableException : Exception, ISerializable
{
    public bool Ignore { get; }

    public UnrecoverableException()
    {
    }

    public UnrecoverableException(string message, Exception innerException)
        : base(message, innerException)
    {
    }

    protected UnrecoverableException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        Ignore= info.GetBoolean(nameof(Ignore));
    }

    public UnrecoverableException(string message, bool ignore= false) : base(message)
    {
        Ignore= ignore;
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(nameof(Ignore), Ignore);
        base.GetObjectData(info, context);
    }
}

not sure what's wrong here as to me it seems totally following rules described here https://rules.sonarsource.com/csharp/tag/pitfall/RSPEC-3925

This rules raises an issue on types that implement ISerializable without following the serialization pattern recommended by Microsoft.

  • The System.SerializableAttribute attribute is missing.

  • Non-serializable fields are not marked with the System.NonSerializedAttribute attribute.

  • There is no serialization constructor.

  • An unsealed type has a serialization constructor that is not protected.

  • A sealed type has a serialization constructor that is not private.

  • An unsealed type has a ISerializable.GetObjectData that is not both public and virtual.

  • A derived type has a serialization constructor that does not call the base constructor.

  • A derived type has a ISerializable.GetObjectData method that does not call the base method.

  • A derived type has serializable fields but the ISerializable.GetObjectData method is not overridden.

YMC
  • 4,243
  • 7
  • 44
  • 66
  • 3
    I think the problem might be with this "An unsealed type has a serialization constructor that is not protected" condition. However what if I need throw this type of exception directly and hove other exceptions derived from it – YMC Feb 20 '20 at 02:23
  • I think it doesn't like the backing field for the auto-property. I bet it isn't decorated with a serialization attribute. What happens if you remove the property, or change it to one with an explicit backing field decorated per the rules? –  Feb 20 '20 at 02:27
  • issue was with protected vs public member indeed – YMC Feb 20 '20 at 15:36
  • Cool, you figured it out? I'm interested in what the answer is. –  Feb 20 '20 at 15:38
  • I just made 2 separate exception classes derived from it instead of using 1 parent and 1 derived class, and made constructors protected – YMC Feb 20 '20 at 18:08
  • 1
    You can answer your own question below, you know? –  Feb 20 '20 at 18:49

1 Answers1

2

All I had to do to pass Sonarqube's analysis was add the [Serializable] attribute to the class and add a protected constructor. i.e.:

[Serializable]
public class BadRequestException : Exception
{
    public BadRequestException(string message) : base(message)
    {

    }

    protected BadRequestException(SerializationInfo info, StreamingContext context) : base(info, context)
    {

    }
}
MattBH
  • 892
  • 3
  • 18
  • 28