Entity Framework возвращает различное значение для типа varbinary в базе данных - PullRequest
1 голос
/ 24 февраля 2020

Я новичок от ie до C# и EF, поэтому извиняюсь за неправильную терминологию, так как в настоящее время исправляю код от разработчика, который написал наш Web APIs, но недоступен.

Итак, у нас есть JAVA интерфейс, который загружает PDF файлы и сохраняет их в нашей базе данных SQL Server как varbinary(max). Когда веб-приложение JAVA загружает PDF, оно вызывает функцию базы данных, которая возвращает данные varbinary в переменную byte[], а затем веб-приложение JAVA может передавать его в файл и сохранять как * 1015. * без проблем.

Значение базы данных для данных файла, а также то, что оно возвращает функцией, возвращающей столбец varbinary(max), а также то, что хранится в byte[], который используется в JAVA и затем преобразуются в строку, все они одинаковы и выглядят так:

"0x255044462D312E360D25E2E3CFD30D0A34372030206F626A0D3C3C2F414442455F46696C6C5369676E496E666F3C3C2F56657273696F6E203130302F666F726D4..."

, что, как я могу судить, является форматом для varbinary данных.

В Web API, который использует EF, та же функция смоделирована в модели EF и выглядит как Complex Type, а столбец Filedata имеет тип Binary, что согласно MS docs это правильно:

(https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-data-type-mappings?redirectedfrom=MSDN)

В модели C# Filedata определяется как:

public byte[] FileData { get; set; }

Существует Controller, который возвращает данные из функции следующим образом:

[HttpGet]
public IHttpActionResult FileAttachment_Get(string FileAttachmentID)
{
   using (TSTDBContext dbContext = new TSTDBContext())
   {
       Guid FileAttachmentGUID = new Guid(FileAttachmentID);
       var entity = dbContext.FileAttachment_Get(FileAttachmentGUID).SingleOrDefault();
       if (entity != null)
       {
            /*var str = System.Text.Encoding.Default.GetString(entity.FileData);*/
            return Ok(new { results = entity });
       }
       else
       {
           return NotFound();
       }
   }
}

Переменная сущности содержит значение Filedata w Затем мы можем вернуться в наш веб-API для использования нашими мобильными приложениями для отображения PDFs. Возвращаемое значение отличается от того, что находится в базе данных, и выглядит так:

"JVBERi0xLjYNJeLjz9MNCjQ3IDAgb2JqDTw8L0FEQkVfRmlsbFNpZ25JbmZvPDwvVmVyc2lvbiAxMDAvZm9ybUlEKDY0OTFiNDYzLTA2MGEtNGU1Yy05NmYyLTljMThkMTZlNDlhZik+Pi9NZXRhZGF0YSA1NSAwIFIvT0NQcm9wZXJ0aWVzPDwvRDw8L09OWzU2IDAgUl0vT3JkZXJbXS9SQkdyb3Vwc1tdPj4vT0NHc1s1NiAwI..."

Когда мы используем это для файла PDF, файл PDF поврежден. Есть другие данные, которые возвращаются функцией, и данные верны, но ни один из данных не имеет тип varbinary. Данные varbinary являются единственным полем, с которым у нас возникают проблемы, и возвращаются в отличие от того, что хранится в базе данных.

Приведенный выше прокомментированный код, который преобразует его в строку, также отображает различные данные.

У меня вопрос, почему EF возвращает разные данные в базу данных для varbinary(max) column?

Надеюсь, я объяснил достаточно, но если вам нужна дополнительная информация, пожалуйста, дайте мне знать .

Спасибо.

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Как уже упоминалось, вы возвращаете сущность, а MVC контроллер возвращает базу 64 в ответе. Если вы хотите получить файл, попробуйте следующий код, слегка откорректированный по вашему примеру.

[HttpGet, Route("api/files/{FileAttachmentID}")]
    public IHttpActionResult FileAttachment_Get(string FileAttachmentID)
    {
        using (TSTDBContext dbContext = new TSTDBContext())
        {
            Guid FileAttachmentGUID = new Guid(FileAttachmentID);
            var entity = dbContext.FileAttachment_Get(FileAttachmentGUID).SingleOrDefault();
            if (entity != null)
            {
                using (var stream = new MemoryStream())
                {
                    var result = new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new ByteArrayContent(entity.Content)//this is your varbinary value
                    };
                    result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                    {
                        FileName = entity.Name
                    };
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    var response = ResponseMessage(result);
                    return response;
                }
            }
            else
            {
                return NotFound();
            }
        }
0 голосов
/ 24 февраля 2020

Ответ MVC Controller, вероятно, base64 закодирован, поэтому вам нужно будет использовать base64 Декодирование в вашем клиенте перед созданием PDF.

...