Я расширяю объект, который сериализуется с помощью System.Runtime.Serialization.Json.DataContractJsonSerializer
, двумя дополнительными свойствами, которые являются строками (а не сложными типами) по наследству. Используемая версия .NET — .NET 4.
Механизм сериализации отлично работает для базового объекта, но не работает для объекта с двумя дополнительными свойствами, что кажется мне очень странным.
Я использую атрибуты [DataContract]
как для базового, так и для унаследованного объекта и все свойства в обоих из них имеют атрибуты [DataMember]
с именами.
Оба объекта являются внутренними, но я не понимаю, как это может повлиять на сериализацию дочернего объекта.
Во время отладки я наблюдал, как базовый объект переходит к try
заблокировать и сериализовать, а потомок разорвется на строке serializer.WriteObject(ms, sourceObject);
Добавление атрибута известного типа [KnownType(typeof(OnTheMoveBusinessComponentJavaScriptInitObject))]
к унаследованному объекту приводит к той же ошибке в том же месте.
Почему я не могу заменить базовый объект унаследованным?
Дочерний объект:
namespace OnTheMoveLibrary.DataControls
{
[DataContract]
[KnownType(typeof(OnTheMoveBusinessComponentJavaScriptInitObject))]
internal class OnTheMoveTreeBusinessComponentJavaScriptInitObject : OnTheMoveBusinessComponentJavaScriptInitObject
{
[DataMember(Name = "MasterRecordId")]
public string MasterRecordId { get; set; }
[DataMember(Name = "ParentRecordId")]
public string ParentRecordId { get; set; }
}
}
Базовый объект:
namespace OnTheMoveLibrary.DataControls
{
[DataContract]
internal class OnTheMoveBusinessComponentJavaScriptInitObject : OnTheMoveValidatable
{
public OnTheMoveBusinessComponentJavaScriptInitObject()
{
this.SqlStatementObject = new OnTheMoveSelectStatement();
this.PreDefaults = new PreDefaultsObject();
this.ParentAssociations = new List<ParentAssociation>();
this.CalculatedFields = new List<OnTheMoveCalculatedField>();
this.BusinessComponentEvents = new List<BusinessComponentEvent>();
}
[DataMember(Name = "sqlStatementObject")]
public IOnTheMoveSelectStatement SqlStatementObject { get; set; }
[DataMember(Name = "calculatedFields")]
public List<OnTheMoveCalculatedField> CalculatedFields { get; set; }
[DataMember(Name = "knockoutContextName")]
public string KnockoutContextName { get; set; }
[DataMember(Name = "observable")]
public bool Observable { get; set; }
[DataMember(Name = "integrationObjectNameForNewRecords")]
public string IntegrationObjectNameForNewRecords { get; set; }
[DataMember(Name = "singleRecordNewFlag")]
public bool SingleRecordNewFlag { get; set; }
[DataMember(Name = "recordIndex")]
public int? RecordIndex { get; set; }
[DataMember(Name = "primaryTableName")]
public string PrimaryTableName { get; set; }
/// <summary>
/// The index within the query string of the "RecordId" parameter to use as a parent to insert new records, defaulting to 0
/// For example, if we have a recordid of "A123,B123" in the querystring, and set ParentQSRecordIdIndex=1, then B123 is used as the parent object when saving
/// </summary>
[DataMember(Name = "parentRecordIdQueryStringIndex")]
public int? ParentRecordIdQueryStringIndex { get; set; }
[DataMember(Name = "parentAssociations")]
public List<ParentAssociation> ParentAssociations { get; set; }
[DataMember(Name = "applyBindings")]
public bool ApplyBindings { get; set; }
[DataMember(Name = "PreDefaults")]
public PreDefaultsObject PreDefaults { get; set; }
/// <summary>
/// Gets or sets a list of <see cref="BusinessComponentEvent">BusinessComponentEvents</see>.
/// </summary>
[DataMember(Name = "businessComponentEvents")]
public List<BusinessComponentEvent> BusinessComponentEvents { get; set; }
[DataMember(Name = "automaticLeadingWildcards")]
public bool? AutomaticLeadingWildcards { get; set; }
[DataMember(Name = "automaticTrailingWildcards")]
public bool? AutomaticTrailingWildcards { get; set; }
[DataMember(Name = "enableAggregateFields")]
public bool? EnableAggregateFields { get; set; }
public override void ValidateProperties()
{
this.ValidateProperty("SqlStatementObject", this.SqlStatementObject != null ? this.SqlStatementObject.ToString() : null);
this.SqlStatementObject.ValidateProperties();
}
}
}
Механизм сериализации:
public static string ObjectToJson<TValue>(TValue sourceObject)
{
string result = null;
Type type = typeof(TValue);
if (type == typeof(object))
{
return CallObjectToJsonWithSpecificType(sourceObject);
}
Type[] knownTypes = new[] { typeof(OnTheMoveSelectStatement), typeof(OnTheMoveCustomSelectStatement) };
var serializer = new DataContractJsonSerializer(type, knownTypes);
var ms = new MemoryStream();
try
{
serializer.WriteObject(ms, sourceObject);
result = Encoding.UTF8.GetString(ms.ToArray());
}
finally
{
ms.Close();
}
return result;
}