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>» @alexmuller your kidding? it should all be "black tie" dress code</text>
<source><a href="http://code.google.com/p/wittytwitter/" rel="nofollow">Witty</a></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
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);
Il est encore plus simple d'ajouter les annotations suivantes au sommet de votre classe:
[Serializable, XmlRoot("user")]
public partial class User
{
}
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName"));
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.
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;
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.
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;
}
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.
Mon problème était que l'élément racine a réellement un xmlns = "abc123"
Donc dû faire XmlRoot ("elementname", NameSpace = "abc123")
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);
}
}
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.