You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让JSON.NET JSchema生成器在JSON Schema中渲染additionalProperties属性

How to Add additionalProperties: false to JSchemas Generated with JSON.NET JSchemaGenerator

Great question! Let's break down how to get the additionalProperties: false attribute added to both your root schema (myType) and nested definitions (mySubType) when using JSON.NET's JSchemaGenerator.

Your Current Setup

First, let's recap your existing code and output to make sure we're aligned:

Your generation code:

var generator = new JSchemaGenerator();
generator.ContractResolver = new CamelCasePropertyNamesContractResolver();
generator.SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName;
var schema = generator.Generate(typeof(myType));
string jsonSchema = schema.ToString();

Current output (missing additionalProperties):

{
  "$id": "myType",
  "definitions": {
    "mySubType" : {
      "$id": "mySubType",
      "type": [ "object", "null" ],
      "properties": { "name": { "type": "string" } },
      "required": [ "name" ]
    }
  },
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "details": { "$ref": "mySubType" }
  },
  "required": [ "name", "details" ]
}

Solution 1: Custom Attribute + Extended JSchemaGenerator

JSON.NET doesn't include a built-in data annotation for additionalProperties: false, but you can create a custom class-level attribute and extend the generator to recognize it. This gives you precise control over which classes get this strict property enforcement.

Step 1: Create a Custom Marker Attribute

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class AdditionalPropertiesFalseAttribute : Attribute
{
    // No extra logic needed—this is just a marker for the generator
}

Step 2: Apply the Attribute to Your Classes

Mark the classes you want to restrict to defined properties only:

[AdditionalPropertiesFalse]
public class myType
{
    [Required]
    public string Name { get; set; }
    
    [Required]
    public mySubType Details { get; set; }
}

[AdditionalPropertiesFalse]
public class mySubType
{
    [Required]
    public string Name { get; set; }
}

Step 3: Extend JSchemaGenerator to Handle the Attribute

Create a custom generator that checks for your attribute and sets additionalProperties accordingly:

public class StrictSchemaGenerator : JSchemaGenerator
{
    protected override JSchema GenerateSchema(Type type, SchemaGenerationContext context)
    {
        var schema = base.GenerateSchema(type, context);
        
        // Check if the current type has our custom attribute
        if (type.GetCustomAttribute<AdditionalPropertiesFalseAttribute>() != null)
        {
            schema.AdditionalProperties = JSchema.CreateFalse();
        }
        
        return schema;
    }
}

Step 4: Use the Custom Generator

Replace your original generator with the custom one:

var generator = new StrictSchemaGenerator();
generator.ContractResolver = new CamelCasePropertyNamesContractResolver();
generator.SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName;
var schema = generator.Generate(typeof(myType));
string jsonSchema = schema.ToString();

Solution 2: Post-Generation Schema Modification

If you prefer a simpler, global approach without custom attributes, you can recursively traverse the generated schema and set additionalProperties: false on all object-type schemas (including nested definitions).

var generator = new JSchemaGenerator();
generator.ContractResolver = new CamelCasePropertyNamesContractResolver();
generator.SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName;
var schema = generator.Generate(typeof(myType));

// Recursively update all object schemas
SetAdditionalPropertiesFalse(schema);

string jsonSchema = schema.ToString();

// Helper method to traverse and modify the schema
void SetAdditionalPropertiesFalse(JSchema targetSchema)
{
    // Set for the current schema if it's an object
    if (targetSchema.Type.HasFlag(JSchemaType.Object))
    {
        targetSchema.AdditionalProperties = JSchema.CreateFalse();
    }

    // Update all nested definitions
    foreach (var definition in targetSchema.Definitions.Values)
    {
        SetAdditionalPropertiesFalse(definition);
    }

    // Update nested object properties
    foreach (var property in targetSchema.Properties.Values)
    {
        if (property.Type.HasFlag(JSchemaType.Object))
        {
            SetAdditionalPropertiesFalse(property);
        }
    }
}

Which Approach to Choose?

  • Custom Attribute: Best if you only want to enforce strict property checking on specific classes, not all of them.
  • Post-Generation Modification: Ideal if you want a strict schema across every object type in your model.

Either method will produce the exact schema you're targeting, with additionalProperties: false added to both myType and mySubType.

内容的提问来源于stack exchange,提问作者Stewart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:59:45