ChatGPT解决这个技术问题 Extra ChatGPT

JavaScriptSerializer - 枚举的 JSON 序列化为字符串

我有一个包含 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,它就没有任何实际用途,就像使用页面方法和,最重要的是,根据问题的要求。接受的答案说不可能。我的回答虽然有点破解,但完成了工作。

A
Alexei Levenkov

我发现 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(香蕉建议): JsonConvert.SerializeObject(MyObject, new Newtonsoft.Json.Converters.StringEnumConverter());

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


跟随链接描述如何在 asp.net mvc 应用程序 james.newtonking.com/archive/2008/10/16/… 中使用它
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 }
A
Alexei Levenkov

不,没有可以使用的特殊属性。 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
I
Iggy

将以下内容添加到 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 的第一个序列化程序设置与操作问题无关。
J
Juri

@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())
JsonConvert 您放置在 ConfigureServices 中还是在 NET CORE 2 中的 Configure 中?
C
Community

我无法像(@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 提到的,这是我使用每个 Enum 值的字符串值而不是数字值序列化 List<AnEnumType> 属性的解决方法。
B
Björn

在 .net core 3 中,这现在可以通过 System.Text.Json 中的内置类实现(edit:System.Text.Json 也可作为 .net core 的 NuGet 包使用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 }

干净整洁。
A
Ashkan S

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 用于枚举成员,它适用于简单的反序列化任务。遗憾的是,在使用 JToken 进行手动调整时,它会被忽略。令人高兴的是 EnumMemberAttribute 就像一个魅力。谢谢!
s
st1

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


S
Stephen Kennedy

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

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

    string GenderString { get { return Gender.ToString(); } }
}

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

此版本的 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 属性。感谢您的大喊,但请注意您拼错了我的名字:)
G
GuCa

这是 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)]
S
Serj-Tm

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

public void ConfigureServices(IServiceCollection services)
{

    services
        .AddControllers()
        .AddJsonOptions(options => 
           options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())
        );

    //...
 }

M
Mariusz Jamro

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

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

它适用于在序列化过程中看到的每个 enum


b
biofractal

这是一个将服务器端 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>

Y
Yahya Hussein

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

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

Y
Yang Zhang

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

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

G
Greg R Taylor

注意到当有描述属性时,序列化没有答案。

这是我支持 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; }

P
PeteGO

对于 .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 => f.Converters.Add(new StringEnumConverter())); 一样使用。
А
Андрей Петрашевич

用这个:

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

[Serializable]
[JsonConverter(typeof(StringEnumConverter))]
public enum Gender { Male, Female }

h
hngr18

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

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

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

对于 .NET 6.0,如果您想使用内置 JsonSerializer (System.Text.Json)

然后,它是开箱即用的,您只需要使用内置的 JsonStringEnumConverter 属性。例如:

[JsonConverter(typeof(JsonStringEnumConverter))]
public SomeEnumType EnumProperty { get; set; }

就是这样,但请确保您的 SomeEnumType 包含具有确切字符串值的值,否则它将引发异常。外壳似乎不敏感。

参考:https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties?pivots=dotnet-6-0#enums-as-strings


我们将它连接到 Program 类中,用于所有转换,如下所示:services.AddControllers().AddJsonOptions(a => a.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()))。你怎么看?
A
Ales Potocnik Hahonina

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

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

希望这可以帮助某人。


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

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

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


D
Dusty

一个更面向未来的选择

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

用法:

[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:仍然会引发异常,但它会导致整个反序列化过程失败(并且它很可能在堆栈中更远的地方被捕获)。您是否需要这种容错是您的用例的产物。
k
kenny

不确定这是否仍然相关,但我不得不直接写入一个 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“规则”开始的小写字母。将其格式化为干净的缩进并忽略输出中的空值。 Aslo 通过添加 StringEnumConverter 它打印带有字符串值的枚举。

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

用法:

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

B
Benjamin Swedlove

对于 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)

J
Jon Grant

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

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


M
Michael K

对于在 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();

z
zilong
        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();

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