web-dev-qa-db-fra.com

{"<utilisateur xmlns = ''> n'était pas attendu.} Désérialisation du code XML Twitter

Alors im en tirant dans le XML de Twitter via OAuth

Donc, je fais une demande à http://Twitter.com/account/verify_credentials.xml

Ce qui retourne le XML suivant 

<?xml version="1.0" encoding="UTF-8"?>
<user>
  <id>16434938</id>
  <name>Lloyd Sparkes</name>
  <screen_name>lloydsparkes</screen_name>
  <location>Hockley, Essex, UK</location>
  <description>Student</description>
  <profile_image_url>http://a3.twimg.com/profile_images/351849613/twitterProfilePhoto_normal.jpg</profile_image_url>
  <url>http://www.lloydsparkes.co.uk</url>
  <protected>false</protected>
  <followers_count>115</followers_count>
  <profile_background_color>9fdaf4</profile_background_color>
  <profile_text_color>000000</profile_text_color>
  <profile_link_color>220f7b</profile_link_color>
  <profile_sidebar_fill_color>FFF7CC</profile_sidebar_fill_color>
  <profile_sidebar_border_color>F2E195</profile_sidebar_border_color>
  <friends_count>87</friends_count>
  <created_at>Wed Sep 24 14:26:09 +0000 2008</created_at>
  <favourites_count>0</favourites_count>
  <utc_offset>0</utc_offset>
  <time_zone>London</time_zone>
  <profile_background_image_url>http://s.twimg.com/a/1255366924/images/themes/theme12/bg.gif</profile_background_image_url>
  <profile_background_tile>false</profile_background_tile>
  <statuses_count>1965</statuses_count>
  <notifications>false</notifications>
  <geo_enabled>false</geo_enabled>
  <verified>false</verified>
  <following>false</following>
  <status>
    <created_at>Mon Oct 12 19:23:47 +0000 2009</created_at>
    <id>4815268670</id>
    <text>&#187; @alexmuller your kidding? it should all be &quot;black tie&quot; dress code</text>
    <source>&lt;a href=&quot;http://code.google.com/p/wittytwitter/&quot; rel=&quot;nofollow&quot;&gt;Witty&lt;/a&gt;</source>
    <truncated>false</truncated>
    <in_reply_to_status_id>4815131457</in_reply_to_status_id>
    <in_reply_to_user_id>8645442</in_reply_to_user_id>
    <favorited>false</favorited>
    <in_reply_to_screen_name>alexmuller</in_reply_to_screen_name>
    <geo/>
  </status>
</user>

J'utilise le code suivant pour désérialiser

    public User VerifyCredentials()
    {
        string url = "http://Twitter.com/account/verify_credentials.xml";
        string xml = _oauth.oAuthWebRequestAsString(oAuthTwitter.Method.GET, url, null);

        XmlSerializer xs = new XmlSerializer(typeof(User),"");

        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));

        return (User)xs.Deserialize(ms);
    }

Et j'ai les éléments suivants pour ma classe d'utilisateurs 

 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class User
{

    [XmlElement(ElementName = "id")]       
    public long Id { get; set; }

    [XmlElement(ElementName = "name")] 
    public string Name { get; set; }

    [XmlElement(ElementName = "screen_name")]       
    public string ScreenName { get; set; }

    [XmlElement(ElementName = "location")]       
    public string Location { get; set; }

    [XmlElement(ElementName = "description")]      
    public string Description { get; set; }

    [XmlElement(ElementName = "profile_image_url")]      
    public string ProfileImageUrl { get; set; }

    [XmlElement(ElementName = "url")]       
    public string Url { get; set; }

    [XmlElement(ElementName = "protected")]      
    public bool Protected { get; set; }

    [XmlElement(ElementName = "followers_count")]      
    public int FollowerCount { get; set; }

    [XmlElement(ElementName = "profile_background_color")]       
    public string ProfileBackgroundColor { get; set; }

    [XmlElement(ElementName = "profile_text_color")]       
    public string ProfileTextColor { get; set; }

    [XmlElement(ElementName = "profile_link_color")]       
    public string ProfileLinkColor { get; set; }

    [XmlElement(ElementName = "profile_sidebar_fill_color")]       
    public string ProfileSidebarFillColor { get; set; }

    [XmlElement(ElementName = "profile_sidebar_border_color")]      
    public string ProfileSidebarBorderColor { get; set; }

    [XmlElement(ElementName = "friends_count")]     
    public int FriendsCount { get; set; }

    [XmlElement(ElementName = "created_at")]     
    public string CreatedAt { get; set; }

    [XmlElement(ElementName = "favourties_count")]      
    public int FavouritesCount { get; set; }

    [XmlElement(ElementName = "utc_offset")]      
    public int UtcOffset { get; set; }

    [XmlElement(ElementName = "time_zone")]       
    public string Timezone { get; set; }

    [XmlElement(ElementName = "profile_background_image_url")]        
    public string ProfileBackgroundImageUrl { get; set; }

    [XmlElement(ElementName = "profile_background_tile")]        
    public bool ProfileBackgroundTile { get; set; }

    [XmlElement(ElementName = "statuese_count")]        
    public int StatusesCount { get; set; }

    [XmlElement(ElementName = "notifications")]       
    public string Notifications { get; set; }

    [XmlElement(ElementName = "geo_enabled")]       
    public bool GeoEnabled { get; set; }

    [XmlElement(ElementName = "Verified")]        
    public bool Verified { get; set; }

    [XmlElement(ElementName = "following")]
    public string Following { get; set; }

    [XmlElement(ElementName = "status", IsNullable=true)]
    public Status CurrentStatus { get; set; }

}

Mais quand sa désérialisation du code XML ci-dessus, je reçois l'erreur suivante

  • $ exception {"Il y a une erreur dans le document XML (2, 2)."} System.Exception {System.InvalidOperationException}

  • InnerException {"<utilisateur xmlns = ''> n'était pas attendu."} System.Exception {System.InvalidOperationException}

Maintenant, j'ai cherché et la meilleure solution que je puisse trouver est d'ajouter des espaces de noms vierges au sérialiseur, lorsque vous sérialisez le contenu, MAIS je ne le sérialise pas, donc je ne peux pas.

J'ai aussi du code pour recevoir Statuses, ce qui fonctionne bien.

Alors, quelqu'un peut-il m'expliquer quoi et pourquoi l'erreur se produit? Ainsi qu'une solution possible?

Merci d'avance

161
lloydsparkes

Décorez votre entité racine avec l'attribut XmlRoot qui sera utilisé lors de la compilation.

[XmlRoot(Namespace = "www.contoso.com", ElementName = "MyGroupName", DataType = "string", IsNullable=true)]

Ou spécifiez l'attribut racine lors de la sérialisation au moment de l'exécution.

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "user";
// xRoot.Namespace = "http://www.cpandl.com";
xRoot.IsNullable = true;

XmlSerializer xs = new XmlSerializer(typeof(User),xRoot);
207
david valentine

Il est encore plus simple d'ajouter les annotations suivantes au sommet de votre classe:

[Serializable, XmlRoot("user")]
public partial class User
{
}
120
Rebecca
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName")); 
19
Ranadheer Reddy

Le message d'erreur est tellement vague, j'avais pour moi ce code:

var streamReader = new StreamReader(response.GetResponseStream());
var xmlSerializer = new XmlSerializer(typeof(aResponse));
theResponse = (bResponse) xmlSerializer.Deserialize(streamReader);

Notez que xmlSerializer est instancié avec aResponse mais lors de la désérialisation, je l'ai jeté accidentellement sur bResonse.

9
Jeremy Thompson

La solution la plus simple et la meilleure consiste simplement à utiliser l'attribut XMLRoot de votre classe, dans lequel vous souhaitez effectuer la désérialisation. 

Comme:

[XmlRoot(ElementName = "YourPreferableNameHere")]
public class MyClass{
...
}

Utilisez également le Assembly suivant:

using System.Xml.Serialization;
4
Khawaja Asim

Comme John Saunders le dit, vérifiez si les noms de classe/propriété correspondent à la casse majuscule de votre XML. Si ce n'est pas le cas, le problème se produira également.

4
Luuk

La seule chose qui a fonctionné dans mon cas a été d’utiliser le code David Valentin. Utiliser Root Attr. dans la classe Personne n'a pas aidé.

J'ai ce simple XML:

<?xml version="1.0"?>
<personList>
 <Person>
  <FirstName>AAAA</FirstName>
  <LastName>BBB</LastName>
 </Person>
 <Person>
  <FirstName>CCC</FirstName>
  <LastName>DDD</LastName>
 </Person>
</personList>

Classe C #:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Code C # de désérialisation à partir d'une méthode Main:

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "personList";
xRoot.IsNullable = true;
using (StreamReader reader = new StreamReader(xmlFilePath))
{
List<Person> result = (List<Person>)(new XmlSerializer(typeof(List<Person>), xRoot)).Deserialize(reader);
 int numOfPersons = result.Count;
}  
2
user2596085

Mon problème était l'un de mes éléments avait l'attribut xmlns:

<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
    <RETS-RESPONSE xmlns="blahblah">
        ...
    </RETS-RESPONSE>
</RETS>

Peu importe ce que j'ai essayé, l'attribut xmlns semblait rompre le sérialiseur, j'ai donc supprimé toute trace de xmlns = "..." du fichier xml:

<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
    <RETS-RESPONSE>
        ...
    </RETS-RESPONSE>
</RETS>

et le tour est joué! Tout a fonctionné.

J'analyse maintenant le fichier xml pour supprimer cet attribut avant la désérialisation . Je ne sais pas pourquoi cela fonctionne, mon cas est peut-être différent puisque l'élément contenant l'attribut xmlns n'est pas l'élément racine.

1
Patrick

Mon problème était que l'élément racine a réellement un xmlns = "abc123"

Donc dû faire XmlRoot ("elementname", NameSpace = "abc123")

1
Nick

Dans mon cas, mon xml avait plusieurs espaces de noms et attributs. J'ai donc utilisé ce site pour générer les objets - https://xmltocsharp.azurewebsites.net/

Et utilisé le code ci-dessous pour désérialiser

 XmlDocument doc =  new XmlDocument();
        doc.Load("PathTo.xml");
        User obj;
        using (TextReader textReader = new StringReader(doc.OuterXml))
        {
            using (XmlTextReader reader = new XmlTextReader(textReader))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(User));
                obj = (User)serializer.Deserialize(reader);
            }
        }
0
JoR

Tout ce qui précède n'a pas fonctionné pour moi, mais c'était: Vérifiez que le nom de l'élément racine de la classe est exactement comme celui de XML sensible à la casse.

0
shdr