Serialização de um objeto com uma imagem para ser salvo no banco de dados SQL
-
13-09-2019 - |
Pergunta
Eu tenho o seguinte objeto:
[Serializable]
public class ExampleImage
{
public int ID { get; set; }
public string Filename { get; set; }
public byte[] Content { get; set; }
}
Eu armazenar isso em um List<ExampleImage>
que eu então passar para a seguinte função para serializar-lo para uma string:
static string SerializeObjectToXmlString(object o)
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(o.GetType());
System.IO.StringWriter writer = new System.IO.StringWriter();
serializer.Serialize(writer, o);
return writer.ToString();
}
Eu, então, passar essa string serializada para um procedimento armazenado em SQL2000 como um NTEXT
que então tratado para inseri-lo no banco de dados:
SELECT * INTO #TempImages
FROM OpenXML(@iDoc, '/ArrayOfExampleImage/ExampleImage')
WITH ([Filename] VARCHAR(255) './Filename', [Content] IMAGE './Content')
O problema que estou tendo é a imagem está sendo destruído. O btye[]
não está sendo salvo corretamente para o DB. Os outros campos são muito bem. Esta é a primeira vez que tenho tentativa de enviar um dados binários via XML para SQL por isso estou provavelmente fazendo algo errado neste momento. É minha função SerializeObjectToXmlString
o problema e não está a lidar com a serialização de um byte[]
corretamente, talvez a função OpenXML
SQL ou mesmo o fato de que estou enviando o XML no como um param NTEXT
. Eu esperaria a função serialize para codificar o binário corretamente, mas eu poderia estar errado.
Qualquer idéia do que é a questão ou talvez uma melhor abordagem para salvar um monte de imagens de uma vez?
Editar: eu acho que está acontecendo, é o serializador está fazendo a byte[]
em uma string base64, que é então se passa ao proc armazenado como base64. Estou em seguida, salvando esta string base64 em um campo de imagem em SQL e lê-lo como um btye[]
. Então eu acho que eu preciso de alguma forma obtê-lo de base64 a um byte[]
antes de inseri-lo na minha mesa?
Editar: Eu estou começando a pensar que a minha única opção é mudar o proc armazenados apenas para fazer 1 imagem de cada vez e não usar XML e apenas passar na byte[]
como um tipo Image
e envoltório todas as chamadas em uma transação.
Solução
Como Gaidin sugeriu, base64 é a melhor opção. É a maneira usual de gravar dados binários em XML. Você pode usar o seguinte código:
public class ExampleImage
{
public int ID { get; set; }
public string Filename { get; set; }
[XmlIgnore]
public byte[] Content { get; set; }
[XmlElement("Content")]
public string ContentBase64
{
get { return Convert.ToBase64String(Content); }
set { Content = Convert.FromBase64String(value); }
}
}
(a propósito, o atributo Serializable
não tem nenhum significado para a serialização XML)
Outras dicas
Em vez de serialização-lo para XML, eu serializar-lo para um byte [] e loja que em varbinary (MAX) campo digite seu DB.
Você poderia tentar convertê-lo para base64, em seguida, salvando-o ao campo de texto ou algo assim.