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

ASP.NET Core控制器如何返回属性为空而非null的JSON数据

ASP.NET Core控制器返回空值而非null的JSON实现方式

以下几种方案可根据项目场景按需选择:

  • 方式1:模型属性初始化默认值(最推荐,无序列化配置侵入)
    在定义模型类时直接为对应类型设置默认值,创建实例时未显式赋值的属性会自动使用预设的默认值,序列化后自然得到空字符串/空数组。
    注意:ASP.NET Core默认仅序列化公共属性,示例中的公共字段需要改为属性,或额外配置序列化包含字段。
    代码示例:
public class Model
{
    public string name { get; set; }
    // 字符串默认值设为空字符串
    public string comment { get; set; } = "";
    // 列表默认值设为空集合
    public List<Contact> Contacts { get; set; } = new List<Contact>();
}
public class Contact
{
    public int id { get; set; }
    public string title { get; set; }
}

这种方式不需要修改任何序列化配置,只要new实例就会自动有默认值,符合C#语法规范,兼容性最好。

  • 方式2:全局配置System.Text.Json序列化规则(适用于项目全局需要统一处理null转空值的场景)
    ASP.NET Core 3.0+默认使用System.Text.Json作为序列化组件,可以通过自定义转换器实现全局null值转换:
    首先定义两个自定义转换器:
// 字符串null转空字符串转换器
public class StringNullToEmptyConverter : JsonConverter<string>
{
    public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return reader.GetString() ?? "";
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value ?? "");
    }
}

// 泛型列表null转空数组转换器
public class ListNullToEmptyConverter<T> : JsonConverter<List<T>>
{
    public override List<T>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Null)
        {
            return new List<T>();
        }
        return JsonSerializer.Deserialize<List<T>>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, List<T> value, JsonSerializerOptions options)
    {
        if (value == null)
        {
            writer.WriteStartArray();
            writer.WriteEndArray();
            return;
        }
        JsonSerializer.Serialize(writer, value, options);
    }
}

然后在Program.cs中注册全局序列化配置:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 注册字符串转换器
        options.JsonSerializerOptions.Converters.Add(new StringNullToEmptyConverter());
        // 注册Contact列表转换器,有其他列表类型可以对应添加
        options.JsonSerializerOptions.Converters.Add(new ListNullToEmptyConverter<Contact>());
        // 如果你的模型用的是公共字段而非属性,需要加下面这行配置
        options.JsonSerializerOptions.IncludeFields = true;
    });
  • 方式3:使用Newtonsoft.Json(Json.NET)时的全局配置
    如果项目仍在使用Newtonsoft.Json作为序列化组件,可以通过如下配置实现:
    首先安装Microsoft.AspNetCore.Mvc.NewtonsoftJsonNuget包,然后在Program.cs中配置:
builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include;
        // 自定义转换器处理列表和字符串,逻辑和System.Text.Json版本一致
        options.SerializerSettings.Converters.Add(new StringNullToEmptyConverterNewtonsoft());
        options.SerializerSettings.Converters.Add(new ListNullToEmptyConverterNewtonsoft());
    });
  • 方式4:单个属性标注特性(适用于仅少数属性需要处理的场景)
    如果不需要全局处理,只需要特定属性返回空值,可以直接在属性上加序列化特性:
    如果用System.Text.Json:
public class Model
{
    public string name { get; set; }
    [JsonConverter(typeof(StringNullToEmptyConverter))]
    public string comment { get; set; }
    [JsonConverter(typeof(ListNullToEmptyConverter<Contact>))]
    public List<Contact> Contacts { get; set; }
}

如果用Newtonsoft.Json:

public class Model
{
    public string name { get; set; }
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
    [DefaultValue("")]
    public string comment { get; set; }
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
    [DefaultValue(typeof(List<Contact>), "[]")]
    public List<Contact> Contacts { get; set; }
}

注意:如果模型使用公共字段而非公共属性,System.Text.Json默认不会序列化字段,需要手动配置JsonSerializerOptions.IncludeFields = true开启,建议优先使用属性定义模型成员,符合.NET开发规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:39:03