使用Newtonsoft.Json序列化接口类型列表报错:接口无无参构造函数
问题描述
序列化实现IAccount接口的类列表时,抛出以下错误:
Newtonsoft.Json.JsonException: No parameterless constructor defined for 'StudentHousingFramework.Interfaces.IAccount'.
错误出现在这个序列化方法中:
public void Serealise<T>(string nameList, List<T> list) { path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, nameList); string jsonString = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, TypeNameHandling = TypeNameHandling.Auto }); ; File.WriteAllText(path, jsonString); }
待序列化的是实现IAccount接口的Room类列表,Room类定义:
public class Room : IAccount { public List<ITask> tasksToDo { get { return factory.manager.tasks.FindAll(w => w.claimer == this); } } public Login login { get; set; } public bool isOccupied { get; private set; } = true; public int id { get; set; } public string name { get { return "Room " + id; } } public Json json { get; set; } = new Json(); private Factory factory { get; set; } public Room(Factory factory, int id) { this.factory = factory; this.id = id; login = new Login(); } }
IAccount接口定义:
[JsonConverter (typeof(IAccount))] public interface IAccount { public Json json { get; set; } Login login { get; set; } int id { get; set; } string name { get;} }
解决步骤
1. 移除接口上错误的JsonConverter特性
接口IAccount上的[JsonConverter(typeof(IAccount))]完全错误——JsonConverter需要传入继承自JsonConverter的实现类,不能直接用接口本身。直接删掉这个特性:
public interface IAccount { public Json json { get; set; } Login login { get; set; } int id { get; set; } string name { get;} }
2. 确认TypeNameHandling配置生效
你已经设置了TypeNameHandling.Auto,这个配置会在序列化接口类型的对象时,自动在JSON中写入具体实现类的类型信息,确保后续反序列化能正确识别对象类型。如果序列化的是List<IAccount>而非List<Room>,这个配置必须保留。
3. 给Room类添加无参构造函数(针对反序列化场景)
如果后续需要反序列化生成的JSON,Json.NET需要无参构造函数来创建对象。可以直接加一个公开无参构造,或者用特性标记现有构造:
// 方案1:添加公开无参构造 public Room() { } // 方案2:用[JsonConstructor]标记现有带参构造(需确保反序列化时能匹配参数) [JsonConstructor] public Room(Factory factory, int id) { this.factory = factory; this.id = id; login = new Login(); }
4. 处理私有成员的序列化(可选)
Room类里的private Factory factory是私有成员,默认不会被序列化。如果需要保留这个字段的序列化信息,给它加[JsonProperty]特性:
[JsonProperty] private Factory factory { get; set; }
注意:Factory类本身也需要支持序列化,避免出现循环引用或其他序列化问题。
内容的提问来源于stack exchange,提问作者CitrusBoy
相关产品推荐
相关产品推荐

