“类型不是预期的”,使用 DataContractSerializer - 但这只是一个简单的类,没有有趣的东西?

问题描述 投票:0回答:7

我正在重构我的 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;
        }
    }

}
}

它给了我这个:

不需要输入数据合约名称为“Konstant:http://schemas.datacontract.org/2004/07/VDB_Sync.Model”的“VDB_Sync.Model.Konstant”。考虑使用 DataContractResolver 或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。

*到目前为止我找到的帮助指向集合和类型。我的类中确实有一个枚举(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();
    }
c# .net serialization xml-serialization datacontractserializer
7个回答
74
投票

报告的异常是 VDB_Sync.Model.Konstant。这意味着在链的更上游的某个位置,这个类被拉入另一个类,而该类就是被序列化的类。

问题是,根据 Konstant 在此类中的嵌入方式(例如,如果它位于集合或通用列表中),DataContractSerializer 可能无法在反序列化期间准备好其出现。

要解决此问题,您需要将known-type属性应用到包含Konstant的类。根据您的序列化代码,我怀疑这是

VDB_SessionController

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

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

18
投票

将其添加到 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-序列化内容和论坛的响应正文=wcf


15
投票

您还可以将

[KnownType]
和反射结合起来,使您的代码更能抵抗未来的变化。

[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
/
XmlSerializer
/
Person
,也可以与从 Person 派生的
any
类型一起使用(只要它是在同一程序集中声明的)。


4
投票

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


4
投票

我的问题是我从 WebAPI 控制器返回接口 (IIndividual)。当我将该返回类型更改为类(个人)类型时,此错误消失了。

不工作:

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

4
投票

就像@Leon建议的那样,但是通过@Bryan的修复,“KnownTypeAttribute”应该位于基类上,所以它应该是这样的:

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

在子类中:

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

0
投票

更改此:

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

对此:

[DataContract(Name="Konstant")]
[KnownTypes(typeof(somenamespace.DataFelt))]
public class Konstant : DataFelt
© www.soinside.com 2019 - 2024. All rights reserved.