Ome*_*ari 1088 c# asp.net enums json javascriptserializer
我有一个包含enum属性的类,在使用时序列化对象时JavaScriptSerializer,我的json结果包含枚举的整数值而不是它的string"name".有没有办法让枚举作为string我的json而不必创建自定义JavaScriptConverter?也许有一个属性,我可以装饰enum定义,或对象属性,?
举个例子:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
期望的json结果:
{ "Age": 35, "Gender": "Male" }
Run Code Online (Sandbox Code Playgroud)
Ome*_*ari 1999
我发现Json.NET提供了我正在寻找的具有StringEnumConverter属性的确切功能:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }
Run Code Online (Sandbox Code Playgroud)
有关StringEnumConverter文档的更多详细信息.
Mat*_*ing 341
没有你可以使用的特殊属性.JavaScriptSerializer序列化enums为其数值而不是其字符串表示形式.您需要使用自定义序列化来序列化enum其名称而不是数值.
编辑:
正如@OmerBakhari所指出的那样,JSON.net涵盖了这个用例(通过属性JavaScriptSerializer)以及许多其他内部.net序列化程序无法处理的用例.这是一个比较序列化器的特性和功能的链接.
Igg*_*ggy 168
将以下内容添加到您的global.asax中,以便将c#enum的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());
Run Code Online (Sandbox Code Playgroud)
Jur*_*uri 146
@Iggy的答案将c#enum的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;
});
Run Code Online (Sandbox Code Playgroud)
有关Json.NET页面的更多信息
此外,要让您的枚举成员序列化/反序列化特定文本,请使用
System.Runtime.Serialization.EnumMember
属性,像这样:
public enum time_zone_enum
{
[EnumMember(Value = "Europe/London")]
EuropeLondon,
[EnumMember(Value = "US/Alaska")]
USAlaska
}
Run Code Online (Sandbox Code Playgroud)
Sco*_*ord 39
我无法像最终答案(@ob.)那样更改源模型,我不想像@Iggy那样全局注册.所以我结合/sf/answers/200929431/和@ Iggy的/sf/answers/1270705971/,允许在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()
}
})
Run Code Online (Sandbox Code Playgroud)
Ash*_*ous 32
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; }
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*edy 31
这是很容易通过添加完成ScriptIgnore属性的Gender属性,使其不被序列化,并增加了GenderString其性能确实得到连载:
class Person
{
int Age { get; set; }
[ScriptIgnore]
Gender Gender { get; set; }
string GenderString { get { return Gender.ToString(); } }
}
Run Code Online (Sandbox Code Playgroud)
mhe*_*man 26
此版本的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 25
这是newtonsoft.json的答案
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
Gender Gender { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
O. *_*hai 23
对于.NET 6.0如果您想使用内置JsonSerializer(System.Text.Json)
然后,它是开箱即用的,您只需要使用内置JsonStringEnumConverter属性即可。例如:
[JsonConverter(typeof(JsonStringEnumConverter))]
public SomeEnumType EnumProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)
就是这样,但请确保您SomeEnumType包含的值具有确切的字符串值,否则它将引发异常。外壳似乎不敏感。
st1*_*st1 22
ASP.NET核心方式:
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
});
}
}
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
Ser*_*-Tm 22
带有 System.Text.Json 的 Asp.Net Core 3
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())
);
//...
}
Run Code Online (Sandbox Code Playgroud)
bio*_*tal 15
这是一个简单的解决方案,它将服务器端C#枚举序列化为JSON,并使用结果填充客户端<select>元素.这适用于简单的枚举和bitflag枚举.
我已经包含了端到端解决方案,因为我认为大多数人想要将C#枚举序列化为JSON也可能会使用它来填充<select>下拉列表.
开始:
示例枚举
public enum Role
{
None = Permission.None,
Guest = Permission.Browse,
Reader = Permission.Browse| Permission.Help ,
Manager = Permission.Browse | Permission.Help | Permission.Customise
}
Run Code Online (Sandbox Code Playgroud)
一个复杂的枚举,它使用按位OR来生成权限系统.所以你不能依赖简单的索引[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);
};
Run Code Online (Sandbox Code Playgroud)
上面的代码使用NancyFX框架来处理Get请求.它使用Nancy的Response.AsJson()辅助方法 - 但不要担心,您可以使用任何标准JSON格式化程序,因为枚举已经被投射到一个简单的匿名类型,可以进行序列化.
生成的JSON
[
{"Id":0,"Name":"None"},
{"Id":2097155,"Name":"Guest"},
{"Id":2916367,"Name":"Reader"},
{"Id":4186095,"Name":"Manager"}
]
Run Code Online (Sandbox Code Playgroud)
客户端 - 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
Run Code Online (Sandbox Code Playgroud)
HTML之前
<select id="role" name="role"></select>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
Jer*_*yal 15
JsonSerializer如果您不想使用JsonConverter属性,还可以为您添加转换器:
string SerializedResponse = JsonConvert.SerializeObject(
objToSerialize,
new Newtonsoft.Json.Converters.StringEnumConverter()
);
Run Code Online (Sandbox Code Playgroud)
它将适用于enum序列化过程中看到的每一个.
Yah*_*ein 13
对于ASP.Net核心,只需将以下内容添加到您的启动类中:
JsonConvert.DefaultSettings = (() =>
{
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter { AllowIntegerValues = false });
return settings;
});
Run Code Online (Sandbox Code Playgroud)
Yan*_*ang 11
您可以通过调用JsonConverter.SerializeObject来创建JsonSerializerSettings,如下所示:
var result = JsonConvert.SerializeObject
(
dataObject,
new JsonSerializerSettings
{
Converters = new [] {new StringEnumConverter()}
}
);
Run Code Online (Sandbox Code Playgroud)
Gre*_*lor 10
注意到存在Description属性时没有序列化的答案.
这是我的实现,它支持Description属性.
public class CustomStringEnumConverter : Newtonsoft.Json.Converters.StringEnumConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Type type = value.GetType() as Type;
if (!type.IsEnum) throw new InvalidOperationException("Only type Enum is supported");
foreach (var field in type.GetFields())
{
if (field.Name == value.ToString())
{
var attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
writer.WriteValue(attribute != null ? attribute.Description : field.Name);
return;
}
}
throw new ArgumentException("Enum not found");
}
}
Run Code Online (Sandbox Code Playgroud)
枚举:
public enum FooEnum
{
// Will be serialized as "Not Applicable"
[Description("Not Applicable")]
NotApplicable,
// Will be serialized as "Applicable"
Applicable
}
Run Code Online (Sandbox Code Playgroud)
用法:
[JsonConverter(typeof(CustomStringEnumConverter))]
public FooEnum test { get; set; }
Run Code Online (Sandbox Code Playgroud)
Pet*_*eGO 10
对于.Net Core Web Api: -
public void ConfigureServices(IServiceCollection services)
{
...
services.AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
...
}
Run Code Online (Sandbox Code Playgroud)
小智 10
用这个:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
[Serializable]
[JsonConverter(typeof(StringEnumConverter))]
public enum Gender { Male, Female }
Run Code Online (Sandbox Code Playgroud)
这是一个老问题,但我认为我会做出贡献以防万一.在我的项目中,我为任何Json请求使用单独的模型.模型通常与具有"Json"前缀的域对象具有相同的名称.使用AutoMapper映射模型.通过让json模型声明一个字符串属性是域类的枚举,AutoMapper将解析为它的字符串表示.
如果您想知道,我需要Json序列化类的单独模型,因为内置的序列化器会提供循环引用.
希望这有助于某人.
以防万一有人发现上述不足,我最终解决了这个过载:
JsonConvert.SerializeObject(objToSerialize, Formatting.Indented, new Newtonsoft.Json.Converters.StringEnumConverter())
Run Code Online (Sandbox Code Playgroud)
在.net core 3中,现在可以通过System.Text.Json中的内置类来实现:
var person = new Person();
// Create and add a converter which will use the string representation instead of the numeric value.
var stringEnumConverter = new System.Text.Json.Serialization.JsonStringEnumConverter();
JsonSerializerOptions opts = new JsonSerializerOptions();
opts.Converters.Add(stringEnumConverter);
// Generate json string.
var json = JsonSerializer.Serialize<Person>(person, opts);
Run Code Online (Sandbox Code Playgroud)
为JsonStringEnumConverter特定属性配置属性装饰:
using System.Text.Json.Serialization;
[JsonConverter(typeof(JsonStringEnumConverter))]
public Gender Gender { get; set; }
Run Code Online (Sandbox Code Playgroud)
如果要始终将枚举转换为字符串,请将属性放在枚举本身。
[JsonConverter(typeof(JsonStringEnumConverter))]
enum Gender { Male, Female }
Run Code Online (Sandbox Code Playgroud)