【问题标题】:Json.Net.Schema: How to generate a schema where only the [Required] properties are required?Json.Net.Schema:如何生成只需要 [Required] 属性的模式?
【发布时间】:2020-12-02 17:32:15
【问题描述】:

我正在编写一个工具来处理 resume.json 文件 (project),并正在创建一个 Json Schema 来验证用户输入。我正在尝试使用 Json.Net.Schema 自动执行此操作,但输出始终需要所有属性,无论属性是否具有 [Required][JsonRequired] 属性。

架构生成代码

var generator = new JSchemaGenerator
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
    SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName
};

var schema = generator.Generate(typeof(Resume));
var sb = new StringBuilder();
schema.WriteTo(new JsonTextWriter(
    new IndentedTextWriter(
        new StringWriter(sb),
        "  ")
    )
{
    Formatting = Formatting.Indented,
    IndentChar = ' ', Indentation = 2,
    QuoteName = true
}, new JSchemaWriterSettings
{
    Version = SchemaVersion.Draft7
});

File.WriteAllText("E:\\resume.schema", sb.ToString());

继续上课(和孩子)

public class Resume
{
    [Required]
    public Basics Basics { get; set; }
    public Work[] Work { get; set; }
    public Volunteer[] Volunteer { get; set; }
    public Education[] Education { get; set; }
    public Award[] Awards { get; set; }
    public Publication[] Publications { get; set; }
    public Skill[] Skills { get; set; }
    public Language[] Languages { get; set; }
    public Interest[] Interests { get; set; }
    public Reference[] References { get; set; }
}

public class Award
{
    [Required]
    public string Title { get; set; }
    public string Date { get; set; }
    public string Awarder { get; set; }
    public string Summary { get; set; }
}

public class Basics
{
    [Required]
    public string Name { get; set; }
    public string Label { get; set; }
    public Uri Picture { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Website { get; set; }
    public string Summary { get; set; }
    public Location Location { get; set; }
    public Profile[] Profiles { get; set; }
}

public class Education
{
    [Required]
    public string Institution { get; set; }
    public string Area { get; set; }
    public string StudyType { get; set; }
    public string StartDate { get; set; }
    public string EndDate { get; set; }
    public string Gpa { get; set; }
    public string[] Courses { get; set; }
}

public class Interest
{
    [Required]
    public string Name { get; set; }
    public string[] Keywords { get; set; }
}

public class Language
{
    [Required]
    public string language { get; set; }
    [Required]
    public string Fluency { get; set; }
}

public class Location
{
    public string Address { get; set; }
    [Required]
    public string PostalCode { get; set; }
    [Required]
    public string City { get; set; }
    [Required]
    public string CountryCode { get; set; }
    public string Region { get; set; }
}

public class Profile
{
    [Required]
    public string Network { get; set; }
    [Required]
    public string Username { get; set; }
    [Required]
    public string Url { get; set; }
}

public class Publication
{
    [Required]
    public string Name { get; set; }
    public string Publisher { get; set; }
    public string ReleaseDate { get; set; }
    public string Website { get; set; }
    public string Summary { get; set; }
}

public class Reference
{
    [Required]
    public string Name { get; set; }
    public string reference { get; set; }
}

public class Skill
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Level { get; set; }
    public string[] Keywords { get; set; }
}

public class Volunteer
{
    [Required]
    public string Organization { get; set; }
    [Required]
    public string Position { get; set; }
    public string Website { get; set; }
    public string StartDate { get; set; }
    public string EndDate { get; set; }
    public string Summary { get; set; }
    public string[] Highlights { get; set; }
}

public class Work
{
    [Required]
    public string Company { get; set; }
    [Required]
    public string Position { get; set; }
    public string Website { get; set; }
    [Required]
    public string StartDate { get; set; }
    public string EndDate { get; set; }
    public string Summary { get; set; }
    public string[] Highlights { get; set; }
}

电流输出

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "Resume",
  "definitions": {
    "Award": {
      "$id": "Award",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "title": {
          "type": "string"
        },
        "date": {
          "type": [
            "string",
            "null"
          ]
        },
        "awarder": {
          "type": [
            "string",
            "null"
          ]
        },
        "summary": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "title",
        "date",
        "awarder",
        "summary"
      ]
    },
    "Basics": {
      "$id": "Basics",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "label": {
          "type": [
            "string",
            "null"
          ]
        },
        "picture": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri"
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "phone": {
          "type": [
            "string",
            "null"
          ]
        },
        "website": {
          "type": [
            "string",
            "null"
          ]
        },
        "summary": {
          "type": [
            "string",
            "null"
          ]
        },
        "location": {
          "$id": "Location",
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "address": {
              "type": [
                "string",
                "null"
              ]
            },
            "postalCode": {
              "type": "string"
            },
            "city": {
              "type": "string"
            },
            "countryCode": {
              "type": "string"
            },
            "region": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "address",
            "postalCode",
            "city",
            "countryCode",
            "region"
          ]
        },
        "profiles": {
          "$id": "Profile[]",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "$id": "Profile",
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "network": {
                "type": "string"
              },
              "username": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "network",
              "username",
              "url"
            ]
          }
        }
      },
      "required": [
        "name",
        "label",
        "picture",
        "email",
        "phone",
        "website",
        "summary",
        "location",
        "profiles"
      ]
    },
    "Education": {
      "$id": "Education",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "institution": {
          "type": "string"
        },
        "area": {
          "type": [
            "string",
            "null"
          ]
        },
        "studyType": {
          "type": [
            "string",
            "null"
          ]
        },
        "startDate": {
          "type": [
            "string",
            "null"
          ]
        },
        "endDate": {
          "type": [
            "string",
            "null"
          ]
        },
        "gpa": {
          "type": [
            "string",
            "null"
          ]
        },
        "courses": {
          "$id": "String[]",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "required": [
        "institution",
        "area",
        "studyType",
        "startDate",
        "endDate",
        "gpa",
        "courses"
      ]
    },
    "Interest": {
      "$id": "Interest",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "keywords": {
          "$id": "String[]",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "required": [
        "name",
        "keywords"
      ]
    },
    "Language": {
      "$id": "Language",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "language": {
          "type": "string"
        },
        "fluency": {
          "type": "string"
        }
      },
      "required": [
        "language",
        "fluency"
      ]
    },
    "Location": {
      "$ref": "Location"
    },
    "Profile": {
      "$ref": "Profile"
    },
    "Publication": {
      "$id": "Publication",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "publisher": {
          "type": [
            "string",
            "null"
          ]
        },
        "releaseDate": {
          "type": [
            "string",
            "null"
          ]
        },
        "website": {
          "type": [
            "string",
            "null"
          ]
        },
        "summary": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "name",
        "publisher",
        "releaseDate",
        "website",
        "summary"
      ]
    },
    "Reference": {
      "$id": "Reference",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "reference": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "name",
        "reference"
      ]
    },
    "Skill": {
      "$id": "Skill",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "level": {
          "type": "string"
        },
        "keywords": {
          "$id": "String[]",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "required": [
        "name",
        "level",
        "keywords"
      ]
    },
    "Volunteer": {
      "$id": "Volunteer",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "organization": {
          "type": "string"
        },
        "position": {
          "type": "string"
        },
        "website": {
          "type": [
            "string",
            "null"
          ]
        },
        "startDate": {
          "type": [
            "string",
            "null"
          ]
        },
        "endDate": {
          "type": [
            "string",
            "null"
          ]
        },
        "summary": {
          "type": [
            "string",
            "null"
          ]
        },
        "highlights": {
          "$id": "String[]",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "required": [
        "organization",
        "position",
        "website",
        "startDate",
        "endDate",
        "summary",
        "highlights"
      ]
    },
    "Work": {
      "$id": "Work",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "company": {
          "type": "string"
        },
        "position": {
          "type": "string"
        },
        "website": {
          "type": [
            "string",
            "null"
          ]
        },
        "startDate": {
          "type": "string"
        },
        "endDate": {
          "type": [
            "string",
            "null"
          ]
        },
        "summary": {
          "type": [
            "string",
            "null"
          ]
        },
        "highlights": {
          "$id": "String[]",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "required": [
        "company",
        "position",
        "website",
        "startDate",
        "endDate",
        "summary",
        "highlights"
      ]
    }
  },
  "type": "object",
  "properties": {
    "basics": {
      "$ref": "Basics"
    },
    "work": {
      "$id": "Work[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Work"
      }
    },
    "volunteer": {
      "$id": "Volunteer[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Volunteer"
      }
    },
    "education": {
      "$id": "Education[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Education"
      }
    },
    "awards": {
      "$id": "Award[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Award"
      }
    },
    "publications": {
      "$id": "Publication[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Publication"
      }
    },
    "skills": {
      "$id": "Skill[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Skill"
      }
    },
    "languages": {
      "$id": "Language[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Language"
      }
    },
    "interests": {
      "$id": "Interest[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Interest"
      }
    },
    "references": {
      "$id": "Reference[]",
      "type": [
        "array",
        "null"
      ],
      "items": {
        "$ref": "Reference"
      }
    }
  },
  "required": [
    "basics",
    "work",
    "volunteer",
    "education",
    "awards",
    "publications",
    "skills",
    "languages",
    "interests",
    "references"
  ]
}

如何让架构生成器支持Required 属性?

【问题讨论】:

    标签: c# json json.net jsonschema


    【解决方案1】:

    JSchemaGenerator 有一个属性DefaultRequired

    获取或设置模式的默认所需状态。

    由于某种原因,该属性的默认值为Required.AllowNull,如source所示:

    public JSchemaGenerator()
    {
        _schemaReferenceHandling = SchemaReferenceHandling.Objects;
        _defaultRequired = Required.AllowNull;
    }
    

    如果将其更改为 Required.Default,则只有那些明确标记为必需的属性,例如使用[Required][JsonProperty(Required = Required.Always)],将根据需要在架构中列出:

    var generator = new JSchemaGenerator
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName,
        DefaultRequired = Required.Default,
    };
    

    DefaultRequired 的默认值不是documented,但可能应该是。您可以向 Newtonsoft 打开一个issue,要求对文档进行澄清。

    演示小提琴here.

    【讨论】:

    • 谢谢,正是我需要的。
    猜你喜欢
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多