c# - sharp - generar documentacion visual studio 2017
{"<user xmlns=''''> no se esperaba.} Deserialización de Twitter XML (10)
Aún más fácil es solo agregar las siguientes anotaciones a la parte superior de su clase:
[Serializable, XmlRoot("user")]
public partial class User
{
}
Así que estoy tirando del XML de Twitter a través de OAuth
Así que estoy haciendo una solicitud a http://twitter.com/account/verify_credentials.xml
Lo cual devuelve el siguiente 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>» @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>
Estoy usando el siguiente código para deserializar
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);
}
Y tengo lo siguiente para mi clase de usuario
[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; }
}
Pero cuando se deserializa el Xml anterior, aparece el siguiente error lanzado
$ exception {"Hay un error en el documento XML (2, 2)."} System.Exception {System.InvalidOperationException}
InnerException {"<user xmlns = ''''> no se esperaba."} System.Exception {System.InvalidOperationException}
Ahora he buscado y la mejor solución que puedo encontrar es agregar espacios de nombres en blanco al serializador, cuando serializas el contenido, PERO no estoy serializándolo así que no puedo.
También tengo un código para recibir estados, que funciona bien.
Entonces, ¿alguien me puede explicar qué y por qué está sucediendo el error? ¿Además de una posible solución?
Gracias por adelantado
Como dice John Saunders, compruebe si los nombres de clase / propiedad coinciden con la mayúscula de su XML. Si este no es el caso, el problema también ocurrirá.
El mensaje de error es tan vago, para mí tenía este código:
var streamReader = new StreamReader(response.GetResponseStream());
var xmlSerializer = new XmlSerializer(typeof(aResponse));
theResponse = (bResponse) xmlSerializer.Deserialize(streamReader);
Tenga en cuenta que xmlSerializer se crea una instancia con una Respuesta, pero al deserializar, lo lancé accidentalmente a bResonse.
La mejor y más simple solución es simplemente usar el atributo XMLRoot en su clase, en el que desea desrealizar.
Me gusta:
[XmlRoot(ElementName = "YourPreferableNameHere")]
public class MyClass{
...
}
También use la siguiente DLL :
using System.Xml.Serialization;
Lo único que funcionó en mi caso fue usar el código de David de San Valentín. Usando Root Attr. en la clase Persona no ayudó.
Tengo este simple Xml:
<?xml version="1.0"?>
<personList>
<Person>
<FirstName>AAAA</FirstName>
<LastName>BBB</LastName>
</Person>
<Person>
<FirstName>CCC</FirstName>
<LastName>DDD</LastName>
</Person>
</personList>
Clase C #:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Código de des-serialización C # de un método principal:
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;
}
Mi problema era que el elemento raíz en realidad tiene un xmlns = "abc123"
Así que tuve que hacer XmlRoot ("elementname", NameSpace = "abc123")
Mi problema era que uno de mis elementos tenía el atributo xmlns:
<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
<RETS-RESPONSE xmlns="blahblah">
...
</RETS-RESPONSE>
</RETS>
No importa lo que intenté, el atributo xmlns parecía estar rompiendo el serializador, así que eliminé cualquier rastro de xmlns = "..." del archivo xml:
<?xml version="1.0" encoding="utf-8"?>
<RETS ReplyCode="0">
<RETS-RESPONSE>
...
</RETS-RESPONSE>
</RETS>
¡y voilá! Todo funcionó.
Ahora analizo el archivo xml para eliminar este atributo antes de deserializarlo. No estoy seguro de por qué funciona esto, tal vez mi caso sea diferente ya que el elemento que contiene el atributo xmlns no es el elemento raíz.
Mi situación era que estaba trabajando en un trabajo donde el código estaba en VB.NET, y una rutina que deserializaba objetos de cadenas xml había funcionado de maravilla para docenas de usos, pero ayer no se pudo con el "usuario xmlns = '''' no se esperaba error (cuando se arrojó una cadena xml que era la serialización de un objeto que tenía una propiedad que era, en sí misma, un objeto serializado). Las respuestas anteriores me ayudaron a resolver esto tomando esta rutina que había estado funcionando ...
'' DESERIALIZE OBJECT FROM XML STRING
Public Shared Function DeserializeFromXml(Of T)(ByVal xml As String) As T
Dim response As T = Nothing
Try
Using reader As TextReader = New StringReader(xml)
response = DirectCast(New XmlSerializer(GetType(T)).Deserialize(reader), T)
End Using
Catch ex As Exception
End Try
Return response
End Function
... copie ese código y cree una nueva rutina que le permita a la persona que llama proporcionar una cadena de "Nombre de atributo raíz". La nueva rutina deserializó el objeto ''problema'' de su cadena xml serializada sin errores:
'' DESERIALIZE OBJECT FROM XML STRING, SUPPLYING A ROOT ATTRIBUTE ELEMENT NAME
Public Shared Function DeserializeFromXmlWithRootAttribute(Of T)(ByVal xml As String, ByVal rootAttributeName As String) As T
Dim response As T = Nothing
Try
Using reader As TextReader = New StringReader(xml)
Dim xra As New XmlRootAttribute()
xra.ElementName = rootAttributeName
xra.IsNullable = True
response = DirectCast(New XmlSerializer(GetType(T), xra).Deserialize(reader), T)
End Using
Catch ex As Exception
End Try
Return response
End Function
Ya sea decorar su entidad raíz con el atributo XmlRoot que se utilizará en tiempo de compilación.
[XmlRoot(Namespace = "www.contoso.com", ElementName = "MyGroupName", DataType = "string", IsNullable=true)]
O especifique el atributo raíz al de serializar en tiempo de ejecución.
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "user";
// xRoot.Namespace = "http://www.cpandl.com";
xRoot.IsNullable = true;
XmlSerializer xs = new XmlSerializer(typeof(User),xRoot);
XmlSerializer xs = new XmlSerializer(typeof(User), new XmlRootAttribute("yourRootName"));