web-dev-qa-db-fra.com

XmlSerializer: la chaîne '' n'est pas une valeur AllXsd valide

Je reçois ce message, "La chaîne '22/07/2006 12:00:00 AM' n'est pas une valeur AllXsd valide.", Lors de la désérialisation d'un XML, l'élément contient une date, c'est la propriété qui est supposée à mapper à l'élément:

[XmlElement("FEC_INICIO_REL",typeof(DateTime))]
public DateTime? FechaInicioRelacion { get; set; }

Est-ce que je fais quelque chose de mal?

MISE À JOUR: Voici le XML:

<Detalle>
  <NOM_ASOC>Financiera Panameña</NOM_ASOC>
  <DESCR_CORTA_RELA>PREST. PERSONAL</DESCR_CORTA_RELA>
  <FEC_INICIO_REL>7/22/2006 12:00:00 AM</FEC_INICIO_REL>
  <FEC_FIN_REL>9/22/2008 12:00:00 AM</FEC_FIN_REL>
  <MONTO_ORIGINAL>1160.0000</MONTO_ORIGINAL>
  <NUM_PAGOS>2</NUM_PAGOS>
  <DESCR_FORMA_PAGO>PAGOS VOLUNTARIOS</DESCR_FORMA_PAGO>
  <IMPORTE_PAGO>59.9400</IMPORTE_PAGO>
  <FEC_ULTIMO_PAGO>11/15/2006 12:00:00 AM</FEC_ULTIMO_PAGO>
  <MONTO_ULTIMO_PAGO>0.0000</MONTO_ULTIMO_PAGO>
  <DESCR_OBS_CORTA />
  <SALDO_ACTUAL>1078.3900</SALDO_ACTUAL>
  <NUM_DIAS_ATRASO>0</NUM_DIAS_ATRASO>
  <HISTORIA>1</HISTORIA>
  <MONTO_CODIFICADO />
  <FEC_ACTUALIZACION>10/17/2008 12:00:00 AM</FEC_ACTUALIZACION>
  <COD_GRUPO_ECON>  </COD_GRUPO_ECON>
  <TIPO_ASOC>  </TIPO_ASOC>
  <NUM_REFER>2008628116</NUM_REFER>
</Detalle>
22
ryudice

J'ai résolu le problème en stockant la date dans une chaîne, puis en créant un getter qui analyse la date et la renvoie en tant que DateTime.

Exemple de code:

    [XmlElement("Valid")]
    public string _Valid
    {
        get;
        set;
    }

    [XmlIgnore]
    public bool? Valid
    {
        get
        {
            if (!string.IsNullOrWhiteSpace(_Valid))
            {
                return bool.Parse(_Valid);
            }

            return null;
        }
    }
20
ryudice

AllocationDate est un champ obligatoire mais peut être fourni en blanc qui est géré en le représentant par AllocationDateString:

    private DateTime? _allocationDate;

    [XmlIgnore]
    public DateTime? AllocationDate
    {
        get { return _allocationDate; }
        set { _allocationDate = value; }
    }

    [XmlAttribute("AllocationDateTime")]
    public string AllocationDateTimeString
    {
        get
        {
            return _allocationDate.HasValue ? XmlConvert.ToString(_allocationDate.Value, XmlDateTimeSerializationMode.Unspecified)
            : string.Empty;
        }
        set
        {
            _allocationDate = !string.IsNullOrEmpty(value) ? XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.Unspecified) : (DateTime?)null;
        }
    }
12
Shay

Je me rends compte que c'est une vieille question, mais j'ai eu ce problème aujourd'hui et j'ai trouvé une solution de contournement en utilisant les propriétés et le casting.

private string _date; // Private variable to store XML string

// Property that exposes date. Specifying the type forces
// the serializer to return the value as a string.
[XmlElement("date", Type = typeof(string))]
public object Date {
    // Return a DateTime object
    get
    {
        return
            !string.IsNullOrEmpty(_date) ? 
            (DateTime?) Convert.ToDateTime(_date) : 
            null;
    }
    set { _date = (string)value; } 
}

Maintenant, chaque fois que vous devez vous référer à la date, vous appelez simplement:

var foo = (DateTime?)Bar.Date

Cela fonctionne bien pour moi depuis. Si cela ne vous dérange pas d'ajouter la distribution supplémentaire dans votre code, vous pouvez également le faire de cette façon!

Edit: En raison du commentaire de Dirk, j'ai décidé de revoir mon implémentation dans une branche séparée. Plutôt que d'utiliser une classe object, qui est sujette aux erreurs du compilateur d'exécution, je renvoie la valeur sous forme de chaîne.

[XmlElement("date")] 
public string Date;

Ce qui rend la déclaration beaucoup plus simple. Mais lorsque vous essayez de lire à partir de la variable, vous devez maintenant fournir des vérifications nulles.

var foo = string.IsNullOrEmpty(Date) ? Convert.ToDateTime(Date) : (DateTime?) null

Il fonctionne exactement de la même manière que l'implémentation précédente, sauf que le casting et les vérifications nulles se produisent à un emplacement différent. Je veux pouvoir écrire mon modèle puis l'oublier, donc je préfère toujours mon implémentation à la place.

Sur une autre note, j'ai ajouté une correction à la distribution avant la modification: DateTime devrait être DateTime?.

4
dimiguel

Pour ceux qui rencontrent ceci, voici la réponse la plus simple, j'ai rencontré le même problème, mais je n'ai pas eu besoin de DateTime nullable. Le XMLElement n'a besoin que d'un get et non d'un ensemble lors du rendu XML.

private DateTime _fechaInicioRelacion;

[XmlElement("FEC_INICIO_REL")]
public string FechaInicioRelacionString
{
    get
        {
            return _fechaInicioRelacion.ToString("yyyy-MM-ddTHH:mm:ss");
        }
    set { }
}

[XmlIgnore]
public DateTime FechaInicioRelacion
{
    get { return _fechaInicioRelacion; }
    set { _fechaInicioRelacion = value; }
}
2
kpasgma

Essayez d'ajouter l'attribut "IsNullable = true".

1
m0s