3 Domanda: XmlSerializer cambia la codifica

domanda creata a Mon, Mar 17, 2014 12:00 AM

Sto usando questo codice per Serialize XML su String:

 
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings
{
    indent = true,
    Encoding = Encoding.UTF8
};

using (var sw = new StringWriter())
{
    using (XmlWriter xmlWriter = XmlWriter.Create(sw, xmlWriterSettings))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(moviesObject.GetType(), new XmlRootAttribute("category"));
        xmlSerializer.Serialize(xmlWriter, moviesObject);
    }
    return sw.ToString();
}

Il problema è che ottengo:

 
<?xml version="1.0" encoding="utf-16"?>
<category xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" havemore="no">
  <items>
    <movie>
      <videoid>videoid1</videoid>
      <title>title1</title>
    </movie>
  </items>
</category>

C'è un modo per cambiare il <?xml version="1.0" encoding="utf-16"?> a  <?xml version="1.0" encoding="utf-8"?>?

    
14
  1. prova questa sottoclasse StringWriter: stackoverflow.com/a/1564727/292411
    2014-03-17 11: 32: 54Z
  2. Sei passato attraverso il codice di esempio MS per XmlWriterSettings? L'esempio mostra come ottenere un output Unicode.
    2014-03-17 11: 37: 45Z
  3. @ C.Evenhuis Grazie, ho trovato la risposta ​​div>
    2014-03-17 12: 27: 30Z
    3 risposte                              3                         

    Ecco un codice con codifica come parametro. Si prega di leggere i commenti perché c'è un SuppressMessage per l'analisi del codice.

     
    /// <summary>
    /// Serialize an object into an XML string
    /// </summary>
    /// <typeparam name="T">Type of object to serialize.</typeparam>
    /// <param name="obj">Object to serialize.</param>
    /// <param name="enc">Encoding of the serialized output.</param>
    /// <returns>Serialized (xml) object.</returns>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
    internal static String SerializeObject<T>(T obj, Encoding enc)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings()
            {
                // If set to true XmlWriter would close MemoryStream automatically and using would then do double dispose
                // Code analysis does not understand that. That's why there is a suppress message.
                CloseOutput = false, 
                Encoding = enc,
                OmitXmlDeclaration = false,
                Indent = true
            };
            using (System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(ms, xmlWriterSettings))
            {
                XmlSerializer s = new XmlSerializer(typeof(T));
                s.Serialize(xw, obj);
            }
    
            return enc.GetString(ms.ToArray());
        }
    }
    
        
    17
    2014-03-17 13: 46: 27Z
    1. Cosa ne pensi della tua risposta risolve il problema per cui l'impostazione della proprietà XmlWriterSettings per Encoding non sembra propagarsi all'output finale? Ho impostato la proprietà Encoding di XmlWriterSettings a Encoding.UTF8 e ho passato questo XmlWriterSettings a XmlWriter.Create, ma continua a serializzare come utf-16. Lo stesso problema che l'OP ha. Non vedo nulla nel tuo codice che possa cambiarlo. Qual è il pezzo mancante?
      2015-10-28 18: 43: 21Z
    2. Ho trovato la mia risposta qui: stackoverflow.com/a/4928759/1195273 . Stavo usando un StringBuilder invece di un MemoryStream. L'uso di StringBuilder ignora l'impostazione Encoding. Parla della complessità nascosta - sheesh!
      2015-10-28 18: 44: 49Z
    3. @ crush Sono felice che tu abbia trovato il pezzo mancante :) e che abbia funzionato per te.
      2015-10-28 19: 52: 31Z

    Prova questo

     
    public static void SerializeXMLData(string pth, object xmlobj)
        {
            XmlSerializer serializer = new XmlSerializer(xmlobj.GetType());
            using (XmlTextWriter tw = new XmlTextWriter(pth, Encoding.UTF8))
            {
                tw.Formatting = Formatting.Indented;
                serializer.Serialize(tw, xmlobj);
            }
        }
    
        
    3
    2014-03-17 11: 45: 48Z

    La soluzione è semplice:
    Utilizzare una classe di StringWriter derivata da StringWriter e impostare la codifica nel costruttore e sovrascrivere la proprietà Encoding della classe base:

     
    public sealed class StringWriterWithEncoding : System.IO.StringWriter
    {
        private readonly System.Text.Encoding encoding;
    
        public StringWriterWithEncoding(System.Text.StringBuilder sb) : base(sb)
        {
            this.encoding = System.Text.Encoding.Unicode;
        }
    
    
        public StringWriterWithEncoding(System.Text.Encoding encoding)
        {
            this.encoding = encoding;
        }
    
        public StringWriterWithEncoding(System.Text.StringBuilder sb, System.Text.Encoding encoding) : base(sb)
        {
            this.encoding = encoding;
        }
    
        public override System.Text.Encoding Encoding
        {
            get { return encoding; }
        }
    }
    

    Quindi basta passare un'istanza di StringWriterWithEnccoding al metodo:

     
    public static string SerializeToXml<T>(T ThisTypeInstance)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        string strReturnValue = null;
    
        //SerializeToXml<T>(ThisTypeInstance, new System.IO.StringWriter(sb));
        SerializeToXml<T>(ThisTypeInstance, new StringWriterWithEncoding(sb, System.Text.Encoding.UTF8));
    
        strReturnValue = sb.ToString();
        sb = null;
    
        return strReturnValue;
    } // End Function SerializeToXml
    
        
    2
    2015-08-27 21: 20: 08Z
    1. molto semplice e ha funzionato come un incantesimo
      2016-02-01 14: 07: 32Z
fonte posta Qui
Altre domande