convertir varbinary en xml C #

J'ai AC # winforms Application qui enregistre les files dans la database sqlserver (2014) au champ varbinary (MAX)

Fonction Pour save

byte[] Bytefile; using (SqlConnection conn = new SqlConnection(DataHelper.GetConnection())) { conn.Open(); DataTable dt = new DataTable(); SqlCommand comm = new SqlCommand("Delete T_Articale_Files where Arsortingcle_id=" + ID, conn); comm.ExecuteNonQuery(); foreach (ssortingng file in Directory.GetFiles(varFilePath)) { using (var stream = new FileStream(Path.Combine(varFilePath, file), FileMode.Open, FileAccess.Read)) { using (var reader = new BinaryReader(stream)) { Bytefile = reader.ReadBytes((int)stream.Length); } } using (var sqlWrite = new SqlCommand("INSERT INTO T_Articale_Files (Arsortingcle_id,FileName,FileData) Values(@ID,@FileName,@File)", conn)) { sqlWrite.Parameters.Add("@ID", SqlDbType.Int, 10).Value = ID; sqlWrite.Parameters.Add("@FileName", SqlDbType.NVarChar, 50).Value = Path.GetFileName(file); sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = Bytefile; sqlWrite.ExecuteNonQuery(); } } } 

Fonction à récupérer

  using (SqlConnection conn = new SqlConnection(DataHelper.GetConnection())) // using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails)) { conn.Open(); DataTable dt = new DataTable(); SqlCommand comm = new SqlCommand("SELECT id,FileName FROM T_Articale_Files WHERE Arsortingcle_id = @varID", conn); comm.Parameters.AddWithValue("@varID", varID); dt.Load(comm.ExecuteReader()); foreach (DataRow item in dt.Rows) { using (var sqlQuery = new SqlCommand(@"SELECT FileData FROM T_Articale_Files WHERE id = @ID", conn)) { sqlQuery.Parameters.AddWithValue("@ID", item["id"]); using (var sqlQueryResult = sqlQuery.ExecuteReader()) while (sqlQueryResult.Read()) { var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))]; sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length); using (var fs = new FileStream(Path.Combine(varPathToNewLocation, item["FileName"].ToSsortingng()), FileMode.Create, FileAccess.Write)) fs.Write(blob, 0, blob.Length); } } } } 

cela fonctionne bien Maintenant, j'ai demandé de convertir la database en XML pour les PC qui n'ont pas login au server

Fonction à convertir en XML

  var xmlFileData = ""; DataSet ds = new DataSet(); var tables = new[] { "V_Articale", "T_Articale", "T_City", "T_Classification", "T_Country", "T_Locations", "T_milishia", "T_Search", "T_statistics", "T_TerrorGroups", "T_Tribes", "T_Users", "T_Articale_Files" }; foreach (var table in tables) { var query = "SELECT * FROM " + table; SqlConnection conn = GetConnection(); SqlCommand cmd = new SqlCommand(query, conn); conn.Open(); SqlDataAdapter da = new SqlDataAdapter(cmd); DataTable dt = new DataTable(table); da.Fill(dt); conn.Close(); conn.Dispose(); ds.Tables.Add(dt); if(table== "T_Articale_Files") { foreach (DataRow item in dt.Rows) { Byte[] file = GetBytes(item["FileData"].ToSsortingng()); } } } xmlFileData = ds.GetXml(); 

cela fonctionne bien, sauf pour le file binary, il est converti en text lorsque

Le résultat XML

 <T_Articale_Files> <id>6</id> <Arsortingcle_id>1013</Arsortingcle_id> <FileName>falcon banner.jpg</FileName> <FileData>/9j/4AAQSkZJRgABAgEASABIAAD/4QleRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUA</FileData> 

quand essayer de le convertir en image, il me donne le file 1kb avec la string pas l'image réelle

est-il spécial convertir pour le domaine binary

Je vous remercie

Modifier le problème résolu grâce à @ grek40 Solution Convertir en XML

  var xmlstream = new SsortingngWriter(); ds.WriteXml(xmlstream, XmlWriteMode.WriteSchema); ssortingng xmlWithSchema = xmlstream.ToSsortingng(); 

où ds est un set de données

Convertir en file

  private void databaseFileRead(int varID, ssortingng varPathToNewLocation) { DataSet ds = new DataSet(); ds.ReadXml(XMLpath); DataTable dt = new DataTable(); dt = ds.Tables["T_Articale_Files"]; DataView dv = new DataView(dt); dv.RowFilter = "Arsortingcle_id=" + varID; if (dv.Count > 0) { foreach (DataRowView item in dv) { byte[] ssortingngArray = (byte[])(item["FileData"]); File.WriteAllBytes(Path.Combine(Filepath, item["FileName"].ToSsortingng()), ssortingngArray ); // save image to disk } } 

Afin d'avoir un enencoding réversible de string de données binarys, vous pouvez utiliser l'enencoding Base64

 public byte[] StrToByteArray(ssortingng str) { return Convert.FromBase64Ssortingng(str); } public ssortingng ByteArrToSsortingng(byte[] byteArr) { return Convert.ToBase64Ssortingng(byteArr); } 

transforme les octets en string stockée dans xml et restaure les octets de la string lors de l'utilisation.

Initialement, datatables sont correctement écrites en XML. Le problème est le plus probable avec la fonction de récupération. Puisque le file xml ne contient pas d'informations sur le schéma, il traitera le <FileData> comme du text, à less qu'il ne soit indiqué différemment.

Pour permettre une relecture correcte, vous avez besoin d'un schéma prédéfini lors de la lecture ou vous devez écrire le schéma avec les tables:

 dataSet.WriteXml(filenameOrStream, XmlWriteMode.WriteSchema) // later read the xml and it will respect the schema information dataSet.ReadXml(filenameOrStream); 

Un petit échantillon des différents aspects:

 var sourceDataSet = new DataSet(); var sourceTable = new DataTable("TableWithBinary"); sourceDataSet.Tables.Add(sourceTable); sourceTable.Columns.Add("Id"); sourceTable.Columns.Add("File", typeof(byte[])); sourceTable.Rows.Add(1, new byte[] { 1, 0, 2 }); sourceTable.Rows.Add(2, new byte[] { 1, 3, 2 }); // write option 1 ssortingng schema = sourceDataSet.GetXmlSchema(); ssortingng getxml = sourceDataSet.GetXml(); // write option 2 var writexmlstream = new SsortingngWriter(); sourceDataSet.WriteXml(writexmlstream, XmlWriteMode.WriteSchema); ssortingng writexmlWithSchema = writexmlstream.ToSsortingng(); // read wrong (missing schema) var targetCorrupted = new DataSet(); targetCorrupted.ReadXml(new SsortingngReader(getxml)); // read correct with schema in every xml file var targetFromXmlWithSchema = new DataSet(); targetFromXmlWithSchema.ReadXml(new SsortingngReader(writexmlWithSchema)); // read correct with separate schema definition and data var targetFromXml = new DataSet(); targetFromXml.ReadXmlSchema(new SsortingngReader(schema)); targetFromXml.ReadXml(new SsortingngReader(getxml)); 

Le format standard pour binary dans XML est base64 . Je ne pense pas, qu'il y a quelque chose de mal avec ce qui précède …

Vous devez garder à l'esprit que plusieurs caractères sont interdits dans XML. Vous ne pouvez pas simplement placer des données binarys entre deux balises XML. S'il y avait le code numérique pour un < (ou un autre caractère interdit) quelque part dans votre binary par hasard, il se casserait.

La string que vous montrez ressemble beaucoup à un code base64.

Essaye ça

 DECLARE @ssortingng VARCHAR(100)='Hello World with forbidden characters (< & >)'; DECLARE @binary VARBINARY(MAX) = CAST(@ssortingng AS VARBINARY(MAX)); DECLARE @xml XML=(SELECT @ssortingng AS ssortingng, @binary AS bin FOR XML PATH('test')); SELECT @xml; 

–Le résultat (avec les entités encodées et le binary implicitement converti en base64)

 <test> <ssortingng>Hello World with forbidden characters (&lt; &amp; &gt;)</ssortingng> <bin>SGVsbG8gV29ybGQgd2l0aCBmb3JiaWRkZW4gY2hhcmFjdGVycyAoPCAmID4p</bin> </test> 

– Maintenant, nous lisons à partir du XML (les entités sont recodées, le binary est représenté par une string HEX et ceci peut être renvoyé à l'ancien VARCHAR(MAX)

 SELECT @xml.value('(/test/ssortingng)[1]','nvarchar(max)') AS TheSsortingngAsIs ,@xml.value('(/test/bin)[1]','varbinary(max)') AS TheSsortingngAsBinary_HEX ,CAST(@xml.value('(/test/bin)[1]','varbinary(max)') AS VARCHAR(100)) AS ReConverted 

Les resultats

 The ssortingng *as-is*: Hello World with forbidden characters (< & >) binary data HEX: 0x48656C6C6F20576F726C64207769746820666F7262696464656E206368617261637465727320283C2026203E29 ReConverted: Hello World with forbidden characters (< & >)