JavaScriptSerializer - JSON serialization of enum as string

后端 未结 27 1730
耶瑟儿~
耶瑟儿~ 2020-11-22 03:22

I have a class that contains an enum property, and upon serializing the object using JavaScriptSerializer, my json result contains the integer valu

相关标签:
27条回答
  • 2020-11-22 04:10

    I have put together all of the pieces of this solution using the Newtonsoft.Json library. It fixes the enum issue and also makes the error handling much better, and it works in IIS hosted services. It's quite a lot of code, so you can find it on GitHub here: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

    You have to add some entries to your Web.config to get it to work, you can see an example file here: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config

    0 讨论(0)
  • 2020-11-22 04:12

    No there is no special attribute you can use. JavaScriptSerializer serializes enums to their numeric values and not their string representation. You would need to use custom serialization to serialize the enum as its name instead of numeric value.


    If you can use JSON.Net instead of JavaScriptSerializer than see answer on this question provided by OmerBakhari: JSON.net covers this use case (via the attribute [JsonConverter(typeof(StringEnumConverter))]) and many others not handled by the built in .net serializers. Here is a link comparing features and functionalities of the serializers.

    0 讨论(0)
  • 2020-11-22 04:12

    Here is a simple solution that serializes a server-side C# enum to JSON and uses the result to populate a client-side <select> element. This works for both simple enums and bitflag enums.

    I have included the end-to-end solution because I think most people wanting to serialize a C# enum to JSON will also probably be using it to fill a <select> drop-down.

    Here goes:

    Example Enum

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

    A complex enum that uses bitwise ORs to generate a permissions system. So you can't rely on the simple index [0,1,2..] for the integer value of the enum.

    Server Side - 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);
    };
    

    The code above uses the NancyFX framework to handle the Get request. It uses Nancy's Response.AsJson() helper method - but don't worry, you can use any standard JSON formatter as the enum has already been projected into a simple anonymous type ready for serialization.

    Generated JSON

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

    Client Side - 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 Before

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

    HTML After

    <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>
    
    0 讨论(0)
  • 2020-11-22 04:16

    Add the below to your global.asax for JSON serialization of c# enum as string

      HttpConfiguration config = GlobalConfiguration.Configuration;
                config.Formatters.JsonFormatter.SerializerSettings.Formatting =
                    Newtonsoft.Json.Formatting.Indented;
    
                config.Formatters.JsonFormatter.SerializerSettings.Converters.Add
                    (new Newtonsoft.Json.Converters.StringEnumConverter());
    
    0 讨论(0)
  • 2020-11-22 04:16

    For .Net Core :-

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
        ...
    }
    
    0 讨论(0)
  • @Iggy answer sets JSON serialization of c# enum as string only for ASP.NET (Web API and so).

    But to make it work also with ad hoc serialization, add following to your start class (like 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;
    });
    

    More information on the Json.NET page

    Additionally, to have your enum member to serialize/deserialize to/from specific text, use the

    System.Runtime.Serialization.EnumMember

    attribute, like this:

    public enum time_zone_enum
    {
        [EnumMember(Value = "Europe/London")] 
        EuropeLondon,
    
        [EnumMember(Value = "US/Alaska")] 
        USAlaska
    }
    
    0 讨论(0)
提交回复
热议问题