我有一个包含枚举属性的类,在使用JavaScriptSerializer序列化对象时,我的json结果包含枚举的整数值,而不是它的字符串“name”。有没有一种方法来获得枚举作为字符串在我的json而不必创建一个自定义JavaScriptConverter?也许有一个属性,我可以装饰枚举定义,或对象属性?

举个例子:

enum Gender { Male, Female }

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

期望的JSON结果:

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

理想情况下,用内置的。net框架类来寻找答案,如果没有可能的替代方案(如Json.net)也是受欢迎的。


当前回答

new JavaScriptSerializer().Serialize(  
    (from p   
    in (new List<Person>() {  
        new Person()  
        {  
            Age = 35,  
            Gender = Gender.Male  
        }  
    })  
    select new { Age =p.Age, Gender=p.Gender.ToString() }  
    ).ToArray()[0]  
);

其他回答

如果你不想使用JsonConverter属性,你也可以给JsonSerializer添加一个转换器:

string SerializedResponse = JsonConvert.SerializeObject(
     objToSerialize, 
     new Newtonsoft.Json.Converters.StringEnumConverter()
); 

它将适用于它在序列化期间看到的每个枚举。

你可以使用内置的JavaScriptSerializer来实现这个功能。通过将枚举转换为Uri,可以将其编码为字符串。

我已经描述了如何对日期执行此操作,但它也可以用于枚举。 自定义DateTime JSON格式。net JavaScriptSerializer。

对于任何在22年5月就需要。net 6解决方案并且仍在使用Newtonsoft的人来说,你可以像这样全局注册转换器:

var builder = WebApplication.CreateBuilder(args);
...
builder.Services.AddControllers(options => options.RespectBrowserAcceptHeader = true)
.AddNewtonsoftJson(opt =>
{
    opt.SerializerSettings.ContractResolver = new DefaultContractResolver();
    opt.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
})
.AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters();

将以下内容添加到全局中。asax用于JSON序列化c# enum为字符串

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

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

注意,当存在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");
    }
}

枚举:

public enum FooEnum
{
    // Will be serialized as "Not Applicable"
    [Description("Not Applicable")]
    NotApplicable,

    // Will be serialized as "Applicable"
    Applicable
}

用法:

[JsonConverter(typeof(CustomStringEnumConverter))]
public FooEnum test { get; set; }