programing tip

DataContractSerializer를 사용하여 "예상되지 않은 유형"-하지만 단순한 클래스 일뿐 재미있는 것은 없습니까?

itbloger 2020. 12. 30. 07:42
반응형

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

}
}

그것은 나에게 이것을 준다 :

데이터 계약 이름이 'Konstant : http : //schemas.datacontract.org/2004/07/VDB_Sync.Model'인 'VDB_Sync.Model.Konstant'를 입력해야합니다. DataContractResolver 사용을 고려하거나 정적으로 알려지지 않은 모든 유형을 알려진 유형 목록에 추가하십시오 (예 : KnownTypeAttribute 특성을 사용하거나이를 DataContractSerializer에 전달 된 알려진 유형 목록에 추가).

* 지금까지 찾은 도움말은 컬렉션과 유형을 가리 킵니다. 클래스에 열거 형 (MySqlDbType)이 있습니다.하지만이 문제가 발생합니다. DataMember가 전혀 선언되지 않은 경우에도 동일한 오류가 발생합니다. -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();
    }

보고되는 예외는 VDB_Sync.Model.Konstant에 대한 것입니다. 이것은 체인의 어딘가에서이 클래스가 다른 클래스로 당겨지고 해당 클래스가 직렬화되고 있음을 의미합니다.

문제는 Konstant가이 클래스에 포함 된 방식에 따라 (예 : 컬렉션 또는 일반 목록에있는 경우) DataContractSerializer가 deserialization 중에 모양을 준비하지 못할 수 있다는 것입니다.

이를 해결하려면 Konstant를 포함하는 클래스에 known-type 속성을 적용해야합니다. 직렬화 코드에 따르면 이것이 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- the-response-body-for-content & forum = wcf


또한 결합 [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/ (동일한 어셈블리 내에서 선언 된 한) 파생 된 모든 유형 에서도 작동 합니다.XmlSerializerPersonPerson


use KnownTypeAttribute for resolving DataFelt class. see: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx


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

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

Change this:

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

to this:

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

ReferenceURL : https://stackoverflow.com/questions/8794594/type-not-expected-using-datacontractserializer-but-its-just-a-simple-class

반응형