{"nie oczekiwano. Deserializacja Twitter XML

Ściągam XML z Twittera przez OAuth.

Składam prośbę do http://twitter.com/account/verify_credentials.xml , który zwraca następujący XML:

<?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>

Używam poniższego kodu do deserializacji:

    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);
    }

I mam następujące dla mojej klasy User:

 [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; }

}

Ale kiedy deserializuje powyższy XML, aplikacja rzuca następujące:

$ exception {"wystąpił błąd w dokumencie XML (2, 2)."} System.Exception {System.InvalidOperationException}

InnerException {"

Teraz szukałem i najlepszym rozwiązaniem, jakie mogę znaleźć, jest dodanie pustych przestrzeni nazw do serializera podczas serializacji treści, ale nie jestem serializacją, więc nie mogę.

Mam też kod do odbierania statusów, który działa dobrze.

Więc może mi ktoś wyjaśnić dlaczego błąd się dzieje? Jak również możliwe rozwiązanie?

Author: Jan Schultke, 2009-10-12

12 answers

Albo Udekoruj swój element root atrybutem xmlroot, który będzie używany podczas kompilacji.

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

Lub określić atrybut root podczas de serializacji w czasie wykonywania.

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

XmlSerializer xs = new XmlSerializer(typeof(User),xRoot);
 285
Author: david valentine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-12 15:53:13

Jeszcze łatwiej jest dodać następujące adnotacje na górze swojej klasy:

[Serializable, XmlRoot("user")]
public partial class User
{
}
 140
Author: Rebecca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 17:41:33
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName")); 
 27
Author: Ranadheer Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-11 06:12:43

Komunikat o błędzie jest tak niejasny, dla mnie miałem ten kod:

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

Zauważ, że XmlSerializer jest uruchamiany z aResponse, ale po deserializacji przypadkowo wrzuciłem go do bResonse.

 12
Author: Jeremy Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-11 06:22:05

Najprostszym i najlepszym rozwiązaniem jest użycie atrybutu XMLRoot w klasie, w której chcesz deserializować.

Jak:

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

Użyj również następującego zestawu :

using System.Xml.Serialization;
 6
Author: Khawaja Asim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 19:46:41

Jak mówi John Saunders, sprawdź, czy nazwy klas / właściwości pasują do Wielkiej obudowy Twojego XML. Jeśli tak nie jest, problem również wystąpi.

 5
Author: Luuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-16 13:39:18

Jedyną rzeczą, która zadziałała w moim przypadku było użycie kodu Davida valentine ' a. Używanie Root Attr. w klasie osoby nie pomogłem.

Mam taki prosty Xml:

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

Klasa C#:

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

De-serializacja kodu C# z głównej metody:

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;
}  
 3
Author: user2596085,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 23:03:11

W moim przypadku, mój xml miał wiele przestrzeni nazw i atrybutów. Więc użyłem tej strony do generowania obiektów - https://xmltocsharp.azurewebsites.net/

I użyłem poniższego kodu do deserializacji

 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);
            }
        }
 3
Author: JoR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-20 17:39:26

Mój problem polegał na tym, że jeden z moich elementów miał atrybut xmlns:

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

Bez względu na to, co próbowałem, atrybut xmlns wydawał się łamać serializer, więc usunąłem wszelkie ślady xmlns="..."z pliku xml:

<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
    <RETS-RESPONSE>
        ...
    </RETS-RESPONSE>
</RETS>
I voila! Wszystko działało.

Analizuję teraz plik xml, aby usunąć ten atrybut przed deserializacją. Nie wiem, dlaczego to działa, może mój przypadek jest inny, ponieważ element zawierający atrybut xmlns nie jest elementem głównym.

 2
Author: Patrick Borkowicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-09 17:05:10

Nic nie działało dla mnie za te błędy z wyjątkiem

... was not expected, 
... there is an error in XML document (1,2)
... System.FormatException Input String was not in correct format ...

Z wyjątkiem tej drogi

1-musisz sprawdzić odpowiedź xml jako łańcuch znaków (odpowiedź, którą próbujesz usunąć serializując do obiektu)

2-Użyj narzędzi online dla string unescape i XML prettify / formatter

3- upewnij się, że Klasa C # (main class), którą próbujesz odwzorować / deserializować łańcuch xml na ma XmlRootAttribute , który pasuje do główny element odpowiedzi.

Exmaple:

Moja odpowiedź XML wyglądała tak:

<ShipmentCreationResponse xmlns="http://ws.aramex.net/ShippingAPI/v1/">
       <Transaction i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
           ....

A C# class definition + attributes było takie :

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="ShipmentCreationResponse", WrapperNamespace="http://ws.aramex.net/ShippingAPI/v1/", IsWrapped=true)]
public partial class ShipmentCreationResponse {
  .........
}

Zauważ, że definicja klasy nie ma " XmlRootAttribute "

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.aramex.net/ShippingAPI/v1/", IsNullable = false)]

I kiedy próbuję de serializować przy użyciu metody generycznej:

public static T Deserialize<T>(string input) where T : class
{
    System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));

    using (System.IO.StringReader sr = new System.IO.StringReader(input))
    {
        return (T)ser.Deserialize(sr);
    }
}





var _Response = GeneralHelper.XMLSerializer.Deserialize<ASRv2.ShipmentCreationResponse>(xml);

Dostawałem błędy powyżej

... was not expected, ... there is an error in XML document (1,2) ...

Teraz po prostu dodając "XmlRootAttribute", który naprawił problem na zawsze i dla każdego inne prośby/odpowiedzi, z którymi miałem podobny problem:

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.aramex.net/ShippingAPI/v1/", IsNullable = false)]

..

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.aramex.net/ShippingAPI/v1/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.aramex.net/ShippingAPI/v1/", IsNullable = false)]
public partial class ShipmentCreationResponse
{
    ........
}
 2
Author: Adel Mourad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-01 10:11:29

Mój problem polegał na tym, że element root faktycznie ma xmlns= "abc123"

Więc musiałem zrobić XmlRoot ("elementname", NameSpace="abc123")

 1
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 19:44:56

Wszystko powyżej nie działało dla mnie, ale to było: Sprawdź, czy nazwa głównego elementu klasy to dokładnie Jak ta z XML rozróżniająca wielkość liter .

 1
Author: shdr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-28 06:41:49