“Type not expected”,使用DataContractSerializer – 但它只是一个简单的类,没有有趣的东西?

我重构我的XML序列化,并认为我会尝试DataContractSerializer。 一切顺利,直到它需要序列化这个类:

using System; using System.Runtime.Serialization; namespace VDB_Sync.Model { [DataContract(Name="Konstant")] public class Konstant : DataFelt { [DataMember] private MySqlDbType mydataType; [DataMember] private object value; public Konstant(string navn, MySqlDbType dataType, object value) : base(navn, dataType, "*Konstant", false, false) { //this.navn = navn; this.mydataType = dataType; this.value = value; if (navn.Contains("*Løbenummer")) { navn = "*Konstant: " + Convert.ToString(value); } } public object Value { get { return value; } } } } 

这给了我这个:

input“VDB_Sync.Model.Konstant”与数据协定名称“Konstant:http://schemas.datacontract.org/2004/07/VDB_Sync.Model”不是预期的。 考虑使用DataContractResolver,或者将未知的静态types添加到已知types的列表中,例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知types的列表中。

*我发现的帮助到目前为止指向集合和types。 我在我的类中有一个枚举(MySqlDbType) – 但得到这个:我甚至得到同样的错误,当我没有DataMembers声明:-x所以 – 这是怎么回事? 我错过了什么?

作为参考,这是我如何序列化它,VDB_SessionController是根:*

  public void GemKonfig(VDB_SessionController session) { var settings = new XmlWriterSettings() { Indent = true, IndentChars = "\t" }; var writer = XmlWriter.Create(defaultFile, settings); DataContractSerializer ser = new DataContractSerializer(typeof(VDB_SessionController)); ser.WriteObject(writer, session); writer.Close(); } 

正在报告的exception是VDB_Sync.Model.Konstant。 这意味着,在这个链条的更上游的某个地方,这个阶级被拉到另一个阶级,那个阶级就是被序列化的阶级。

问题在于,根据Konstant如何embedded此类(例如,如果它位于集合或通用列表中),DataContractSerializer在反序列化期间可能无法准备好它的外观。

要解决此问题,您需要将已知types的属性应用于包含Konstant的类。 根据你的序列化代码,我怀疑这是VDB_SessionController

所以,试着用KnownType属性来装饰这个类:

 [KnownType(typeof(VDB_Sync.Model.Konstant)] public class VDB_SessionController 

将此添加到WebApiConfig.cs

 GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; var json = config.Formatters.JsonFormatter; json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; config.Formatters.Remove(config.Formatters.XmlFormatter); 

参考: http : //www.datazx.cn/Forums/en-US/a5adf07b-e622-4a12-872d-40c753417645/action? threadDisplayName= web-api-error-the-objectcontent1-type-failed-to-serialize-该反应体换内容&论坛= WCF

您还可以结合[KnownType]和reflection,使您的代码更能抵御未来的变化。

 [DataContract] [KnownType("GetKnownPersonTypes")] internal class Person { private static IEnumerable<Type> _personTypes; private static IEnumerable<Type> GetKnownTypes() { if (_personTypes == null) _personTypes = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => typeof (Person).IsAssignableFrom(t)) .ToList(); return _personTypes; } } 

现在, DataContractSerializer / DataContractJsonSerializer / XmlSerializerconfiguration为与Person一起工作,也可以使用从Person派生的任何types(只要它在同一个程序集中声明)。

使用KnownTypeAttribute来parsingDataFelt类。 请参阅: http : //msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx

我的问题是,我从我的WebAPI控制器返回接口(IIndividual)。 当我将返回types更改为Class(Individual)types时,此错误消失。

不工作:

  [HttpGet] [Route("api/v1/Individual/Get/{id}")] public IIndividual Get([FromUri]int id) { return _individualService.Get(id); } 

加工:

  [HttpGet] [Route("api/v1/Individual/Get/{id}")] public Individual Get([FromUri]int id) { IIndividual individual = _individualService.Get(id); return individual as Individual; } 

这就像@Leonbuild议的,但是从@Bryan的修复,“KnownTypeAttribute”应该在基类,所以它应该是这样的:

 [DataContract(Name="DataFelt")] [KnownType(typeof(somenamespace.Konstant))] public class DataFelt 

并在子类中:

 [DataContract(Name="Konstant")] public class Konstant : DataFelt 

改变这个:

 [DataContract(Name="Konstant")] public class Konstant : DataFelt 

对此:

 [DataContract(Name="Konstant")] [KnownTypes(typeof(somenamespace.DataFelt))] public class Konstant : DataFelt