“Type not expected”, using DataContractSerializer - but it's just a simple class, no funny stuff?

北战南征 提交于 2019-11-27 05:23:30

The exception that is being reported is for VDB_Sync.Model.Konstant. This means that somewhere further up the chain, this class is being pulled into another class and that class is the one being serialized.

The issue is that depending on how Konstant is embedded in this class (for example, if it is in a collection or a generic list), the DataContractSerializer may not be prepared for its appearance during deserialization.

To resolve this, you need to apply the known-type attribute to the class that contains Konstant. Based on your serialization code, I suspect that this is VDB_SessionController.

So, try decorating this class with the KnownType attribute:

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

Add this to 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);

Reference: http://www.datazx.cn/Forums/en-US/a5adf07b-e622-4a12-872d-40c753417645/action?threadDisplayName=web-api-error-the-objectcontent1-type-failed-to-serialize-the-response-body-for-content&forum=wcf

dcastro

You can also combine [KnownType] and reflection to make your code more resistant to future changes.

[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;
    }
}

Now a DataContractSerializer / DataContractJsonSerializer / XmlSerializer configured to work with Person, will also work with any type derived from Person (as long as it's declared within the same assembly).

The problem for me was that I was returning the Interface (IIndividual) from my WebAPI controller. When I changed that return type to the Class (Individual) type, this error went away.

Not working:

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

Working:

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

It is like as @Leon suggested but with the fix from @Bryan, the 'KnownTypeAttribute' should be on the base class, so it should be like this:

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

and in the Subclass:

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

Change this:

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

to this:

[DataContract(Name="Konstant")]
[KnownTypes(typeof(somenamespace.DataFelt))]
public class Konstant : DataFelt
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!