I have a pdf file , in admin all the pdf files are converted into byte array stored in database.
public void Getfile()
{
byte[] file;
string varFilePath = #"D:\PDFConvertion\pdf\100CountryHouses.pdf";
try
{
using (var stream = new FileStream(varFilePath, FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(stream))
{
file = reader.ReadBytes((int)stream.Length);
}
}
SqlConnection sqlCon;
sqlCon = new SqlConnection("server details");
sqlCon.Open();
using (var sqlWrite = new SqlCommand("INSERT INTO pdftest Values(#File)", sqlCon))
{
sqlWrite.Parameters.Add("#File", SqlDbType.VarBinary, file.Length).Value = file;
sqlWrite.ExecuteNonQuery();
}
sqlCon.Close();
MessageBox.Show("Converted Success - Length " + Convert.ToString(file.Length));
}
catch (Exception Ex)
{
throw Ex;
}
}
Once file has been uploaded user has view the file , i have used adobe reader component to load the pdf file .
private void button1_Click(object sender, EventArgs e)
{
string varPathToNewLocation = #"D:\PDFConvertion\converted\test.pdf";
try
{
SqlConnection sqlCon;
sqlCon = new SqlConnection("");
sqlCon.Open();
using (var sqlQuery = new SqlCommand(#"SELECT test FROM [dbo].[pdftest] ", sqlCon))
{
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null)
{
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(varPathToNewLocation, FileMode.Create, FileAccess.Write))
fs.Write(blob, 0, blob.Length);
}
}
sqlCon.Close();
axAcroPDF1.LoadFile(#"D:PDFConvertion\converted\test.pdf");
}
catch (Exception Ex)
{
throw Ex;
}
}
But i want to load the file in adobe reader component directly without storing in location.
What you want is something like a LoadStream api. A quick search of the Acrobat SDK didn't seem to turn anything up.
If it is a web application you can put the pdf file into the Response object of the web page. Then the browser opens acrobat reader automatically. Here is the c# snippet:
Response.Buffer = true;
Response.Clear();
Response.ContentType = "application/pdf";
// if blob is the byte array of the pdf file
Response.BinaryWrite(blob);
Response.Flush();
Response.End();
Related
i am using ICSharpCode.SharpZipLib.Zip to compress the files & download zip file, and here using SQL File stream to store any kind of file(any amount of GB).
Then, how can i zip the files from sql file stream and get download...
And i tried something like below, which is throwing an exception "size was 845941, but I expected 16 at ICSharpCode.SharpZipLib.Zip.ZipOutputStream.CloseEntry()".How to solve this...
string zipFileName = "ZipName.zip";
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "fileName=" + zipFileName);
byte[] buffer = new byte[4096];
ZipOutputStream zipOutputStream = new ZipOutputStream(Response.OutputStream);
zipOutputStream.SetLevel(3);
string cs = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
foreach (Filec file1 in Files)
{
StreamModel model123 = new StreamModel();
const string SelectTSql = #"
SELECT FileData.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT(), FileType
FROM MyFiles WHERE FileId = #FileId";
using (TransactionScope ts = new TransactionScope())
{
using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(cs))
{
conn.Open();
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(SelectTSql, conn))
{
cmd.Parameters.Add("#FileId", System.Data.SqlDbType.Int).Value = Convert.ToInt32(file1.FileId);
using (System.Data.SqlClient.SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
model123.serverPath = rdr.GetSqlString(0).Value;
model123.serverTxn = rdr.GetSqlBinary(1).Value;
model123.filetype = rdr.GetSqlString(2).Value;
rdr.Close();
}
}
}
ZipEntry zipEntry = new ZipEntry(ZipEntry.CleanName(file1.FileName));
zipEntry.Size = model123.serverTxn.Length;
zipOutputStream.PutNextEntry(zipEntry);
byte[] buffer3 = new byte[4096];
using (System.Data.SqlTypes.SqlFileStream sfs = new System.Data.SqlTypes.SqlFileStream(model123.serverPath, model123.serverTxn, FileAccess.Read))
{
int bytesRead;
while ((bytesRead = sfs.Read(buffer3, 0, buffer3.Length)) > 0)
{
zipOutputStream.Write(buffer3, 0, bytesRead);
}
sfs.Close();
}
zipOutputStream.CloseEntry(); // at this line throwing an exception.
ts.Complete();
}
}
zipOutputStream.Close();
Response.Flush();
Response.End();
After Understanding each line of code, i figured out the solution..
1) "zipEntry.Size = model123.serverTxn.Length;" this line is causing the exception as "size was 845941, but I expected 16"..because "model123.serverTxn.Length" is not the complete size of the file., So i changed this to "sfs.Length" which is SqlFileStream length.
2) zipOutputStream level is set maximum as "zipOutputStream.SetLevel(9)" because, i am zipping the large size files here like videos..
3) And TransactionScope has to be more, other wise the complete file(large files more than 500mb) is not going to be downloaded hence we will see file damaged error message after downloading..
string zipFileName = "ZipName.zip";
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "fileName=" + zipFileName);
byte[] buffer = new byte[4096];
ZipOutputStream zipOutputStream = new ZipOutputStream(Response.OutputStream);
zipOutputStream.SetLevel(9); // Point 2
try
{
string cs = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
foreach (Filec file1 in Files)
{
StreamModel model123 = new StreamModel();
const string SelectTSql = #"SELECT FileData.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT(), FileType
FROM MyFiles WHERE FileId = #FileId";
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions { Timeout = TimeSpan.FromDays(1) })) // Point 3
{
using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(cs))
{
conn.Open();
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(SelectTSql, conn))
{
cmd.Parameters.Add("#FileId", System.Data.SqlDbType.Int).Value = Convert.ToInt32(file1.FileId);
using (System.Data.SqlClient.SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
model123.serverPath = rdr.GetSqlString(0).Value;
model123.serverTxn = rdr.GetSqlBinary(1).Value;
model123.filetype = rdr.GetSqlString(2).Value;
rdr.Close();
}
}
}
using (System.Data.SqlTypes.SqlFileStream sfs = new System.Data.SqlTypes.SqlFileStream(model123.serverPath, model123.serverTxn, FileAccess.Read))
{
ZipEntry zipEntry = new ZipEntry(ZipEntry.CleanName(file1.FileName));
zipEntry.Size = sfs.Length; // Point 1
zipOutputStream.PutNextEntry(zipEntry);
int bytesRead;
while ((bytesRead = sfs.Read(buffer, 0, buffer.Length)) > 0)
{
if (!Response.IsClientConnected)
{
break;
}
zipOutputStream.Write(buffer, 0, bytesRead);
Response.Flush();
}
sfs.Close();
}
ts.Complete();
}
zipOutputStream.CloseEntry();
}
zipOutputStream.Finish();
zipOutputStream.Close();
Response.Flush();
Response.End();
}
catch (Exception ex)
{
TempData["ErrorMessage"] = "Oohhhh! Exception Occured(Error)...";
}
When I try to read images from my SQL Server database I get an error: on the following line:
Image returnImage = Image.FromStream(ms);
An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid.
My code:
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
private ArrayList GetImagesFromDB(string code)
{
ArrayList images = new ArrayList();
SqlCommand selectImagesCommand = new SqlCommand("SELECT * FROM images WHERE code = '"+code+"'");
selectImagesCommand.Connection = myConnection;
if(myConnection.State == ConnectionState.Closed){
myConnection.Open();
}
SqlDataReader imagesReader = selectImagesCommand.ExecuteReader();
while (imagesReader.Read())
{
byte[] newimagebytesRecord = (byte[])imagesReader["image"];
images.Add(byteArrayToImage(newimagebytesRecord));
}
return images;
}
Use SqlDataReader.GetStream method.
So you would do something along the lines:
using(SqlDataReader imageReader = selectSingleImageCommand.ExecuteReader(CommandBehavior.SequentialAccess))
{
if (imageReader.Read())
{
using (Stream backendStream = imageReader.GetStream(0))
{
//Do whater you need with the Stream
}
}
}
You migh also be able to iterate over the reader (selecting multiple images) and open stream by stream - I haven't use it that way though, so I'm not 100% sure.
try
{
SqlCommand cmdSelect=new SqlCommand("select Picture" +
" from tblImgData where ID=#ID",this.sqlConnection1);
cmdSelect.Parameters.Add("#ID",SqlDbType.Int,4);
cmdSelect.Parameters["#ID"].Value=this.editID.Text;
this.sqlConnection1.Open();
byte[] barrImg=(byte[])cmdSelect.ExecuteScalar();
string strfn=Convert.ToString(DateTime.Now.ToFileTime());
FileStream fs=new FileStream(strfn,
FileMode.CreateNew, FileAccess.Write);
fs.Write(barrImg,0,barrImg.Length);
fs.Flush();
fs.Close();
pictureBox1.Image=Image.FromFile(strfn);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.sqlConnection1.Close();
}
I send the image from a Windows Phone 8 App to an MVC WCF service. I know it is receiving the image, because when it does receive the image, it is instructed to save the image in a local folder called "uploads". Every time the image gets there it is put into this folder so I can tell that it was uploaded. My trouble is with uploading it to my SQL Server database. Everything compiles, but when I check my database table, it is not there. Please help.
namespace MVCImageUpload.Controllers
{
public class FileUploadController : Controller
{
// GET: /FileUpload/
[HttpPost]
public ActionResult Index()
{
var fileUploaded = false;
foreach (string upload in Request.Files)
{
if (!HasFile(Request.Files[upload]))
continue;
string path = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"uploads");
string filename = Path.GetFileName(
Request.Files[upload].FileName);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Request.Files[upload].SaveAs(Path.Combine(
path, filename));
fileUploaded = true;
updatedata(filename);
}
this.ViewData.Add("uploaded", fileUploaded);
return View();
}
private static bool HasFile(HttpPostedFileBase file)
{
return (file != null && file.ContentLength > 0) ? true : false;
}
private void updatedata(string imagename)
{
//use filestream object to read the image.
//read to the full length of image to a byte array.
//add this byte as an oracle parameter and insert it into database.
try
{
//proceed only when the image has a valid path
if (imagename != "")
{
FileStream fs;
fs = new FileStream(#imagename, FileMode.Open, FileAccess.Read);
//a byte array to read the image
byte[] picbyte = new byte[fs.Length];
fs.Read(picbyte, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
//open the database using odp.net and insert the data
string connstr = #".\SQLEXPRESS;Database=ImageDB;Trusted_Connection=True;";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
string query;
query = "insert into Images(ActualImage) values(#ActualImage)";
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "ActualImage";
picparameter.Value = picbyte;
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add(picparameter);
cmd.ExecuteNonQuery();
//MessageBox.Show("Image Added");
cmd.Dispose();
conn.Close();
conn.Dispose();
//Connection();
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
}
}
You can skip a step and save the file directly into the database.
HttpPostedFileBase Picture = Request.Files["Picture"];
Byte[] Bytes = new byte[Picture.ContentLength];
string ContentType = Picture.ContentType;
string FileName = Picture.FileName;
Picture.InputStream.Read(Bytes, 0, Picture.ContentLength);
You now have Name, Bytes, and content type which u can store in the database.
Let me start off by saying I'm sure this is something that's quite simple, unfortunately I just can't seem to figure it out. So here's my problem, I query the database, return what I need, zip it all up, and prompt user to save. When You attempt to open this, there are no files inside the folder. Where has my data gone? I stepped through everything, and it appears to write everything properly. Any help would be greatly appreciated!!
if (e.CommandName == "DownloadAttachment")
{
e.Canceled = true;
// Create a zip and send it to the client.
//Response.Write(#"<script language='javascript'>alert('Details saved successfully')</script>");
var item = e.Item as GridEditableItem;
fileId = (int)item.GetDataKeyValue("Unique");
FileData[] allrecords = null;
using (
SqlConnection conn =
new SqlConnection(ConfigurationManager.ConnectionStrings["PtcDbModelEntities"].ConnectionString))
{
using (
SqlCommand comm = new SqlCommand("Select Unique1, BinaryData, FileName from PtcDbTracker.dbo.CafFileTable where Unique1=#fileId AND FileName IS NOT NULL", conn))
{
comm.Parameters.Add(new SqlParameter("#fileId", fileId));
conn.Open();
using (var reader = comm.ExecuteReader())
{
var list = new List<FileData>();
while (reader.Read())
{
list.Add(new FileData { Unique1 = reader.GetInt32(0) });
long len = reader.GetBytes(1, 0, null, 0, 0);
Byte[] buffer = new byte[len];
list.Add(new FileData { BinaryData = (byte)reader.GetBytes(1, 0, buffer, 0, (int)len), FileName = reader.GetString(2) });
allrecords = list.ToArray();
}
}
conn.Close();
}
}
using (var compressedFileStream = new MemoryStream())
{
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false))
{
if (allrecords != null)
{
foreach (var record in allrecords)
{
//Create a zip entry for each attachment
if (record.FileName != null)
{
var zipEntry = zipArchive.CreateEntry(record.FileName);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(record.BinaryData))
{
using (var zipEntryStream = zipEntry.Open())
{
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
}
}
Response.ClearContent();
Response.ClearHeaders();
Response.BinaryWrite(compressedFileStream.ToArray());
Response.AppendHeader("Content-Disposition", "Attachment; filename=result.zip");
Response.Flush();
Response.Close();
zipArchive.Dispose();
//How Do I Prompt for open or save?
}
}
Are you sure the BinaryWrite is getting a valid ByteArray?
In any case here's a tested method to output a file to the Response with the typically needed headers for binary attachments:
public bool WriteFile(byte[] byteContent, DateTime dtTimeStamp, string urlFilename)
{
HttpContext context = HttpContext.Current;
HttpResponse response = context.Response;
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.BufferOutput = true;
response.AppendHeader("Content-Length", byteContent.Length.ToString());
response.AppendHeader("Content-Type", "application/octet-stream");
response.AppendHeader("Last-Modified", dtTimeStamp.ToString("R"));//Last-Modified Wed, 28 Aug 2013 10:16:46 GMT
response.AppendHeader("Content-Disposition", "inline; filename=\"" + urlFilename + "\"");
response.BinaryWrite(byteContent);
response.Flush();
// Prevents any other content from being sent to the browser
response.SuppressContent = true;
context.ApplicationInstance.CompleteRequest();
return true;
}
I have been trying to perform a simple upload operation of an image using the asp FileUpload control and save it in Oracle database. Though I have hardcoded a few lines, I somehow succeeded. But then, I really want to understand the issue and I seek experts opinion. After a lot of googling, I attempted using various code snippets in my web application and eventually failed. Here is the code that partially worked for me.
protected void btnSubmit_Click(object sender, EventArgs e)
{
String strFileName = Path.GetFileName(imgUpload.PostedFile.FileName);
String strFileExtension = Path.GetExtension(imgUpload.PostedFile.FileName);
byte[] byteArray = null;
if (imgUpload.PostedFile != null)
{
using (FileStream fs = new FileStream(strFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
byteArray = new byte[fs.Length];
int iBytesRead = fs.Read(byteArray, 0, (int)fs.Length);
}
string sql = " INSERT INTO IMAGETBL(ID,IMAGE) VALUES(:ID, :IMAGE) ";
OracleConnection conn = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVER_NAME=XE)));User Id=sakthi_studdb;Password=sakthi;");
try
{
conn.Open();
OracleCommand cmd = new OracleCommand(sql, conn);
cmd.Parameters.Add("ID", OracleDbType.Int32, 4, ParameterDirection.Input);
cmd.Parameters.Add("IMAGE", OracleDbType.Blob, byteArray, ParameterDirection.Input);
cmd.ExecuteNonQuery();
secondlabel.Text = "Image added to blob field";
}
catch (Exception ex)
{
secondlabel.Text = ex.ToString();
}
finally
{
conn.Close();
}
}
}
When I run this code, it prompts Filenotfound error. Could not find file 'C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0'
Then to make it work I had to manually copy paste my image file in the above mentioned location. There must be a way to create a directory and save the images there temporarily. Later the same image should be inserted in Oracle database.
HttpPostedFile imgFile = imgUpload.PostedFile;
int imgFileLength = imgFile.ContentLength;
if (imgFileLength > 0)
{
var fileName = System.IO.Path.GetFileName(imgFile.FileName);
var fileUpload = Path.Combine(Server.MapPath("~/user_uploads"), fileName);
imgFile.SaveAs(fileUpload);
if (System.IO.File.Exists(fileUpload))
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(fileUpload))
{
var input = sr.ReadToEnd();
var lines = Regex.Split(input, "#!#");
And another one..
string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/user_uploads");
string fn = System.IO.Path.GetFileName(imgUpload.PostedFile.FileName);
imgUpload.PostedFile.SaveAs(System.IO.Path.Combine(path, fn));
Mylabel.Text = Path.GetFullPath(strFileName);
imgUpload.PostedFile.SaveAs(strFileName);
I hardly understood these snippets. Also, if you know easier methods to accomplish the same do suggest. Kindly help me out!
If you're just uploading a file and want to push it to the Db you should be able to just grab the postedFile value and use it.
Tweaking your first snipped:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (imgUpload.PostedFile != null)
{
BinaryReader b = new BinaryReader(imgUpload.InputStream);
byte[] byteArray = b.ReadBytes(imgUpload.ContentLength);
string sql = " INSERT INTO IMAGETBL(ID,IMAGE) VALUES(:ID, :IMAGE) ";
OracleConnection conn = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVER_NAME=XE)));User Id=sakthi_studdb;Password=sakthi;");
try
{
conn.Open();
OracleCommand cmd = new OracleCommand(sql, conn);
cmd.Parameters.Add("ID", OracleDbType.Int32, 4, ParameterDirection.Input);
cmd.Parameters.Add("IMAGE", OracleDbType.Blob, byteArray, ParameterDirection.Input);
cmd.ExecuteNonQuery();
secondlabel.Text = "Image added to blob field";
}
catch (Exception ex)
{
secondlabel.Text = ex.ToString();
}
finally
{
conn.Close();
}
}
}