Search code examples
c#swaggerautorest

How to prevent autorest from accepting null / nullable parameters in the constructors?


I am using autorest to generate C# clients from a swagger.json file.

However, I noticed that the auto generated classes have constructors accepting nullable values.

Here is the original C# class the swagger.json is from:

/// <summary>
/// Defines the GPS coordinates model.
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
public sealed class GpsCoordinatesModel
{
    #region Properties

    /// <summary>
    /// Gets the latitude.
    /// </summary>
    [JsonProperty("latitude")]
    public double Latitude { get; }

    /// <summary>
    /// Gets the longitude.
    /// </summary>
    [JsonProperty("longitude")]
    public double Longitude { get; }

    #endregion

    #region Constructors

    /// <param name="latitude"></param>
    /// <param name="longitude"></param>
    /// <exception cref="ArgumentOutOfRangeException">
    /// Thrown if:
    /// - The Latitude is not within the interval [-90, 90].
    /// - The Longitude is not within the interval [-180, 180].
    /// </exception>
    [JsonConstructor]
    public GpsCoordinatesModel(double latitude, double longitude)
    {
        if (latitude < -90d || latitude > 90d)
            throw new ArgumentOutOfRangeException(nameof(latitude), latitude, $"The {nameof(latitude)} must be between -90 and 90.");

        if (longitude < -180d || longitude > 180d)
            throw new ArgumentOutOfRangeException(nameof(longitude), longitude, $"The {nameof(latitude)} must be between -180 and 180.");

        Latitude = latitude;
        Longitude = longitude;
    }

    #endregion
}

Here is the definition of the class within the swagger:

"GpsCoordinatesModel": {
    "type":"object",
    "properties": {
        "latitude": {  
            "format":"double",
            "type":"number",
            "readOnly":true
        },
        "longitude": {
            "format":"double",
            "type":"number",
            "readOnly":true
        }
    }       
}

And here is these same auto generated with autorest:

public partial class GpsCoordinatesModel
{
    /// <summary>
    /// Initializes a new instance of the GpsCoordinatesModel class.
    /// </summary>
    public GpsCoordinatesModel()
    {
        CustomInit();
    }

    /// <summary>
    /// Initializes a new instance of the GpsCoordinatesModel class.
    /// </summary>
    public GpsCoordinatesModel(double? latitude = default(double?), double? longitude = default(double?))
    {
        Latitude = latitude;
        Longitude = longitude;
        CustomInit();
    }

    /// <summary>
    /// An initialization method that performs custom operations like setting defaults
    /// </summary>
    partial void CustomInit();

    /// <summary>
    /// </summary>
    [JsonProperty(PropertyName = "latitude")]
    public double? Latitude { get; private set; }

    /// <summary>
    /// </summary>
    [JsonProperty(PropertyName = "longitude")]
    public double? Longitude { get; private set; }

}

It is not good because I do not want any of these properties to be null, ever.

I have a service that provides GPS coordinates. It requires clients using this service to check each of these property is null when it could avoided automatically if the constructor never accepts those in the first place.

Question

Is there a way to prevent autorest from generated nullable parameters in the constructor?


Solution

  • autorest does not take into account the Required attribute. However, it does take into account the Required property of the JsonProperty class:

    /// <summary>
    /// Defines the GPS coordinates model.
    /// </summary>
    [JsonObject(MemberSerialization.OptIn)]
    public sealed class GpsCoordinatesModel
    {
        #region Properties
    
        /// <summary>
        /// Gets the latitude.
        /// </summary>
        [JsonProperty(PropertyName = "latitude", Required = Required.Always)]
        public double Latitude { get; }
    
        /// <summary>
        /// Gets the longitude.
        /// </summary>
        [JsonProperty(PropertyName = "longitude", Required = Required.Always)]
        public double Longitude { get; }
    
        #endregion
    
        #region Constructors
    
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown if:
        /// - The Latitude is not within the interval [-90, 90].
        /// - The Longitude is not within the interval [-180, 180].
        /// </exception>
        [JsonConstructor]
        public GpsCoordinatesModel(double latitude, double longitude)
        {
            if (latitude < -90d || latitude > 90d)
                throw new ArgumentOutOfRangeException(nameof(latitude), latitude, $"The {nameof(latitude)} must be between -90 and 90.");
    
            if (longitude < -180d || longitude > 180d)
                throw new ArgumentOutOfRangeException(nameof(longitude), longitude, $"The {nameof(latitude)} must be between -180 and 180.");
    
            Latitude = latitude;
            Longitude = longitude;
        }
    
        #endregion
    }