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

带[Serializable]的C#类接收Axios POST时字段为空的问题

问题原因及解决方案

为什么[Serializable]会导致接收对象为空?

当C#类标记了[Serializable]特性时,ASP.NET WebAPI默认使用的Json.NET(Newtonsoft.Json)序列化器会切换行为:优先序列化类的字段而非公开属性。你的类里的公开属性对应的是编译器自动生成的私有字段(比如_Location、_Medium),但前端传递的JSON键是属性名(比如Medium),两者命名不匹配,导致无法正确绑定值。

另外你的SomeLocationInfo类构造函数是私有(默认无访问修饰符即为private),这也会让序列化器难以正常创建实例并初始化属性,进一步加剧了绑定失败的问题。

额外注意:前端传的字段名和后端属性还存在不匹配(比如前端SampleLocation对应后端Location,前端ParameterPairs对应后端ParameterPairsInfo),这也是需要修正的点——移除特性后能正常工作,是因为Json.NET默认会处理属性映射,但带[Serializable]时这个逻辑被覆盖了。

无需新建类的复用方案

方案1:用特性覆盖[Serializable]的序列化行为

在类上添加[JsonObject(MemberSerialization.OptIn)],并给每个需要绑定的属性加上[JsonProperty],强制Json.NET使用属性级序列化,同时修正构造函数为public:

[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class SomeLocationInfo
{
    [JsonProperty]
    public string Location { get; set; }
    [JsonProperty]
    public string Medium { get; set; }
    [JsonProperty]
    public List<ParameterPairs> ParameterPairsInfo { get; set; }

    public SomeLocationInfo()
    {
        ParameterPairsInfo = new List<ParameterPairs>();
    }
}

[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class ParameterPairs
{
    [JsonProperty]
    public string Parameter { get; set; }
    [JsonProperty]
    public string Units { get; set; }
}

同时调整前端请求的字段名,和后端属性完全对应:

const locationData = {
    Location: locationName, // 把SampleLocation改成Location
    Medium: mediumName,
    ParameterPairsInfo: [{ // 把ParameterPairs改成ParameterPairsInfo
        Parameter: parameterName,
        Units: unitAmount
    }]
};

方案2:全局配置Json.NET忽略[Serializable]特性

在WebAPI的WebApiConfig.cs的Register方法中添加全局序列化设置,让所有带[Serializable]的类都按属性序列化:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 其他配置...
        
        // 忽略Serializable特性,强制使用属性序列化
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver
        {
            IgnoreSerializableAttribute = true
        };
    }
}

这个方法无需修改每个类的特性,一劳永逸。同样需要修正前端字段名和后端属性的匹配问题,以及把SomeLocationInfo的构造函数改为public。

方案3:补充DataContract特性兼容旧代码

如果旧WebAPI代码使用DataContractSerializer,可以给类添加[DataContract]和[DataMember]特性,同时保留[Serializable],这样新旧序列化器都能正确处理:

[Serializable]
[DataContract]
public class SomeLocationInfo
{
    [DataMember]
    public string Location { get; set; }
    [DataMember]
    public string Medium { get; set; }
    [DataMember]
    public List<ParameterPairs> ParameterPairsInfo { get; set; }

    public SomeLocationInfo()
    {
        ParameterPairsInfo = new List<ParameterPairs>();
    }
}

[Serializable]
[DataContract]
public class ParameterPairs
{
    [DataMember]
    public string Parameter { get; set; }
    [DataMember]
    public string Units { get; set; }
}

这种方式既能满足旧代码的序列化需求,又能让新WebAPI的Json.NET正确绑定属性值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:07:49