【问题标题】:How do I get only a shadowed property, not the base property, to get JSON serialized?如何仅获取阴影属性而不是基本属性来获取 JSON 序列化?
【发布时间】:2017-05-19 08:56:24
【问题描述】:

在我的 ASP.NET MVC Web 应用程序中,我使用内置的 Controller.Json() 方法序列化对象并将其发送回客户端以响应 AJAX 调用。被序列化的对象的类继承自另一个具有一些共享属性名称的类。这是故意的,因为我需要属性名称来匹配正在发生的一些反射。我在派生类中“隐藏”这些属性,以便它们可以是与基类中的同名对应物不同的类型。这是一个简化的示例:

public class BaseModel
{
    public string Title { get; set; }
    public decimal CleanUpHours { get; set; }
    public decimal InstallHours { get; set; }
}

public class DerivedModel : BaseModel
{
    public new BucketHoursWithCalculations CleanUpHours { get; set; }
    public new BucketHoursWithCalculations InstallHours { get; set; }
}

当我序列化 DerivedModel 的实例时,我在客户端上的 JSON 对象仅包含 decimal 版本的 CleanUpHoursInstallHours,而不是我的自定义类 BucketHoursWithCalculations

在序列化之前在 Visual Studio 中检查对象会显示这些属性的基础版本和派生版本,如此处所示(请原谅所有额外的属性 - 我上面的示例类比我实际使用的更简化,但原理是一样的):

这是该对象在序列化为 JSON 后在客户端上的样子:

如您所见,派生/阴影属性未序列化,而基础属性已序列化,但仅在存在名称冲突的情况下(例如,基础模型中的 Title 属性序列化就好了)。

如何仅序列化存在名称冲突的阴影属性?我不相信在我的情况下更改基本属性上的访问修饰符(即从publicprotected 或其他东西)会起作用,因为BaseModel 由实体框架使用,并且必须具有公共属性。任何帮助将不胜感激。

【问题讨论】:

  • [NonSerialized()]属性装饰不需要的属性怎么样?
  • @uncoder 不幸的是,该属性不适用于继承的类,这是不需要的属性所在的地方
  • 您不是在隐藏属性,而是在隐藏它们。您有一个名为 CleanUpHours 和 InstallHours 的变量的两个完全独立的实例。根据纯粹基于字符串的JSON,哪一个应该在哪里序列化?你不应该有两个不同的对象类型同名。
  • 使用BaseModel<THours>作为基类,继承类可以指定是使用decimal还是BucketHoursWithCalculations作为类型呢?
  • @Dispersia 阴影和隐藏是一回事。如果我的理解有误,请将一些文档链接给我,以便我可以更改问题的标题。至于您认为我不应该有两个具有相同名称的不同对象类型的观点,我认为这没有问题。编译器允许它,它允许我使用反射动态地编组数据,而且很容易理解。在我的用例中没有明显的缺点,除了我遇到的技术问题(这是序列化程序的问题,而不是继承链的问题)

标签: c# asp.net-mvc jsonserializer


【解决方案1】:

一个想法是在用于小时属性的基本模型上定义类型参数。然后,为decimalBucketHoursWithCalculations 定义派生模型。我很想知道BucketHoursWithCalculations 如何序列化为 JSON,但无论如何CleanUpHoursInstallHours 属性都应该序列化。

// use a type parameter on the base model that must be specified
// in derived models.
public class BaseModel<THours>
{
    public string Title { get; set; }
    public THours CleanUpHours { get; set; }
    public THours InstallHours { get; set; }
}

// hours are specified as decimals
public class DecimalModel : BaseModel<decimal>
{
}

// hours are specified as BucketHoursWithCalculations    
public class BucketHoursWithCalculationsModel : BaseModel<BucketHoursWithCalculations>
{
}

// usage
DecimalModel d = new DecimalModel();
d.CleanUpHours = 1.0M; // CleanUpHours is a decimal here

BucketHoursWithCalculationsModel b = new BucketHoursWithCalculationsModel();
b.CleanUpHours = new BucketHoursWithCalculations();
b.CleanUpHours.SomeProperty = 1.0M;

【讨论】:

猜你喜欢
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 2017-04-18
相关资源
最近更新 更多