CSharp - JSon enum作为字符串的序列化

  显示原文与译文双语对照的内容

我有一个包含 enum 属性的类,在使用 JavaScriptSerializer 序列化对象时,我的json结果包含枚举的整数值而不是 string"姓名"。 是否有办法在我的json中将枚举作为字符串获取,而不必创建自定义的JavaScriptConverter? 也许有一个属性,我可以装饰枚举定义,或者对象属性?

举例来说,


enum Gender { Male, Female }

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

所需的json结果:


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

时间:

我发现 Json.NET 提供了使用 StringEnumConverter 属性所需的精确功能:


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

更多关于 StringEnumConverter 文档编辑器的详细信息。

将下面的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());

这很容易通过添加一个 ScriptIgnoreGender 财产属性,使其不会serialised,添加 GenderString 财产并得到 serialised:


class Person
{
 int Age { get; set; }

 [ScriptIgnore]
 Gender Gender { get; set; }

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

stephan的这个版本的回答不改变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; 
 }
 }
}

@Iggy 应答将 C# 枚举的JSON序列化设置为只用于 ASP.NET ( Web API 等等) 。

但是,为了使它与即席序列化一起工作,在开始类( 如 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
}

下面是一个简单的解决方案,它将 server-side C# 枚举序列化为JSON并使用结果填充 client-side <select> 元素。 这既适用于简单枚举,也适用于位标志枚举。

我已经包含了end-to-end解决方案,因为我认为大多数希望序列化 C# 枚举的人也将使用它来填充 <select> drop-down 。

这里是:

示例枚举


public enum Role
{
 None = Permission.None,
 Guest = Permission.Browse,
 Reader = Permission.Browse| Permission.Help, 
 Manager = Permission.Browse | Permission.Help | Permission.Customise
}

使用按位ORs生成权限系统的复杂枚举。 所以你不能依靠简单的索引 [0,1,2..] 作为枚举的整数值。

服务器端- C#


Get["/roles"] = _ =>
{
 var type = typeof(Role);
 var data = Enum
. GetNames(type)
. Select(name => new 
 {
 Id = (int)Enum.Parse(type, name), 
 Name = name 
 })
. ToArray();

 return Response.AsJson(data);
};

上面的代码使用NancyFX框架来处理获取请求。 它使用 Response.AsJson() helper 方法的- 但是不用担心,你可以使用任何标准的JSON格式化程序,因为枚举已经被投射到一个简单的匿名类型,准备序列化。

生成的JSON


[
 {"Id":0,"Name":"None"},
 {"Id":2097155,"Name":"Guest"},
 {"Id":2916367,"Name":"Reader"},
 {"Id":4186095,"Name":"Manager"}
]

客户端- CoffeeScript


fillSelect=(id, url, selectedValue=0)->
 $select = $ id
 $option = (item)-> $"<option/>", 
 {
 value:"#{item.Id}"
 html:"#{item.Name}"
 selected:"selected" if item.Id is selectedValue
 }
 $.getJSON(url).done (data)->$option(item).appendTo $select for item in data

$ ->
 fillSelect"#role","/roles", 2916367

HTML之前


<select id="role" name="role"></select>

HTML


<select id="role" name="role">
 <option value="0">None</option>
 <option value="2097155">Guest</option>
 <option value="2916367" selected="selected">Reader</option>
 <option value="4186095">Manager</option>
</select>

...