【问题标题】:Serialize interface as JsonResult将接口序列化为 JsonResult
【发布时间】:2020-08-19 00:08:45
【问题描述】:

我正在尝试编写一个返回对象列表的 .NET Core API。以下类用于发送响应:

class AnimalResponse {
    public IAnimal Animal { get; set; }
}

有一个空接口:

interface IAnimal {

}

还有2个类实现了这个接口:

class Cat : IAnimal {
    public string CatProperty { get; set; }
}

class Dog : IAnimal { 
    public string DogProperty { get; set; }
}

如您所见,AnimalResponse 类的Animal 属性可以包含CatDog 类对象。这就是我发送响应的方式:

var response = new AnimalResponse() {
    Animal = new Cat() { 
         CatProperty = "Cat Property Value"
    }
};
return JsonResult(response);

由于某种原因,CatProperty 在序列化后从 API 响应中丢失。 API 返回以下 json:{Animal:{}}

那么,如何让它包含所有特定于类的属性?

注意:我使用的是Microsoft.AspNetCore.Mvc.JsonResult不是 Newtonsoft.Json

【问题讨论】:

  • 你解决过这个问题吗?
  • 不,看起来不可能实现这种行为。

标签: c# json asp.net-mvc .net-core


【解决方案1】:

仅当变量类型为object 时,派生类型的序列化才有效。

换句话说,如果你重新定义你的AnimalResponse,一切都会正常工作:

class AnimalResponse {
    public object Animal { get; set; }
}

你失去了一点类型安全,但你可以像这样绕过它:

class AnimalResponse {
    public AnimalResponse(IAnimal animal) { Animal = animal; }
    public object Animal { get; }
}

这是因为System.Text.Json 有一个object 的特殊情况。

(那里有几篇文章解释了为什么以及如何使用它,但不幸的是,不久前我找到了一篇真正让我明白的文章。)

【讨论】:

    【解决方案2】:

    1 安装 NewtonsoftJson

    安装包 Microsoft.AspNetCore.Mvc.NewtonsoftJson

    2 配置服务

    services.AddControllersWithViews().AddNewtonsoftJson();

    【讨论】:

      【解决方案3】:

      如果您还在这里阅读Why are interfaces not [Serializable]? 接口不是可序列化的,因为它们定义的是合同而不是数据。

      它们是为类定义行为的一种方式。

      顺便说一句,您应该能够通过实现 ISerializable 接口使其可序列化。

      编辑:如果您只需要序列化数据,请考虑使用基类而不是接口。如果您需要同时拥有这两者,或许更好的解决方案是拥有一个基类和一个接口并同时实现两者。

      更新:基类必须实现 ISerializable 接口。

      【讨论】:

      • 将接口更改为类后问题仍然存在。
      • 让类也实现ISerializable接口。很抱歉造成误解,应该序列化的对象必须实现 ISerializable,那么在我看来,最好是实现它的类而不是接口,它也可以工作,但恕我直言,这违背了接口的目标。跨度>
      猜你喜欢
      • 1970-01-01
      • 2014-10-08
      • 2011-05-02
      • 1970-01-01
      • 2019-08-20
      • 2022-07-19
      • 1970-01-01
      • 2019-06-11
      • 2013-02-09
      相关资源
      最近更新 更多