c# - net - stringenumconverter example




JSON序列化為字符串的枚舉 (13)

@Iggy答案將c#enum的JSON序列化設置為僅適用於ASP.NET的Web應用程序(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
}

我有一個包含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" }

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; }
}

下面是一個簡單的解決方案,它將服務器端C#枚舉序列化為JSON,並使用結果填充客戶端<select>元素。 這適用於簡單的枚舉和位標記枚舉。

我已經包含了端到端的解決方案,因為我認為大多數人想要將C#枚舉序列化為JSON也可能會使用它來填充<select>下拉列表。

開始:

示例枚舉

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

一個使用按位或運算來生成權限系統的複雜枚舉。 所以你不能依賴簡單索引[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框架來處理Get請求。 它使用了Nancy的Response.AsJson()輔助方法 - 但不用擔心,你可以使用任何標準的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>

不,沒有可以使用的特殊屬性。 JavaScriptSerializerenums序列化為它們的數值而不是它們的字符串表示。 您需要使用自定義序列化來將enum序列化為名稱而不是數值。

編輯:正如@OmerBakhari所指出的,JSON.net涵蓋了這個用例(通過屬性[JsonConverter(typeof(StringEnumConverter))]和其他許多未由內置的.net序列化器處理的內容。 這是一個比較序列化器的特性和功能的鏈接


如果您不想使用JsonConverter屬性,也可以將轉換器添加到JsonConverter

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

它將在序列化過程中看到的每個enum都有效。



對於.Net Core Web Api: -

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
    ...
}

您可以通過調用JsonConverter.SerializeObject來創建JsonSerializerSettings,如下所示:

var result = JsonConvert.SerializeObject
            (
                dataObject,
                new JsonSerializerSettings
                {
                    Converters = new [] {new StringEnumConverter()}
                }
            );

我無法像在頂部答案(@ob)中那樣更改源模型,我也不想像@Iggy那樣在全局範圍內註冊它。 所以我結合了https://.com/a/2870420/237091和@ Iggy的https://.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()
        }
    })

我發現Json.NET通過StringEnumConverter屬性提供了我正在尋找的確切功能:

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

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

有關StringEnumConverter文檔的更多詳細信息。


這是newtonsoft.json的答案

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

這是一個老問題,但我認為我會為了以防萬一。 在我的項目中,我使用單獨的模型來處理任何Json請求。 模型通常與具有“Json”前綴的域對象具有相同的名稱。 模型使用AutoMapper進行映射。 通過讓json模型聲明一個字段屬性,該屬性是域類的枚舉,AutoMapper將解析為字符串表示。

如果您想知道,我需要單獨的Json序列化類的模型,因為內置的序列化器會提供循環引用。

希望這可以幫助某人。


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]  
);




javascriptserializer