Aracılığıyla paylaş


JSON şema dışarı aktarma

JsonSchemaExporter.NET 9'da tanıtılan sınıfı, bir veya JsonSerializerOptions örneğini kullanarak .NET türlerinden JSON şemaJsonTypeInfoolanak tanır. Sonuçta elde edilen şema .NET türü için JSON serileştirme sözleşmesinin belirtimini sağlar. Şemada nelerin seri hale getirileceği ve seri durumdan çıkarılabileceklerin şekli açıklanmaktadır.

Aşağıdaki kod parçacığı bir örnek gösterir.

public static void SimpleExtraction()
{
    JsonSerializerOptions options = JsonSerializerOptions.Default;
    JsonNode schema = options.GetJsonSchemaAsNode(typeof(Person));
    Console.WriteLine(schema.ToString());
    //{
    //  "type": ["object", "null"],
    //  "properties": {
    //    "Name": { "type": "string" },
    //    "Age": { "type": "integer" },
    //    "Address": { "type": ["string", "null"], "default": null }
    //  },
    //  "required": ["Name", "Age"]
    //}
}

record Person(string Name, int Age, string? Address = null);

Bu örnekte de görülebileceği gibi, dışarı aktarıcı null atanabilir ve null atanamaz özellikleri birbirinden ayırır ve anahtar sözcüğü isteğe bağlı olan veya olmayan bir oluşturucu parametresinin özelliğiyle doldurur required .

Şema çıkışını yapılandırma

Yöntemini çağırdığınız veya JsonSerializerOptions örneğinde belirtilen yapılandırmaya JsonTypeInfo göre şema çıktısını GetJsonSchemaAsNode etkileyebilirsiniz. Aşağıdaki örnek adlandırma ilkesini olarak KebabCaseUpperayarlar, sayıları dize olarak yazar ve eşlenmemiş özelliklere izin vermemektedir.

public static void CustomExtraction()
{
    JsonSerializerOptions options = new(JsonSerializerOptions.Default)
    {
        PropertyNamingPolicy = JsonNamingPolicy.KebabCaseUpper,
        NumberHandling = JsonNumberHandling.WriteAsString,
        UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow,
    };

    JsonNode schema = options.GetJsonSchemaAsNode(typeof(MyPoco));
    Console.WriteLine(schema.ToString());
    //{
    //  "type": ["object", "null"],
    //  "properties": {
    //    "NUMERIC-VALUE": {
    //      "type": ["string", "integer"],
    //      "pattern": "^-?(?:0|[1-9]\\d*)$"
    //    }
    //  },
    //  "additionalProperties": false
    //}
}

class MyPoco
{
    public int NumericValue { get; init; }
}

Oluşturulan şemayı yapılandırma türünü kullanarak JsonSchemaExporterOptions daha fazla denetleyebilirsiniz. Aşağıdaki örnek, kök düzeyindeki türleri null atanamaz olarak işaretlemek için TreatNullObliviousAsNonNullable özelliğini olarak ayarlartrue.

public static void CustomExtraction()
{
    JsonSerializerOptions options = JsonSerializerOptions.Default;
    JsonSchemaExporterOptions exporterOptions = new()
    {
        TreatNullObliviousAsNonNullable = true,
    };

    JsonNode schema = options.GetJsonSchemaAsNode(typeof(Person), exporterOptions);
    Console.WriteLine(schema.ToString());
    //{
    //  "type": "object",
    //  "properties": {
    //    "Name": { "type": "string" }
    //  },
    //  "required": ["Name"]
    //}
}

record Person(string Name);

Oluşturulan şemayı dönüştürme

Bir temsilci belirterek TransformSchemaNode oluşturulan şema düğümlerine kendi dönüştürmelerinizi uygulayabilirsiniz. Aşağıdaki örnek, ek açıklamalardan oluşturulan DescriptionAttribute şemaya metin ekler.

JsonSchemaExporterOptions exporterOptions = new()
{
    TransformSchemaNode = (context, schema) =>
    {
        // Determine if a type or property and extract the relevant attribute provider.
        ICustomAttributeProvider? attributeProvider = context.PropertyInfo is not null
            ? context.PropertyInfo.AttributeProvider
            : context.TypeInfo.Type;

        // Look up any description attributes.
        DescriptionAttribute? descriptionAttr = attributeProvider?
            .GetCustomAttributes(inherit: true)
            .Select(attr => attr as DescriptionAttribute)
            .FirstOrDefault(attr => attr is not null);

        // Apply description attribute to the generated schema.
        if (descriptionAttr != null)
        {
            if (schema is not JsonObject jObj)
            {
                // Handle the case where the schema is a Boolean.
                JsonValueKind valueKind = schema.GetValueKind();
                Debug.Assert(valueKind is JsonValueKind.True or JsonValueKind.False);
                schema = jObj = new JsonObject();
                if (valueKind is JsonValueKind.False)
                {
                    jObj.Add("not", true);
                }
            }

            jObj.Insert(0, "description", descriptionAttr.Description);
        }

        return schema;
    }
};

Aşağıdaki kod örneği, ek açıklamalardan description anahtar sözcük kaynağını içeren DescriptionAttribute bir şema oluşturur:

JsonSerializerOptions options = JsonSerializerOptions.Default;
JsonNode schema = options.GetJsonSchemaAsNode(typeof(Person), exporterOptions);
Console.WriteLine(schema.ToString());
//{
//  "description": "A person",
//  "type": ["object", "null"],
//  "properties": {
//    "Name": { "description": "The name of the person", "type": "string" }
//  },
//  "required": ["Name"]
//}
[Description("A person")]
record Person([property: Description("The name of the person")] string Name);