JavaScriptSerializer - 枚举的 JSON 序列化为字符串

我有一个包含enum属性的类,并在使用JavaScriptSerializer序列化对象后,我的 json 结果包含枚举的整数值,而不是其string “name”。有没有一种方法可以在我的 json 中将枚举作为string获取而无需创建自定义JavaScriptConverter ?也许有一个属性可以修饰enum定义或对象属性?

举个例子:

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }
    Gender Gender { get; set; }
}

所需的 json 结果:

{ "Age": 35, "Gender": "Male" }

理想情况下,使用内置的. NET 框架类寻找答案,如果可能的话,欢迎使用替代方法(如 Json.net)。

答案

我发现Json.NET通过StringEnumConverter属性提供了我正在寻找的确切功能:

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }

有关更多详细信息,请StringEnumConverter文档

还有其他地方可以更全局地配置此转换器:

  • 枚举本身,如果您想让枚举始终被序列化 / 反序列化为字符串:

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
  • 如果有人想避免装修的属性,你可以转换器添加到您的 JsonSerializer(所建议比约恩埃吉尔 ):

    serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());

    并且它将对在序列化期间看到的每个枚举都有效(由Travis建议)。

  • 或 JsonConverter(由香蕉建议):

    JsonConvert.SerializeObject(MyObject, 
        new Newtonsoft.Json.Converters.StringEnumConverter());

另外,您可以使用StringEnumConverter(NamingStrategy,Boolean)构造函数来控制大小写以及是否仍接受数字。

不,没有可以使用的特殊属性。 JavaScriptSerializerenums序列化为其数值,而不是其字符串表示形式。您将需要使用自定义序列化来将enum序列化为其名称而不是数字值。


如果您可以使用 JSON.Net 代替JavaScriptSerializer ,则可以查看OmerBakhari提供的有关此问题答案 :JSON.net 涵盖了此用例(通过属性[JsonConverter(typeof(StringEnumConverter))] )以及许多其他内置方法未处理的情况. net 序列化器。 这是一个比较串行器特性和功能的链接

将以下内容添加到 global.asax 中,以将 c#枚举的 JSON 序列化为字符串

HttpConfiguration config = GlobalConfiguration.Configuration;
            config.Formatters.JsonFormatter.SerializerSettings.Formatting =
                Newtonsoft.Json.Formatting.Indented;

            config.Formatters.JsonFormatter.SerializerSettings.Converters.Add
                (new Newtonsoft.Json.Converters.StringEnumConverter());

@Iggy 答案仅将 ASP.NET(Web API 等)的 c#枚举的 JSON 序列化设置为字符串。

但是要使其也可以用于临时序列化,请在您的开始类中添加以下内容(例如 Global.asax Application_Start)

//convert Enums to Strings (instead of Integer) globally
JsonConvert.DefaultSettings = (() =>
{
    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
    return settings;
});

有关Json.NET 页面的更多信息

此外,要让您的枚举成员对特定文本进行序列化 / 反序列化,请使用

System.Runtime.Serialization.EnumMember

属性,如下所示:

public enum time_zone_enum
{
    [EnumMember(Value = "Europe/London")] 
    EuropeLondon,

    [EnumMember(Value = "US/Alaska")] 
    USAlaska
}

我无法像(@ob。)的最高答案中那样更改源模型,也不想像 @Iggy 这样在全球范围内注册它。所以我将https://stackoverflow.com/a/2870420/237091和 @Iggy 的https://stackoverflow.com/a/18152942/237091结合在一起,以允许在 SerializeObject 命令本身期间设置字符串枚举转换器:

Newtonsoft.Json.JsonConvert.SerializeObject(
    objectToSerialize, 
    Newtonsoft.Json.Formatting.None, 
    new Newtonsoft.Json.JsonSerializerSettings()
    {
        Converters = new List<Newtonsoft.Json.JsonConverter> {
            new Newtonsoft.Json.Converters.StringEnumConverter()
        }
    })

Omer Bokhari 和 uri 的答案的结合始终是我的解决方案,因为我想要提供的值通常与枚举中的值有所不同,特别是如果需要,我希望能够更改枚举。

因此,如果有人感兴趣,它是这样的:

public enum Gender
{
   [EnumMember(Value = "male")] 
   Male,
   [EnumMember(Value = "female")] 
   Female
}

class Person
{
    int Age { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}

这是很容易通过添加完成ScriptIgnore属性的Gender属性,使其不被序列化,并增加了GenderString不会获取序列化属性:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

    string GenderString { get { return Gender.ToString(); } }
}

这个版本的 Stephen 的答案不会更改 JSON 中的名称:

[DataContract(
    Namespace = 
       "http://schemas.datacontract.org/2004/07/Whatever")]
class Person
{
    [DataMember]
    int Age { get; set; }

    Gender Gender { get; set; }

    [DataMember(Name = "Gender")]
    string GenderString
    {
        get { return this.Gender.ToString(); }
        set 
        { 
            Gender g; 
            this.Gender = Enum.TryParse(value, true, out g) ? g : Gender.Male; 
        }
    }
}

这是 newtonsoft.json 的答案

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}

ASP.NET Core 方式:

public class Startup
{
  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
    services.AddMvc().AddJsonOptions(options =>
    {
      options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
    });
  }
}

https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e