Posso não desserializar com XmlSerializer em C # se um elemento não é encontrado?
-
06-07-2019 - |
Pergunta
Eu estou usando XmlSerializer para escrever e ler um objeto para XML em C #. Eu uso atualmente o XmlElement
e XmlIgnore
atributos para manipular a serialização do objeto.
Se meu arquivo xml está faltando um elemento XML que eu preciso, meu objeto ainda desserializa (xml -> objeto) muito bem. Como faço para indicar (de preferência através de Atributos) que um determinado campo é "necessária"?
Aqui é um método de amostra do que eu estou usando atualmente:
[XmlElement(ElementName="numberOfWidgets")]
public int NumberThatIsRequired {
set ...;
get ...;
}
Minha solução ideal seria adicionar algo como um atributo XmlRequired
.
Além disso, existe uma referência boa para o que atributos estão disponíveis para manipular o comportamento de XmlSerializer?
Solução
Eu tenho uma resposta para a segunda parte: "Atributos que a serialização XML controle" .
Ainda investigando a primeira parte ...
EDIT: Eu suspeito fortemente que você não pode fazer isso através do próprio desserialização XML. Acabei de correr xsd.exe em um esquema de exemplo que inclui um atributo obrigatório - e é exatamente o mesmo se o atributo é marcado como sendo opcional. Se houvesse uma maneira de exigir propriedades para ser definido, eu esperaria que é aplicado nesse caso.
Eu suspeito que você basicamente tem que apenas validar a sua árvore de objetos após deserializing-lo. Desculpe por isso ...
Outras dicas
A única maneira que eu encontrei de fazer isso é através de XSD. O que você pode fazer é validar enquanto você desserializar:
static T Deserialize<T>(string xml, XmlSchemaSet schemas)
{
//List<XmlSchemaException> exceptions = new List<XmlSchemaException>();
ValidationEventHandler validationHandler = (s, e) =>
{
//you could alternatively catch all the exceptions
//exceptions.Add(e.Exception);
throw e.Exception;
};
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(schemas);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += validationHandler;
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xml))
using (XmlReader books = XmlReader.Create(sr, settings))
return (T)serializer.Deserialize(books);
}
Por razões de extensibilidade, XmlSerializer
é muito indulgente quando se trata de desserialização; coisas como [DefaultValue]
, ShouldSerialize{Foo}
e {Foo}Specified
são principalmente usado durante serialização (o {Foo}Specified
exceção sendo, que é definido durante a desserialização, bem como consultados durante a serialização).
Como tal; não há uma maneira fácil de fazer isso, a menos que você implementar IXmlSerializable
e fazê-lo sozinho. damagednoob mostra uma opção XSD, que também é uma opção.