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);
또한 결합 [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
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
'programing tip' 카테고리의 다른 글
선택적 매개 변수를 사용한 라우팅 (0) | 2020.12.30 |
---|---|
싱글 톤 릴리스 방법이 경고를 생성합니까? (0) | 2020.12.30 |
Powershell 및 조건부 연산자 (0) | 2020.12.30 |
C / C ++에서 양수 모듈로를 얻는 가장 빠른 방법 (0) | 2020.12.30 |
파일을 열 때 기본값을 펼침으로 설정하는 방법은 무엇입니까? (0) | 2020.12.29 |