2016-03-31 2 views
2

Я использую пакет Newtonsoft.Json.Schema для создания схем JSON. В настоящее время схемы не содержат свойства «title», поэтому я создал пользовательский поставщик, следующий за the example in the documentation, однако поставщик работает только на родительском узле и пропускает все узлы свойств.Как создать пользовательский JSchemaGenerationProvider, который добавляет атрибут title как к модели, так и к свойствам модели?

class User { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public DateTime CreatedDate { get; set; } 
} 

class TitleProvider : JSchemaGenerationProvider { 
    public override JSchema GetSchema(JSchemaTypeGenerationContext context) { 
     var schema = new JSchemaGenerator().Generate(context.ObjectType); 
     schema.Title = "foo"; 
     return schema; 
    } 
} 

public class Program { 
    public static void Main() { 
     var generator = new JSchemaGenerator(); 
     generator.GenerationProviders.Add(new TitleProvider()); 
     var schema = generator.Generate(typeof(User)); 

     Console.WriteLine(schema); 
    } 
} 
// OUTPUT: 
//{ 
// "title": "foo", 
// "type": "object", 
// "properties": { 
// "Id": { 
//  "type": "integer" 
// }, 
// "Name": { 
//  "type": [ 
//  "string", 
//  "null" 
//  ] 
// }, 
// "CreatedDate": { 
//  "type": "string" 
// } 
// }, 
// "required": [ 
// "Id", 
// "Name", 
// "CreatedDate" 
// ] 
//} 

Как настроить этот поставщик для запуска на узлах свойств (по аналогии с примером, приведенным в связанной документации)?

Другие Примечания:

  • если вы возвращаете нуль из метода поставщика GetSchema, это перебрать все свойства (которые я наблюдал в отладчике), хотя он не имеет функциональности я хочу тогда
  • , если добавить в блок, если пропустить, когда ток context.ObjectType обладает свойствами, это перебрать все свойства, но только добавляет заголовок первого свойства

ответ

3

Так я оказался Downlo добавив код и перешагнув его, и обнаружил, что, как только ваш провайдер возвращает схему, он обходит всю обработку по умолчанию для всех узлов ниже текущего узла. Так что в значительной степени вам нужно все разобрать самостоятельно или каким-то образом изменить поведение по умолчанию. Я в конечном итоге создать провайдера, который позволяет выполнять логику на каждом узле, но по-прежнему дает схему по умолчанию создается для работы с:

abstract class RecursiveProvider : JSchemaGenerationProvider { 
    public string SkipType { get; set; } 
    public override JSchema GetSchema(JSchemaTypeGenerationContext context) { 
     var type = context.ObjectType; 
     JSchema schema = null; 

     var generator = new JSchemaGenerator(); 

     Console.WriteLine(type.Name); 

     var isObject = type.Namespace != "System"; 

     if (isObject) { 
      if (SkipType == type.Name) 
       return null; 

      this.SkipType = type.Name; 
      generator.GenerationProviders.Add(this); 
     } 

     schema = generator.Generate(type); 
     return ModifySchema(schema, context); 
    } 

    public abstract JSchema ModifySchema(JSchema schema, JSchemaTypeGenerationContext context); 

} 

class PropertyProvider : RecursiveProvider { 
    public override JSchema ModifySchema(JSchema schema, JSchemaTypeGenerationContext context) { 
     schema.Title = "My Title"; 
     return schema; 
    } 
} 
+0

Большое спасибо за размещение этого, он оказался очень полезным для меня! – SebastianC

1

Последняя версия Json.NET Schema поддерживает DisplayNameAttribute и DescriptionAttribute. Размещение объектов типа или свойства добавит title и description свойствам к сгенерированной схеме.

Тип:

[DisplayName("Postal Address")] 
[Description("The mailing address.")] 
public class PostalAddress 
{ 
    [DisplayName("Street Address")] 
    [Description("The street address. For example, 1600 Amphitheatre Pkwy.")] 
    public string StreetAddress { get; set; } 

    [DisplayName("Locality")] 
    [Description("The locality. For example, Mountain View.")] 
    public string AddressLocality { get; set; } 

    [DisplayName("Region")] 
    [Description("The region. For example, CA.")] 
    public string AddressRegion { get; set; } 

    [DisplayName("Country")] 
    [Description("The country. For example, USA. You can also provide the two letter ISO 3166-1 alpha-2 country code.")] 
    public string AddressCountry { get; set; } 

    [DisplayName("Postal Code")] 
    [Description("The postal code. For example, 94043.")] 
    public string PostalCode { get; set; } 
} 

Код:

JSchemaGenerator generator = new JSchemaGenerator(); 
generator.DefaultRequired = Required.DisallowNull; 

JSchema schema = generator.Generate(typeof(PostalAddress)); 
// { 
// "title": "Postal Address", 
// "description": "The mailing address.", 
// "type": "object", 
// "properties": { 
//  "StreetAddress": { 
//  "title": "Street Address", 
//  "description": "The street address. For example, 1600 Amphitheatre Pkwy.", 
//  "type": "string" 
//  }, 
//  "AddressLocality": { 
//  "title": "Locality", 
//  "description": "The locality. For example, Mountain View.", 
//  "type": "string" 
//  }, 
//  "AddressRegion": { 
//  "title": "Region", 
//  "description": "The region. For example, CA.", 
//  "type": "string" 
//  }, 
//  "AddressCountry": { 
//  "title": "Country", 
//  "description": "The country. For example, USA. You can also provide the two-letter ISO 3166-1 alpha-2 country code.", 
//  "type": "string" 
//  }, 
//  "PostalCode": { 
//  "title": "Postal Code", 
//  "description": "The postal code. For example, 94043.", 
//  "type": "string" 
//  } 
// } 
// } 

https://www.newtonsoft.com/jsonschema/help/html/GenerateWithDescriptions.htm

Смежные вопросы