Reputation: 197
I'm a newbie to C#
and EF
so apologies if I get some terminology incorrect as I'm currently fixing some code from a developer who wrote our Web APIs
but is not available.
In summary we have a JAVA
front end that uploads PDF
files and stores them in our SQL Server
database as varbinary(max)
. When the JAVA
web app downloads the PDF
it calls a database function which returns the varbinary
data into a byte[]
variable and then the JAVA
web app is able to file stream it and save as a PDF
no problems.
The database value for the file data, as well as what it returned by the function that returns the varbinary(max)
column as well as what is stored in the byte[]
that is used in JAVA
and then converted to a string, are all the same and looks like :
"0x255044462D312E360D25E2E3CFD30D0A34372030206F626A0D3C3C2F414442455F46696C6C5369676E496E666F3C3C2F56657273696F6E203130302F666F726D4..."
which from what I can tell is the format for varbinary
data.
In the Web API
which uses EF
, the same function is modelled in the EF
Model and it appears as a Complex Type
, and the Filedata
column is of type Binary
which according to MS docs
this is correct:
In the C# model, the Filedata
is defined as :
public byte[] FileData { get; set; }
There is a Controller
that returns the data from the function as follows:
[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();
}
}
}
The entity variable contains the Filedata
value which we can then return in our Web API to be used by our mobile apps to display PDFs
. The returned value is different to what is in the database and looks like:
"JVBERi0xLjYNJeLjz9MNCjQ3IDAgb2JqDTw8L0FEQkVfRmlsbFNpZ25JbmZvPDwvVmVyc2lvbiAxMDAvZm9ybUlEKDY0OTFiNDYzLTA2MGEtNGU1Yy05NmYyLTljMThkMTZlNDlhZik+Pi9NZXRhZGF0YSA1NSAwIFIvT0NQcm9wZXJ0aWVzPDwvRDw8L09OWzU2IDAgUl0vT3JkZXJbXS9SQkdyb3Vwc1tdPj4vT0NHc1s1NiAwI..."
When we use this for the PDF
file the PDF
file is corrupted. There is other data that is returned by the function and the data is correct, but none of the data is of type varbinary
. The varbinary
data is the only field we are having issues with and is returned different to what is stored in the database.
The commented code above that converts it to a string also displays the different data.
My question is why is EF
bringing back different data to what is in the database for the varbinary(max) column
?
I hope I have explained enough but if you need more details please let me know.
Thanks.
Upvotes: 1
Views: 2694
Reputation: 797
As others have mentioned that you are returning an entity and MVC controller is returning base 64 in the response. If you want to get the file you can try the following code, slightly adjusted from your sample.
[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();
}
}
Upvotes: 2
Reputation: 1
The MVC Controller
Response is probably base64
Encoded, so you will need to use base64
Decoding in your client before creating the PDF.
Upvotes: 0