«Тип не ожидается», используя DataContractSerializer – но это просто class, не смешные вещи?
Я рефакторинг моей XML-сериализации, и решил, что я попробую DataContractSerializer. Все работает плавно, пока не потребуется сериализовать этот 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; } } } }
Это дает мне следующее:
Введите «VDB_Sync.Model.Konstant» с именем контракта с данными «Konstant: http: //schemas.datacontract.org/2004/07/VDB_Sync.Model» не ожидается. Подумайте об использовании DataContractResolver или добавьте любые типы, не известные статически в список известных типов – например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, переданных DataContractSerializer.
* Помощь, которую я нашел до сих пор, указывает на коллекции и типы. У меня есть enum (MySqlDbType) в моем classе, но получаю следующее: я даже получаю ту же ошибку, когда у меня нет объявленных 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(); }
- ShouldSerialize * () vs * Условный шаблон условной сериализации
- Предотrotation изменения часового пояса при десериализации значения DateTime
- Как сделать тип значения nullable с помощью .NET XmlSerializer?
- JAXB: Как игнорировать пространство имен во время развязывания XML-документа?
- Преобразование набора данных в XML
- Как XML-сериализовать словарь
- Каковы различия между XmlSerializer и BinaryFormatter
- Сериализация XML XML без текстового объявления
Сообщается об исключении для VDB_Sync.Model.Konstant. Это означает, что где-то дальше по цепочке этот class втягивается в другой class, и этот class является сериализованным.
Проблема в том, что в зависимости от того, как Konstant встроен в этот class (например, если он находится в коллекции или общем списке), DataContractSerializer может быть не подготовлен к его появлению во время десериализации.
Чтобы решить эту проблему, вам необходимо применить атрибут известного типа к classу, который содержит Konstant. Основываясь на вашем коде сериализации, я подозреваю, что это VDB_SessionController
.
Итак, попробуйте украсить этот class атрибутом 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- -реакция тела в обмен на содержание и форум = ФОС
Вы также можете комбинировать [KnownType]
и reflection, чтобы сделать ваш код более устойчивым к будущим изменениям.
[DataContract] [KnownType("GetKnownPersonTypes")] internal class Person { private static IEnumerable _personTypes; private static IEnumerable GetKnownTypes() { if (_personTypes == null) _personTypes = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => typeof (Person).IsAssignableFrom(t)) .ToList(); return _personTypes; } }
Теперь DataContractSerializer
/ DataContractJsonSerializer
/ XmlSerializer
настроенный для работы с Person
, также будет работать с любым типом, производным от Person
(если он объявлен в той же сборке).
используйте KnownTypeAttribute для разрешения classа DataFelt. см .: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx
Проблема для меня заключалась в том, что я возвращал интерфейс (II индивидуал) из своего controllerа WebAPI. Когда я изменил этот тип возврата на тип classа (индивидуальный), эта ошибка исчезла.
Не работает:
[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; }
Это похоже на предложение @Leon, но с исправлением от @Bryan, «KnownTypeAttribute» должен быть в базовом classе, поэтому он должен выглядеть следующим образом:
[DataContract(Name="DataFelt")] [KnownType(typeof(somenamespace.Konstant))] public class DataFelt
и в подclassе:
[DataContract(Name="Konstant")] public class Konstant : DataFelt
Измените это:
[DataContract(Name="Konstant")] public class Konstant : DataFelt
к этому:
[DataContract(Name="Konstant")] [KnownTypes(typeof(somenamespace.DataFelt))] public class Konstant : DataFelt