"Type pas prévu", en utilisant DataContractSerializer - mais c'est juste une classe simple, pas de trucs drôles?
Je refactionne ma sérialisation XML, et j'ai pensé essayer le DataContractSerializer. Tout se déroule en douceur, jusqu'à ce qu'il ait besoin de sérialiser cette classe:
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;
}
}
}
}
Il donne de moi:
Type 'VDB_Sync.Modèle.Konstant "with data contract name" Konstant: http: / / schemas.datacontract.org/2004/07/VDB_Sync.Modèle " n'est pas prévu. Envisagez d'utiliser un DataContractResolver ou ajouter des types non connus statiquement à la liste des types connus - par exemple, en utilisant l'attribut KnownTypeAttribute ou en les ajoutant à la liste des types connus passés à DataContractSerializer.
*L'aide que j'ai trouvé jusqu'à présent des points pour les collections et les Types. J'ai un enum (MySqlDbType) dans ma classe - mais j'obtiens ceci: j'obtiens même la même erreur quand je n'ai pas de DataMembers déclaré du tout: - x Ce qui se passe ici? Ce qui me manque?
pour la référence, c'est la façon dont je sérialisé, VDB_SessionController étant la racine:*
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();
}
7 réponses
l'exception qui est déclarée est pour VDB_Sync.Modèle.Konstant. Cela signifie que quelque part en haut de la chaîne, cette classe est tiré dans une autre classe et cette classe est celle qui est sérialisé.
le problème est que selon la façon dont Konstant est incorporé dans cette classe (par exemple, si elle est dans une collection ou une liste générique), le DataContractSerializer peut ne pas être préparé pour son apparition lors de la désérialisation.
à résolvez cela, vous devez appliquer l'attribut known-type à la classe qui contient Konstant. D'après votre code de sérialisation, je soupçonne que c'est VDB_SessionController
.
alors, essayez de décorer cette classe avec l'attribut type connu:
[KnownType(typeof(VDB_Sync.Model.Konstant)]
public class VDB_SessionController
ajoutez ceci à 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);
vous pouvez également combiner [KnownType]
et la réflexion pour rendre votre code plus résistant aux changements futurs.
[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
configuré pour fonctionner avec Person
, fonctionnera également avec tout type dérivé de Person
(tant qu'il est déclaré dans le même ensemble).
utiliser KnownTypeAttribute pour résoudre la classe DataFelt. voir: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx
le problème pour moi était que je retournais L'Interface (Iindividu) de mon contrôleur WebAPI. Lorsque j'ai changé ce type de retour au type de classe (particulier), cette erreur a disparu.
ne travaillant pas:
[HttpGet]
[Route("api/v1/Individual/Get/{id}")]
public IIndividual Get([FromUri]int id)
{
return _individualService.Get(id);
}
"151920920 de Travail":
[HttpGet]
[Route("api/v1/Individual/Get/{id}")]
public Individual Get([FromUri]int id)
{
IIndividual individual = _individualService.Get(id);
return individual as Individual;
}
c'est comme @Leon l'a suggéré, mais avec la correction de @Bryan, le 'KnownTypeAttribute' devrait être sur la classe de base, donc il devrait être comme ceci:
[DataContract(Name="DataFelt")]
[KnownType(typeof(somenamespace.Konstant))]
public class DataFelt
et dans la sous-classe:
[DataContract(Name="Konstant")]
public class Konstant : DataFelt
Modifiez ce qui suit:
[DataContract(Name="Konstant")]
public class Konstant : DataFelt
à ceci:
[DataContract(Name="Konstant")]
[KnownTypes(typeof(somenamespace.DataFelt))]
public class Konstant : DataFelt