C# DATACONTROJTJSONSORIALIZER序列化错误:考虑使用DATACONTractRealver或添加任何静态不知道的类型到列表中

C# DATACONTROJTJSONSORIALIZER序列化错误:考虑使用DATACONTractRealver或添加任何静态不知道的类型到列表中,c#,json,serialization,.net-4.0,datacontractserializer,C#,Json,Serialization,.net 4.0,Datacontractserializer,我正在使用继承的字符串(不是复杂类型)的两个附加属性扩展使用System.Runtime.Serialization.Json.DataContractJsonSerializer进行序列化的对象。使用的Net版本是.Net 4。 序列化机制对基本对象运行良好,但对具有两个附加属性的对象无效,这两个属性对我来说非常特殊。 我在基本对象和继承对象上都使用了[DataContract]属性,并且这两个对象上的所有属性都具有带有名称的[DataMember]属性。 这两个对象都是内部对象,但我看不出这

我正在使用继承的字符串(不是复杂类型)的两个附加属性扩展使用
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();
        }
    }
}
TheMovelLibrary.DataControls上的命名空间 { [数据合同] OnTheMoveBusinessComponentJavaScriptInitObject的内部类:OnTheMoveValidable { 公共OnTheMoveBusinessComponentJavaScriptInitObject() { this.SqlStatementObject=新的OnTheMoveSelectStatement(); this.PreDefaults=新的PreDefaultsObject(); this.ParentAssociations=新列表(); this.CalculatedFields=新列表(); this.BusinessComponentEvents=新列表(); } [DataMember(Name=“sqlStatementObject”)] public-ionMoveSelectStatementSqlStatementObject{get;set;} [DataMember(Name=“calculatedFields”)] 公共列表计算字段{get;set;} [DataMember(Name=“knockoutContextName”)] 公共字符串KnockoutContextName{get;set;} [数据成员(Name=“可观察”)] 公共布尔可观测{get;set;} [DataMember(Name=“integrationObjectNameForNewRecords”)] 公共字符串IntegrationObjectNameForNewRecords{get;set;} [DataMember(Name=“singleRecordNewFlag”)] public bool SingleRecordNewFlag{get;set;} [DataMember(Name=“recordIndex”)] 公共int?记录索引{get;set;} [DataMember(Name=“primaryTableName”)] 公共字符串PrimaryTableName{get;set;} /// ///“RecordId”参数的查询字符串中的索引,用作插入新记录的父项,默认为0 ///例如,如果查询字符串中的recordid为“A123,B123”,并将ParentQSRecordIdIndex设置为1,则保存时将B123用作父对象 /// [DataMember(Name=“parentRecordIdQueryStringIndex”)] public int?ParentRecordIdQueryStringIndex{get;set;} [DataMember(Name=“parentAssociations”)] 公共列表父关联{get;set;} [DataMember(Name=“applyBindings”)] 公共bool ApplyBindings{get;set;} [DataMember(Name=“PreDefaults”)] 公共预默认对象预默认{get;set;} /// ///获取或设置BusinessComponentEvents的列表。 /// [DataMember(Name=“businessComponentEvents”)] 公共列表BusinessComponentEvents{get;set;} [DataMember(Name=“automaticLeadingWildcards”)] public bool?自动加密通配符{get;set;} [DataMember(Name=“AutomaticRailing通配符”)] public bool?自动跟踪通配符{get;set;} [DataMember(Name=“enableggregatefields”)] 公共布尔?EnableAggregateFields{get;set;} 公共重写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;
    }
公共静态字符串ObjectToJson(TValue sourceObject)
{
字符串结果=null;
类型=类型(TValue);
if(type==typeof(object))
{
返回CallObjectToJsonWithSpecificType(sourceObject);
}
Type[]knownTypes=new[]{typeof(OnTheMoveSelectStatement),typeof(OnTheMoveCustomSelectStatement)};
var serializer=newdatacontractjsonserializer(类型,knownTypes);
var ms=新内存流();
尝试
{
serializer.WriteObject(ms,sourceObject);
结果=Encoding.UTF8.GetString(ms.ToArray());
}
最后
{
Close女士();
}
返回结果;
}
我自己解决了

而不是将基类type in属性添加到继承的类

[DataContract]
[KnownType(typeof(OnTheMoveBusinessComponentJavaScriptInitObject))]
internal class OnTheMoveTreeBusinessComponentJavaScriptInitObject : OnTheMoveBusinessComponentJavaScriptInitObject
我们必须做相反的事情——用子类类型添加到基类属性(这打破了所有面向对象的设计,因为基类永远不应该知道谁从中继承)

[DataContract]
[KnownType(typeof(OnTheMoveTreeBusinessComponentJavaScriptInitObject))]
internal class OnTheMoveBusinessComponentJavaScriptInitObject : OnTheMoveValidatable