Skip to content

[DataMember(IsRequired = true)] do not mark property as required #2383

@ouvreboite

Description

@ouvreboite

Swashbuckle.AspNetCore.SwaggerGen 6.3.0
Swashbuckle.AspNetCore.Newtonsoft 6.3.0

A field annotated with [DataMember(IsRequired = true)] is not marked as required in the generated OpenApi specification.

// class
[DataContract]
public class DataMemberModel
{
    [DataMember(Name = "customId", IsRequired = true)]
    public string Id;
}

// schema
"DataMemberModel": {
    "type": "object",
    "properties": {
        "customId": {  //the id shows that DataMember is indeed used
            "type": "string",
            "nullable": true
        }
    },
    "additionalProperties": false
}

The "required" status is supposed to be set in NewtonsoftDataContractResolver.GetDataPropertiesFor, using JsonPropertyExtensions.IsRequiredSpecified to know if JsonProperty.Required is readable. But JsonPropertyExtensions.IsRequiredSpecified does not actually look at JsonProperty.Required (which is equals to NotNull in our case). It incorrectly return false.

//NewtonsoftDataContractResolver.cs
var required = jsonProperty.IsRequiredSpecified()
      ? jsonProperty.Required
      : jsonObjectContract.ItemRequired ?? Required.Default;

//JsonPropertyExtensions.cs
public static bool IsRequiredSpecified(this JsonProperty jsonProperty)
{
    if (!jsonProperty.TryGetMemberInfo(out MemberInfo memberInfo))
        return false;

    if (memberInfo.GetCustomAttribute<JsonRequiredAttribute>() != null)
        return true;

    var jsonPropertyAttributeData = memberInfo.GetCustomAttributesData()
        .FirstOrDefault(attrData => attrData.AttributeType == typeof(JsonPropertyAttribute));

    return (jsonPropertyAttributeData != null) && jsonPropertyAttributeData.NamedArguments.Any(arg => arg.MemberName == "Required");
}

Maybe adding a if(jsonProperty.Required != Required.Default) return true at the start of IsRequiredSpecified could be enough.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions