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

发布于 2024-12-25 19:15:31 字数 1741 浏览 5 评论 0原文

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

I'm refactoring my XML-serialization, and figured I'd try the DataContractSerializer.
Everything runs smoothly, until it needs to serialize this class:

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

}
}

It give's me this:

Type 'VDB_Sync.Model.Konstant' with data contract name 'Konstant:http://schemas.datacontract.org/2004/07/VDB_Sync.Model' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

*The help I've found so far points to collections and Types. I do have an enum (MySqlDbType) in my class - but get this: I even get the same error when i have no DataMembers declared at all :-x
So - what's going on here? What am I missing?

for reference, this is how i serialized it, VDB_SessionController being the root:*

    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();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夕色琉璃 2025-01-01 19:15:31

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

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

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

因此,尝试使用 KnownType 属性来装饰此类:

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

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
说好的呢 2025-01-01 19:15:31

将其添加到 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- the-response-body-for-content&forum=wcf

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

陌伤浅笑 2025-01-01 19:15:31

您还可以将 [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;
    }
}

现在,配置为与 Person 一起使用的 DataContractSerializer / DataContractJsonSerializer / XmlSerializer 也可以与any< /em> 派生自 Person 的类型(只要它是在同一程序集中声明的)。

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).

吃→可爱长大的 2025-01-01 19:15:31

对我来说,问题是我从 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;
    }

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;
    }
橘味果▽酱 2025-01-01 19:15:31

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

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

在子类中:

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

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
提笔落墨 2025-01-01 19:15:31

将此:更改

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

为:

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

Change this:

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

to this:

[DataContract(Name="Konstant")]
[KnownTypes(typeof(somenamespace.DataFelt))]
public class Konstant : DataFelt
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文