You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#和Blazor中遍历this关键字并序列化为JSON的方法

解决方案:Blazor页面中动态序列化this的成员

问题原因

JsonConvert.SerializeObject(this)返回空字符串,核心原因是:

  • Blazor页面继承的ComponentBase包含大量内部/受保护的框架属性,默认情况下Json.NET只会序列化公共属性,如果你要序列化的是私有字段,会被直接跳过。
  • 即使开启非公共成员序列化,默认也会包含父类(ComponentBase)的冗余属性,导致要么为空,要么序列化一堆无用内容。

直接foreach遍历this报错,是因为页面类并非集合类型,没有实现IEnumerable接口,不能直接遍历实例本身。

可行方案

方案1:反射过滤当前类成员,构建字典后序列化

通过反射获取当前页面类自己定义的字段/属性,过滤掉父类的框架成员,再序列化,这是最精准的方式。

示例代码(假设你的页面类是Pages.Index):

using System.Reflection;
using Newtonsoft.Json;

// 在页面的方法(比如按钮点击事件)中执行
var targetMembers = this.GetType()
    // 获取当前实例的所有字段:公共+非公共
    .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
    // 只保留当前类定义的字段,排除ComponentBase等父类的成员
    .Where(member => member.DeclaringType == typeof(Index))
    // 转成字典,键为字段名,值为字段值
    .ToDictionary(member => member.Name, member => member.GetValue(this));

// 序列化字典
var jsonResult = JsonConvert.SerializeObject(targetMembers, Formatting.Indented);

如果要序列化属性而非字段,把GetFields换成GetProperties即可:

var targetMembers = this.GetType()
    .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
    .Where(member => member.DeclaringType == typeof(Index))
    .ToDictionary(member => member.Name, member => member.GetValue(this));

方案2:配置JsonSerializer,仅序列化当前类成员

通过自定义序列化配置,让Json.NET包含非公共成员,同时只处理当前页面类的成员:

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

var serializerSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver = new DefaultContractResolver
    {
        // 允许序列化非公共成员
        DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
        // 只序列化当前类定义的成员,忽略父类
        ShouldSerialize = (member) => member.DeclaringType == typeof(Index)
    }
};

var jsonResult = JsonConvert.SerializeObject(this, serializerSettings);

方案3:遍历this的成员(实现类似foreach的效果)

如果需要遍历成员而非序列化,同样用反射获取成员集合后遍历:

using System.Reflection;

// 获取当前类的所有字段
var fields = this.GetType()
    .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
    .Where(m => m.DeclaringType == typeof(Index));

foreach (var field in fields)
{
    string memberName = field.Name;
    object memberValue = field.GetValue(this);
    // 这里处理每个成员,比如打印、存入集合等
}

注意事项

  • 如果你用的是System.Text.Json而非Newtonsoft.Json,配置逻辑类似,需要设置JsonSerializerOptions的IncludeFields和自定义JsonConverter来过滤父类成员。
  • 反射会带来轻微的性能开销,但对于Blazor页面的场景(非高频调用)完全可以忽略。

内容的提问来源于stack exchange,提问作者freyfrey01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:33:24