JSON 序列化的时候忽略无效的属性值

例如我拥有以下代码。

public class NewObject
{
    public int? TestValue { get; set; }

    public int? Age { get; set; }
}

当我为 TestValue 属性传入一个非法数据的时候,在使用 JSON.NET 进行反序列化时会抛出异常。例如我通过以下代码对一个字符串进行反序列化,如果不出意外的话会提示无效参数值的异常。

var newValue = JsonConvert.DeserializeObject<NewObject>(@"{""TestValue"":""FFFF"",""Age"":15}",settings);

通过 Stackoverflow 查询得知,可以通过在反序列化时指定 JsonSerializerSettings 对象进行忽略。

var settings = new JsonSerializerSettings
{
    Error = (obj, args2) =>
    {
        args2.ErrorContext.Handled = true;
    }
};

var newValue = JsonConvert.DeserializeObject<NewObject>(@"{""TestValue"":""FFFF"",""Age"":15}",settings);

这样,在进行反序列化的时候就可以忽略 TestValue 的无效值,为其属性设置为 null,并且成功解析 Age 的值。

如果你是 ASP.NET Core 的程序,可以通过 IServiceCollectionConfigure<T>() 方法来配置 Error 的处理器。

services.Configure<MvcJsonOptions>(jsonOptions =>
{
    // 忽略转换过程中的异常信息
    jsonOptions.SerializerSettings.Error += (sender, args) => { args.ErrorContext.Handled = true; };
});

转载于:https://www.cnblogs.com/myzony/p/10347652.html

<think>嗯,用户问的是在使用JSON.stringify序列化对象时,对象的方法会被如何处理。我需要先回忆一下JSON.stringify的工作原理。 首先,JSON.stringify的作用是将JavaScript对象转换成JSON字符串。但是JSON格式本身只支持一些基本的数据类型,比如对象、数组、字符串、数字、布尔值和null。而像函数、Symbol、undefined这些类型是被支持的。所以当遇到这些类型时,JSON.stringify会如何处理呢? 用户的问题是关于对象方法的,也就是函数。对象的方法其实就是对象的一个属性,其值是一个函数。当使用JSON.stringify序列化这个对象时,函数会被忽略吗?或者会被转换成什么? 根据之前的知识,JSON.stringify在序列化时会忽略函数、Symbol以及undefined这些值。如果是数组中的这些值,会被转换成null;如果是对象的属性,则会被直接省略。所以对象中的方法作为函数类型的属性,应该会被忽略会出现在结果字符串中。 过,用户可能想知道更详细的处理机制,或者有没有例外情况。比如,如果对象有一个toJSON方法,会会影响序列化的结果?因为如果对象有toJSON方法,JSON.stringify会调用这个方法,并使用返回的值进行序列化。这时候,如果toJSON方法返回了包含函数的属性,那会怎样?但实际上,即使这样,函数本身还是无法被序列化的,所以结果可能仍然是忽略或者被处理成其他形式。 另外,用户可能对如何保留方法有疑问,但JSON本身并支持函数,所以可能需要其他方法,比如序列化函数字符串,然后在解析时重新转换为函数。但这样做有安全风险,通常推荐。 需要确认是否在序列化过程中,函数会被完全忽略。例如,考虑一个对象: const obj = { name: "Alice", greet: function() { console.log("Hello"); } }; 使用JSON.stringify(obj)的结果应该是{"name":"Alice"},greet方法被忽略。 另外,如果对象中有嵌套结构,比如属性是另一个对象,里面的函数同样会被忽略。 可能还需要提到,如果使用replacer函数作为JSON.stringify的第二个参数,可以自定义序列化过程。但即使这样,如果返回函数,仍然会被忽略,因为JSON支持函数。 总结起来,JSON.stringify在处理对象方法时,会忽略函数类型的属性,会将它们包含在生成的JSON字符串中。如果需要保留方法,必须采用其他方式,但通常建议这样做,因为JSON用于数据交换,函数属于行为而非数据。</think>在 JavaScript 中,使用 `JSON.stringify()` 序列化对象时,**对象的方法(函数类型的属性)会被直接忽略**,会出现在最终的 JSON 字符串中。以下是详细说明和原理: --- ### 1. **JSON 的数据格式限制** JSON(JavaScript Object Notation)是一种**数据交换格式**,仅支持以下基本数据类型: - 对象(普通对象,非函数) - 数组 - 字符串 - 数字 - 布尔值 - `null` **支持的类型**包括: - 函数(方法) - `undefined` - `Symbol` - 循环引用的对象 - 其他特殊对象(如 `Date`、`Map`、`Set` 等,除非经过特殊处理)。 --- ### 2. **对象方法的处理逻辑** 当对象包含方法(函数属性)时,`JSON.stringify()` 会按以下规则处理: ```javascript const obj = { name: "Alice", greet: function() { console.log("Hello"); } }; const jsonStr = JSON.stringify(obj); // 输出结果:{"name":"Alice"}(greet 方法被忽略) ``` - **原因**:函数无法直接表示为 JSON 的有效值,因此会被静默跳过。 - **深层嵌套对象**:如果对象属性是嵌套对象,其内部的方法也会被忽略。 --- ### 3. **自定义序列化:`toJSON` 方法** 如果对象自身定义了 `toJSON()` 方法,`JSON.stringify()` 会优先调用该方法,并使用其返回值进行序列化。但**仍无法保留函数**: ```javascript const obj = { data: "test", log: function() { console.log(this.data); }, toJSON: function() { return { data: this.data }; // 手动排除函数属性 } }; JSON.stringify(obj); // 输出:{"data":"test"} ``` --- ### 4. **使用 `replacer` 参数尝试保留方法(无效)** 通过 `JSON.stringify()` 的第二个参数(`replacer` 函数),可以干预序列化过程,但**无法将函数转换为有效 JSON**: ```javascript const obj = { name: "Alice", greet: function() { return "Hello"; } }; const jsonStr = JSON.stringify(obj, (key, value) => { if (typeof value === "function") { return value.toString(); // 将函数转为字符串(但 JSON 支持) } return value; }); // 输出结果:{"name":"Alice","greet":"function() { return \"Hello\"; }"} // 注意:此 JSON 在解析时无法还原为函数,仅保留字符串形式。 ``` --- ### 5. **反序列化后恢复方法的局限性** 即使强行将函数转为字符串并序列化,反序列化时(`JSON.parse()`)**无法自动还原为可执行的函数**: ```javascript const jsonStr = '{"name":"Alice","greet":"function() { return \\"Hello\\"; }"}'; const parsedObj = JSON.parse(jsonStr); console.log(parsedObj.greet); // 输出字符串,而非函数 // 若需还原函数,需手动调用 eval(存在安全风险,推荐): parsedObj.greet = eval(`(${parsedObj.greet})`); parsedObj.greet(); // 输出 "Hello" ``` --- ### 总结 - **默认行为**:`JSON.stringify()` 会忽略对象的方法(函数属性)。 - **根本原因**:JSON 是数据描述格式,支持函数序列化。 - **解决方案**: - 若需保留方法逻辑,需在序列化前将函数转为字符串,反序列化时手动还原(需谨慎安全风险)。 - 推荐仅序列化数据属性,方法应在代码中独立维护。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值