2014-09-08 3 views
3

Возможно ли создать схему с Json.NET, которая выводит значения enum как строки, а не целые числа? Я заметил, что кто-то разворачивал код, чтобы сделать это, но задавался вопросом, есть ли другой способ сделать это, или если есть какие-то планы сделать это.Сгенерировать схему с помощью StringEnumConverter

EDIT

Чтобы быть ясно, я пытаюсь использовать это, чтобы создать схему:

var schemaGenerator = new JsonSchemaGenerator(); 
var schema = schemaGenerator.Generate(typeof(Class1)); 

return schema.ToString(); 
+0

Вы пробовали использовать 'StringEnumConverter'? Он должен делать именно это. –

+0

Генератор схемы, похоже, полностью игнорирует его. Я попробовал '[JsonProperty (ItemConverterType = typeof (StringEnumConverter)], но это не сработает. – Tom

+0

Вам нужно использовать' [JsonConverter (typeof (StringEnumConverter))] вместо. –

ответ

1

У меня была такая же проблема. Я написал хак, который заменяет целые числа с перечислениями через отражение. Все еще ждут официального исправления.

var jsonSchemaString = JsonUtility.getRawJSONSchema(typeof(Class1).FullName); 

Не тестировалось со всеми тестовыми случаями.

public class JsonUtility 
{ 
    public static string getRawJSONSchema(string jsonObjectTypeName) 
    { 
     var jsonSchemaGenerator = new JsonSchemaGenerator(); 

     var myType = Type.GetType(jsonObjectTypeName); 

     var schema = jsonSchemaGenerator.Generate(myType); 

     schema.Title = myType.Name; 

     var enumToFix = new Dictionary<string, string>(); 

     FindEnums(schema, myType, ref enumToFix); 

     var writer = new StringWriter(); 

     var jsonTextWriter = new JsonTextWriter(writer); 

     schema.WriteTo(jsonTextWriter); 

     var result = writer.ToString(); 

     ReplaceEnums(ref result, enumToFix); 

     return result; 
    } 



    //This is a known issue with JsonSchemaGenarator 
    //Stay tuned with future releases of JSON.Net package 
    //Enums are generator as integers 
    //Lets convert intergers to string here 
    private static void FindEnums(JsonSchema schema, Type Type, ref Dictionary<string, string> result) 
    { 

     if (schema.Properties != null) 
      foreach (var prop in schema.Properties) 
      { 
       if (prop.Value.Enum != null) 
       { 

        var properties = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance); 
        foreach (var p in properties) 
        { 
         SearchProperty(p, prop.Key, ref result); 
        } 


       } 
       FindEnums(prop.Value, Type, ref result); 
      } 

    } 



    private static void SearchProperty(PropertyInfo property, string propertyName, ref Dictionary<string, string> result) 
    { 
     //IF property name is same as JSON property name 
     if (property.Name.Trim().ToLower() == propertyName.Trim().ToLower()) 
     { 
      result.Add(property.Name, EnumToJsonArray(property.PropertyType)); 
      return; 
     } 
     //Custom JSON property names set via attributes 
     foreach (CustomAttributeData customAttr in property.CustomAttributes) 
     { 
      if (customAttr.AttributeType.Name == "JsonPropertyAttribute") 
      { 
       foreach (CustomAttributeNamedArgument arg in customAttr.NamedArguments) 
       { 
        if (arg.TypedValue.Value.ToString().Trim().ToLower() == propertyName.Trim().ToLower()) 
        { 
         result.Add(propertyName, EnumToJsonArray(property.PropertyType)); 
         return; 
        } 
       } 
       foreach (CustomAttributeTypedArgument arg in customAttr.ConstructorArguments) 
       { 
        if (arg.Value.ToString().Trim().ToLower() == propertyName.Trim().ToLower()) 
        { 
         result.Add(propertyName, EnumToJsonArray(property.PropertyType)); 
         return; 
        } 
       } 
      } 
     } 



     PropertyInfo[] info = property.PropertyType.GetProperties(BindingFlags.Public | BindingFlags.Instance); 

     if (info.Length > 0) 
     { 
      foreach (var item in info) 
      { 
       SearchProperty(item, propertyName, ref result); 
      } 
     } 

    } 

    private static string EnumToJsonArray(Type type) 
    { 
     if (!type.IsEnum) 
      throw new InvalidOperationException("enum expected"); 

     var results = 
      Enum.GetValues(type).Cast<object>().Select(enumValue => enumValue.ToString()) 
       .ToList(); 

     return Newtonsoft.Json.JsonConvert.SerializeObject(results); 

    } 

    private static void ReplaceEnums(ref string result, Dictionary<string, string> enumToFix) 
    { 
     foreach (var item in enumToFix) 
     { 
      result = Regex.Replace(result, @"""" + item.Key + ".*?}", @"""" + item.Key + @""":{""required"":true,""type"":""string"",""enum"":" + item.Value + @"}"); 
     } 
    } 

} 
2

Установить Newtonsoft.Json.Schema пакет через менеджер пакетов NuGet, то вы можете выводить перечислений как строки вне-коробки.

Указанные классы

public class Foo 
{ 
    public Options Bar { get; set; } 
} 

public enum Options 
{ 
    Option1, 
    Option2 
} 

схемы будет генерироваться следующим образом, нет необходимости для украшения классов/свойств с [JsonConverter(typeof(StringEnumConverter))] атрибута.

JSchemaGenerator generator = new JSchemaGenerator(); 
generator.GenerationProviders.Add(new StringEnumGenerationProvider()); 
JSchema schema = generator.Generate(typeof(Foo), false); 
//Console.WriteLine(schema); 

image

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