Сериализация объекта с изображением для сохранения в базе данных SQL
-
13-09-2019 - |
Вопрос
У меня есть следующий объект:
[Serializable]
public class ExampleImage
{
public int ID { get; set; }
public string Filename { get; set; }
public byte[] Content { get; set; }
}
Я храню это в List<ExampleImage>
который я затем передаю следующей функции, чтобы сериализовать его в строку:
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();
}
Затем я передаю эту сериализованную строку в хранимую процедуру в SQL2000 в качестве NTEXT
который затем обрабатывается для вставки его в базу данных:
SELECT * INTO #TempImages
FROM OpenXML(@iDoc, '/ArrayOfExampleImage/ExampleImage')
WITH ([Filename] VARCHAR(255) './Filename', [Content] IMAGE './Content')
Проблема, с которой я столкнулся, заключается в том, что изображение становится испорченным.В btye[]
не сохраняется должным образом в базе данных.С остальными полями все в порядке.Это первый раз, когда я пытаюсь отправить двоичные данные через XML в SQL, поэтому, скорее всего, на данный момент я делаю что-то не так.Это мой SerializeObjectToXmlString
решить проблему, и она не обрабатывает сериализацию byte[]
должным образом, может быть, OpenXML
SQL-функция или даже тот факт, что я отправляю XML в качестве NTEXT
параметр.Я бы ожидал, что функция serialize правильно закодирует двоичный файл, но я могу ошибаться.
Есть идеи, в чем проблема или, может быть, лучший подход к сохранению сразу нескольких изображений?
Редактировать: Я думаю, что происходит то, что сериализатор создает byte[]
в строку base64, которая затем передается в сохраненный процесс как base64.Затем я сохраняю эту строку base64 в поле Image в SQL и считываю ее как btye[]
.Поэтому я думаю, что мне нужно каким-то образом перенести его из base64 в byte[]
прежде чем вставить его в мою таблицу?
Редактировать: Я начинаю думать, что мой единственный вариант - изменить сохраненный процесс, чтобы он выполнял только 1 изображение за раз и не использовал XML, а просто передавал byte[]
в качестве Image
введите и объедините все вызовы в транзакцию.
Решение
Как предположил Гайдин, base64 - лучший вариант.Это обычный способ записи двоичных данных в XML.Вы можете использовать следующий код :
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); }
}
}
(кстати, в Serializable
атрибут не имеет значения для сериализации XML)
Другие советы
Вместо сериализации его в XML, я бы сериализовал его в byte[] и сохранил это в поле типа varbinary (MAX) в вашей базе данных.
Вы могли бы попробовать преобразовать его в base64, затем сохранить в ТЕКСТОВОЕ поле или что-то в этом роде.