【问题标题】:JavaScriptSerializer - JSON serialization of enum as stringJavaScriptSerializer - 枚举的 JSON 序列化为字符串
【发布时间】:2019-02-28 15:21:03
【问题描述】:

我有一个包含enum 属性的类,并且在使用JavaScriptSerializer 序列化对象时,我的json 结果包含枚举的整数值而不是它的string“名称”。有没有办法在我的 json 中将枚举作为 string 而不必创建自定义 JavaScriptConverter?也许有一个属性可以用来装饰enum 定义或对象属性?

举个例子:

enum Gender { Male, Female }

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

所需的 JSON 结果:

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

如果不可能的话,欢迎使用内置的 .NET 框架类寻找答案(如 Json.net)。

【问题讨论】:

  • 改成哪个?最高投票的答案实际上并没有回答这个问题 - 是的,它在其他情况下很有用,因此投票,但如果你坚持使用 MS JavaScriptSerializer,它就没有任何实际用途,就像使用页面方法和,最重要的是,根据问题的要求。接受的答案说不可能。我的回答虽然有点技巧,但完成了工作。

标签: c# asp.net json enums javascriptserializer


【解决方案1】:

没有可以使用的特殊属性。 JavaScriptSerializerenums 序列化为它们的数值而不是它们的字符串表示形式。您需要使用自定义序列化将enum 序列化为其名称而不是数值。


如果您可以使用 JSON.Net 代替 JavaScriptSerializer,而不是参见 OmerBakhari 提供的 answer on this question:JSON.net 涵盖了此用例(通过属性 [JsonConverter(typeof(StringEnumConverter))])以及许多其他未由内置处理.net 序列化程序。 Here is a link comparing features and functionalities of the serializers.

【讨论】:

  • @Fabzter -- 你的解决方案使用 Newtonsoft 的 Json 与我合作
  • @BornToCode Json.NET 是 ASP.NET 默认使用的序列化器。
  • @BrainSlugs83 - 问题是关于使用 JavaScriptSerializer,而不是 Json.NET(如果你查看修订历史,你会看到有一个编辑来澄清这一点),如果你使用 JavaScriptSerializer JsonConverter 属性不起作用。
  • “Json.NET 是 ASP.NET 默认使用的序列化程序”——当问题被提出或回答时,情况并非如此。 (但最重要的是答案的清晰)
  • [JsonConverter(typeof(StringEnumConverter))] 用于 newtonsoft
【解决方案2】:

我发现Json.NET 通过StringEnumConverter 属性提供了我正在寻找的确切功能:

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

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

更多详情请访问StringEnumConverter documentation

还有其他地方可以更全局地配置此转换器:

  • 如果您希望枚举始终被序列化/反序列化为字符串,则枚举本身:

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
    
  • 如果有人想避免属性修饰,您可以将转换器添加到您的 JsonSerializer(Bjørn Egil 建议):

    serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); 
    

    并且它将适用于它在序列化期间看到的每个枚举(由Travis 建议)。

  • 或 JsonConverter(banana 建议):

    JsonConvert.SerializeObject(MyObject, 
        new Newtonsoft.Json.Converters.StringEnumConverter());
    

此外,您可以使用StringEnumConverter(NamingStrategy, Boolean) 构造函数控制大小写以及是否仍接受数字。

【讨论】:

  • 点击链接了解如何在asp.net mvc应用程序中使用它james.newtonking.com/archive/2008/10/16/…
  • 这里是该函数的链接:james.newtonking.com/projects/json/help/html/…
  • HttpConfiguration 配置 = GlobalConfiguration.Configuration; config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; config.Formatters.JsonFormatter.SerializerSettings.Converters.Add (new Newtonsoft.Json.Converters.StringEnumConverter());
  • 请注意默认情况下 ASP.NET MVC 不使用 Json.Net 作为 json 序列化器,需要扩展 Controller 或手动覆盖每个序列化。
  • 您可以自定义转换器(例如,camelCase 输出):new StringEnumConverter { CamelCaseText = true }
【解决方案3】:

您实际上可以通过内置的 JavaScriptSerializer 使用 JavaScriptConverter 来完成此操作。通过将枚举转换为 Uri,您可以将其编码为字符串。

我已经描述了如何为日期执行此操作,但它也可以用于枚举。 Custom DateTime JSON Format for .NET JavaScriptSerializer.

【讨论】:

    【解决方案4】:

    这很容易通过将ScriptIgnore 属性添加到Gender 属性,使其不被序列化,并添加一个GenderString 属性 被序列化:

    class Person
    {
        int Age { get; set; }
    
        [ScriptIgnore]
        Gender Gender { get; set; }
    
        string GenderString { get { return Gender.ToString(); } }
    }
    

    【讨论】:

    • 让我试着解释一下。根据设计模式,这个解决方案是不正确的。您根据视图目的修改了模型。但是模型必须只包含数据并且不关心演示。您必须将此功能移至另一层。
    • 其实Model是用来从controller传递数据的,ant是controller,不关心表现。自动化属性(此处为 GenderString)的引入并没有破坏控制器,它仍然使用 Gender 属性,但为视图提供了方便的访问。逻辑解决方案。
    • @RredCat 在“视图模型”中拥有特定于视图的属性并没有错。恕我直言,错误是不要将视图模型与域模型分开:blogs.msdn.com/b/simonince/archive/2010/01/26/…
    • @RredCat,即使根据某种模式它是不正确的,OP 对此也只字未提,所以这确实是一个正确的答案。 (即使我在哲学上可能同意你的观点。)
    • 此评论线程中的迂腐荒谬的自行车脱落令人着迷。
    【解决方案5】:

    这是一个老问题,但我想我会做出贡献以防万一。在我的项目中,我对任何 Json 请求都使用单独的模型。模型通常与带有“Json”前缀的域对象具有相同的名称。使用AutoMapper 映射模型。通过让 json 模型声明一个作为域类枚举的字符串属性,AutoMapper 将解析为它的字符串表示形式。

    如果您想知道,我需要 Json 序列化类的单独模型,因为否则内置序列化程序会提供循环引用。

    希望这对某人有所帮助。

    【讨论】:

    • 很高兴了解 Automapper 的特性 ;-) [ScriptIgnore] 属性将删除循环引用
    • 哦。不知道属性。谢谢!你会在你的 Pocos 上使用它吗?我已经对任何 Poco 属性使用 MetadataType 定义,只是为了保持它们干净。该属性仍然可以通过元数据工作吗?
    【解决方案6】:

    此版本的 Stephen 的 answer 不会更改 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; 
            }
        }
    }
    

    【讨论】:

    • 我相信这对DataContractJsonSerializer 而不是JavaScriptSerializer 有效
    • 使用本机 .NET 框架序列化程序很简单并为我解决了问题。
    • 对我来说最好的解决方案,因为我不允许使用 3rd 方库(ISO 合规性问题)
    • 这当然不适用于问题中的序列化程序类型。 JavaScriptSerializer 序列化所有未被忽略的内容,而 DataContractJsonSerializer 需要 DataMember 属性。感谢您的喊叫,但请注意您拼错了我的名字:)
    【解决方案7】:

    这是一个简单的解决方案,它将服务器端 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
    }
    

    使用按位 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);
    };
    

    上面的代码使用 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>
    

    【讨论】:

      【解决方案8】:

      将以下内容添加到 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());
      

      【讨论】:

      • 出于某种原因,我无法让它工作。 Fiddler 显示一个顽固的 2 而不是“警告”,即使有这个。另外 - 为什么要将 Formatting 更改为 Indented
      • 此示例的第三行已添加到 App_start/webapiconfig.cs 文件中,并在 ASP.NET Web API 2.1 项目中为我做了一个技巧,以返回 REST 中枚举值的字符串(json fomat ) 调用。
      • 有没有办法只在每个请求范围内设置这个属性?
      • @AnestisKivranoglou 只需为每个请求使用自定义的 json 序列化程序,并使用它自己的设置。
      • indented的第一个序列化器设置与op问题无关。
      【解决方案9】:

      我无法像(@ob.)的最佳答案那样更改源模型,并且我不想像 @Iggy 那样在全局范围内注册它。所以我结合了https://stackoverflow.com/a/2870420/237091 和@Iggy 的https://stackoverflow.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()
              }
          })
      

      【讨论】:

      • 如果你有一个像这样的属性 List 这也很好
      • 正如@Bogdan 提到的,这是我使用每个枚举值的字符串值而不是数字值序列化List&lt;AnEnumType&gt; 属性的解决方法。
      【解决方案10】:

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

      更多信息on the Json.NET page

      此外,要让您的枚举成员对特定文本进行序列化/反序列化,请使用

      System.Runtime.Serialization.EnumMember

      属性,像这样:

      public enum time_zone_enum
      {
          [EnumMember(Value = "Europe/London")] 
          EuropeLondon,
      
          [EnumMember(Value = "US/Alaska")] 
          USAlaska
      }
      

      【讨论】:

      • 谢谢!我只是在寻找[EnumMember]
      • CamelCaseText 属性现在被标记为过时。实例化转换器的新方法:new StringEnumConverter(new CamelCaseNamingStrategy())
      • 您在 ConfigureServices 中或在 NET CORE 2 中的 Configure 中放置的 JsonConvert?
      【解决方案11】:

      这是 newtonsoft.json 的答案

      enum Gender { Male, Female }
      
      class Person
      {
          int Age { get; set; }
      
          [JsonConverter(typeof(StringEnumConverter))]
          Gender Gender { get; set; }
      }
      

      【讨论】:

      • 感谢您的回答,对我帮助很大!如果你想在 PascalCase 中定义你的枚举,但是你希望它在 camelCase 中被序列化,那么你需要像这样将true 添加到你的 JsonConverter 类型中:[JsonConverter(typeof(StringEnumConverter), true)]
      【解决方案12】:

      您可以通过调用 JsonConverter.SerializeObject 来创建 JsonSerializerSettings,如下所示:

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

      【讨论】:

        【解决方案13】:

        注意到有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; }
        

        【讨论】:

          【解决方案14】:

          如果您不想使用JsonConverter 属性,也可以将转换器添加到您的JsonSerializer

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

          它适用于它在序列化期间看到的每个enum

          【讨论】:

            【解决方案15】:
            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]  
            );
            

            【讨论】:

              【解决方案16】:

              以防万一有人发现上述内容不足,我最终解决了这个重载:

              JsonConvert.SerializeObject(objToSerialize, Formatting.Indented, new Newtonsoft.Json.Converters.StringEnumConverter())
              

              【讨论】:

              • 这对于我当前的用例来说是一个很好的解决方案:我不想更改序列化程序的默认值,而且我在使用属性时遇到问题,因为我的属性是 IList 类型的。
              【解决方案17】:

              我使用Newtonsoft.Json 库将这个解决方案的所有部分组合在一起。它修复了枚举问题,也使错误处理变得更好,并且可以在 IIS 托管服务中运行。代码挺多的,可以在 GitHub 上找到:https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

              您必须在Web.config 中添加一些条目才能使其正常工作,您可以在此处查看示例文件: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config

              【讨论】:

                【解决方案18】:

                对于 .Net 核心:-

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

                【讨论】:

                • 如果这是来自Microsoft.AspNetCore.Mvc.Formatters.Json NuGet 包的那个,它似乎只是IMvcCoreBuilder 上的扩展方法,而不是IMvcBuilder。所以它被用作services.AddMvcCore().AddJsonFormatters(f =&gt; f.Converters.Add(new StringEnumConverter()));
                【解决方案19】:

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

                【讨论】:

                • 我将JsonPropertyAttribute 用于枚举成员,它适用于简单的反序列化任务。可悲的是,在使用 JTokens 进行手动调整时,它会被忽略。很高兴EnumMemberAttribute 就像一个魅力。谢谢!
                【解决方案20】:

                ASP.NET Core 方式:

                public class Startup
                {
                  public IServiceProvider ConfigureServices(IServiceCollection services)
                  {
                    services.AddMvc().AddJsonOptions(options =>
                    {
                      options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
                    });
                  }
                }
                

                https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e

                【讨论】:

                  【解决方案21】:

                  对于 ASP.Net 核心,只需将以下内容添加到您的启动类:

                  JsonConvert.DefaultSettings = (() =>
                          {
                              var settings = new JsonSerializerSettings();
                              settings.Converters.Add(new StringEnumConverter { AllowIntegerValues = false });
                              return settings;
                          });
                  

                  【讨论】:

                    【解决方案22】:

                    不确定这是否仍然相关,但我必须直接写入一个 json 文件,然后我想出了以下将几个 stackoverflow 答案拼凑在一起

                    public class LowercaseJsonSerializer
                    {
                        private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
                        {
                            ContractResolver = new LowercaseContractResolver()
                        };
                    
                        public static void Serialize(TextWriter file, object o)
                        {
                            JsonSerializer serializer = new JsonSerializer()
                            {
                                ContractResolver = new LowercaseContractResolver(),
                                Formatting = Formatting.Indented,
                                NullValueHandling = NullValueHandling.Ignore
                            };
                            serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
                            serializer.Serialize(file, o);
                        }
                    
                        public class LowercaseContractResolver : DefaultContractResolver
                        {
                            protected override string ResolvePropertyName(string propertyName)
                            {
                                return Char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1);
                            }
                        }
                    }
                    

                    它确保我所有的 json 键都是根据 json“规则”开始的小写字母。将其格式化为干净的缩进并忽略输出中的空值。此外,通过添加 StringEnumConverter,它会打印带有字符串值的枚举。

                    我个人觉得这是我能想到的最干净的方法,而不必用注释弄脏模型。

                    用法:

                        internal void SaveJson(string fileName)
                        {
                            // serialize JSON directly to a file
                            using (StreamWriter file = File.CreateText(@fileName))
                            {
                                LowercaseJsonSerializer.Serialize(file, jsonobject);
                            }
                        }
                    

                    【讨论】:

                      【解决方案23】:

                      对于 VB.net,我发现了以下作品:

                      Dim sec = New Newtonsoft.Json.Converters.StringEnumConverter()
                      sec.NamingStrategy() = New Serialization.CamelCaseNamingStrategy
                      
                      Dim JSON_s As New JsonSerializer
                      JSON_s.Converters.Add(sec)
                      
                      Dim jsonObject As JObject
                      jsonObject = JObject.FromObject(SomeObject, JSON_s)
                      Dim text = jsonObject.ToString
                      
                      IO.File.WriteAllText(filePath, text)
                      

                      【讨论】:

                        【解决方案24】:

                        更面向未来的选项

                        面对同样的问题,我们确定我们需要一个自定义版本的 StringEnumConverter 以确保我们的枚举值可以随着时间的推移而扩展,而不会在反序列化方面发生灾难性的中断(请参阅下面的背景)。使用下面的 SafeEnumConverter 可以完成反序列化,即使负载包含没有命名定义的枚举值,更接近于 int 到枚举转换的工作方式。

                        用法:

                        [SafeEnumConverter]
                        public enum Colors
                        {
                            Red,
                            Green,
                            Blue,
                            Unsupported = -1
                        }
                        

                        [SafeEnumConverter((int) Colors.Blue)]
                        public enum Colors
                        {
                            Red,
                            Green,
                            Blue
                        }
                        

                        来源:

                        public class SafeEnumConverter : StringEnumConverter
                        {
                            private readonly int _defaultValue;
                        
                            public SafeEnumConverter()
                            {
                                // if you've been careful to *always* create enums with `0` reserved
                                // as an unknown/default value (which you should), you could use 0 here. 
                                _defaultValue = -1;
                            }
                        
                            public SafeEnumConverter(int defaultValue)
                            {
                                _defaultValue = defaultValue;
                            }
                        
                            /// <summary>
                            /// Reads the provided JSON and attempts to convert using StringEnumConverter. If that fails set the value to the default value.
                            /// </summary>
                            /// <returns>The deserialized value of the enum if it exists or the default value if it does not.</returns>
                            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
                            {
                                try
                                {
                                    return base.ReadJson(reader, objectType, existingValue, serializer);
                                }
                                catch
                                {
                                    return Enum.Parse(objectType, $"{_defaultValue}");
                                }
                            }
                        
                            public override bool CanConvert(Type objectType)
                            {
                                return base.CanConvert(objectType) && objectType.GetTypeInfo().IsEnum;
                            }
                        }
                        

                        背景

                        当我们考虑使用StringEnumConverter 时,我们遇到的问题是我们还需要在添加新枚举值的情况下进行被动处理,但并不是每个客户端都会立即意识到新值。在这些情况下,使用 Newtonsoft JSON 打包的StringEnumConverter 会抛出类似于“将值 SomeString 转换为类型 EnumType 时出错”的JsonSerializationException,然后整个反序列化过程失败。这对我们来说是一个交易破坏者,因为即使客户端计划忽略/丢弃它不理解的属性值,它仍然需要能够反序列化剩余的有效负载!

                        【讨论】:

                        • 对 .NET 来说还是比较新的,但有人告诉我,出于性能原因,要避免 try catch 表达式。如果是这样的话,序列化器不是一个不好的地方吗?
                        • @laventnc try...catch 本身不会影响性能,但如果引发异常,则会产生性能开销。这个实现的重点是容错......不允许单个未知的枚举值来阻止整个 JSON 有效负载反序列化。比较基础StringEnumConveter:仍然会引发异常,但它会导致整个反序列化过程失败(并且它可能会在堆栈更远的地方被捕获)。您是否需要这种容错是您的用例的产物。
                        【解决方案25】:

                        在 .net core 3 中,这现在可以通过 System.Text.Json 中的内置类实现(编辑:System.Text.Json 也可作为 NuGet 包用于.net core 2.0 和.net framework 4.7.2 及更高版本根据docs):

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

                        JsonStringEnumConverter配置特定属性的属性修饰:

                        using System.Text.Json.Serialization;
                        
                        [JsonConverter(typeof(JsonStringEnumConverter))]
                        public Gender Gender { get; set; }
                        

                        如果您想始终将枚举转换为字符串,请将属性放在枚举本身。

                        [JsonConverter(typeof(JsonStringEnumConverter))] 
                        enum Gender { Male, Female }
                        

                        【讨论】:

                        • 漂亮干净。
                        【解决方案26】:

                        带有 System.Text.Json 的 Asp.Net Core 3

                        public void ConfigureServices(IServiceCollection services)
                        {
                        
                            services
                                .AddControllers()
                                .AddJsonOptions(options => 
                                   options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())
                                );
                        
                            //...
                         }
                        

                        【讨论】:

                          【解决方案27】:
                                  Person p = new Person();
                                  p.Age = 35;
                                  p.Gender = Gender.Male;
                                  //1.  male="Male";
                                  string male = Gender.Male.ToString();
                          
                                  p.Gender = Gender.Female;
                          
                                  //2.  female="Female";
                                  string female = Enum.GetName(typeof(Gender), p.Gender);
                          
                                  JObject jobj = new JObject();
                                  jobj["Age"] = p.Age;
                                  jobj["Gender"] = male;
                                  jobj["Gender2"] = female;
                          
                                  //you result:  josn= {"Age": 35,"Gender": "Male","Gender2": "Female"}
                                  string json = jobj.ToString();
                          

                          【讨论】:

                            【解决方案28】:

                            使用这个:

                            using Newtonsoft.Json;
                            using Newtonsoft.Json.Converters;
                            
                            [Serializable]
                            [JsonConverter(typeof(StringEnumConverter))]
                            public enum Gender { Male, Female }
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2012-02-27
                              • 1970-01-01
                              • 2013-09-04
                              • 1970-01-01
                              • 2011-01-08
                              相关资源
                              最近更新 更多