I asked too many questions today but I have one more question. I'm trying to save an image into my database. I couldn't solve something. When I try to add image, it says paramater string can not be transleted into BYTE[]. Actually I'm giving bytes[] as paramater value.I tried to solve, but I couldn't find any answer maybe you can help me. Here is my code:
Stream fs = FileUpload1.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
//insert the file into database
string strQuery = "INSERT INTO Books(Book_Name, Author_Name, Image,In_Lib) VALUES (#BN, #AN, #IM,#LIB)";
SqlCommand cmd = new SqlCommand(strQuery);
string val1 = "" + TextBox1.Text;
string val2 = "" + TextBox2.Text;
cmd.Parameters.Add("#BN", SqlDbType.VarChar).Value = val1;
cmd.Parameters.Add("#AN", SqlDbType.VarChar).Value= val2;
cmd.Parameters.Add("#IM", SqlDbType.Binary).Value = bytes;
cmd.Parameters.Add("#LIB", SqlDbType.Binary).Value = "NO";
InsertUpdateData(cmd);
lblMessage.ForeColor = System.Drawing.Color.Green;
lblMessage.Text = "File Uploaded Successfully";
This line is invalid:
cmd.Parameters.Add("#LIB", SqlDbType.Binary).Value = "NO";
Based on your SQL, it looks like you intended to use a varchar there.
You have passed the string "NO" as a value of the Binary parameter #LIB:
cmd.Parameters.Add("#LIB", SqlDbType.Binary).Value = "NO";
I guess that is your problem.
Related
I would like to extract word documents stored as image type fields in SQL and save each individual document in a local folder. The doc files stored in the image type data in sql, are special encoded OLEObjects.
I am trying with one first but I need to do the same for each record in the table. This is what I have done so far:
Byte[] bytData = null;
string constring = #"mystirngconnection";
SqlCommand command = new SqlCommand(#"SELECT LongDescription FROM SuUserReport
WHERE ProductId = 53 AND UserReportId = 31525");
command.CommandType = CommandType.Text;
SqlConnection myconn = new SqlConnection(constring);
command.Connection = myconn;
myconn.Open();
using (SqlDataReader dr = command.ExecuteReader())
{
while (dr.Read())
{
bytData = (byte[])dr["LongDescription"];
}
}
if (bytData != null)
{
FileStream fs = new FileStream("C:\\Temp\\Test1.doc",
FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter br = new BinaryWriter(fs);
br.Write(bytData, 0, bytData.Length);
fs.Dispose();
}
I basically have two problems:
Reading this type of data it is very slow
Using the code above works for normal word documents however the information in my table has OLEObject encoded information, the code saves a word document but the information is only encoded characters
Previously, these images (word documents) where opened straightaway from SQL when the form was opened using an Access bound object frame linked to the longDescription image type field. The user could edit the document by double clicking on this special frame. The following code opens the document and makes it available to save changes:
With oleLongDescription
.Verb = acOLEVerbOpen 'In a separate window
.Action = acOLEActivate
End With
Could anybody be so kind as to help me out with this, please? I do not mind to use c# or vb as long as it works =).
Here is code that I use to open my blobs. the byte[] myarray is the blob field from the database, the fileext is the extension of the file you are creating and the filename is a name you give it. It deletes any previous file of this name.
public static string Openfilefrombyte(byte[] myarray, string fileext, string filename)
{
Computer myComputer = new Computer();
string filenamef = myComputer.FileSystem.SpecialDirectories.Temp + #"\" + filename + "." + fileext;
if (File.Exists(filenamef))
{
File.Delete(filenamef);
}
//save to file and open
FileStream myfs = new FileStream(filenamef, FileMode.CreateNew);
myfs.Write(myarray, 0, myarray.Length);
myfs.Flush();
myfs.Close();
myfs = null;
Process.Start(filenamef);
return "OK";
}
i basically have two problems:
Reading this type of data it is very slow
Answer : Yes Its Slowly But if You save The Image in sql database as VarBinary it will be Fast .
i am Using OpenFileDialog1 To Bring Image Or what You Want (Rar , Pdf .World ...)
If OpenFileDialog1.ShowDialog = DialogResult.OK Then
Try
T4.Text = OpenFileDialog1.FileName
T5.Text = Path.GetExtension(OpenFileDialog1.FileName)
T7.Text = Path.GetFileNameWithoutExtension(OpenFileDialog1.FileName)
Catch ex As Exception
End Try
End If
Here My Code I used it To Save Data In My Sql database :
Dim SQLCON As New SqlConnection(MyDataBaseCon)
Dim CMD As SqlCommand
Try
CMD = New SqlCommand("Insert Into TBLAtach (ID,AtachName,AtachMain,AtachFile,AtachNM,AtachDT,AtachAdres) Values (#ID,#AtachName,#AtachMain,#AtachFile,#AtachNM,#AtachDT,#AtachAdres)", SQLCON)
SQLCON.Open()
CMD.Parameters.Add(New SqlParameter("#ID", SqlDbType.Int)).Value = Val(T1.Text)
CMD.Parameters.Add(New SqlParameter("#AtachName", SqlDbType.Int)).Value = Val(T2.Text)
CMD.Parameters.Add(New SqlParameter("#AtachMain", SqlDbType.Int)).Value = Val(T3.Text)
Dim FSTream As New FileStream(OpenFileDialog1.FileName, FileMode.Open, FileAccess.Read)
Dim BNStream As New BinaryReader(FSTream)
Dim FAttach() As Byte = BNStream.ReadBytes(BNStream.BaseStream.Length)
CMD.Parameters.Add(New SqlParameter("#AtachFile", SqlDbType.VarBinary)).Value = FAttach
CMD.Parameters.Add(New SqlParameter("#AtachNM", SqlDbType.NVarChar, 50)).Value = T5.Text
CMD.Parameters.Add(New SqlParameter("#AtachDT", SqlDbType.NVarChar, 50)).Value = TD1.Text
CMD.Parameters.Add(New SqlParameter("#AtachAdres", SqlDbType.NVarChar, 250)).Value = T7.Text
CMD.ExecuteNonQuery()
SQLCON.Close()
FSTream.Close()
BNStream.Close()
MsgBox("Ok ", MsgBoxStyle.Information)
SearchID()
ClearTxT()
Catch ex As Exception
MsgBox(ex.Message)
SQLCON.Close()
WaitPic.Visible = False
End Try
Using the code above, saves a word document but the information is only encoded characters
Answer : To retrieve Data (Image,Pdf,RAR,...)
i am Using This Code :
Try
ItDataset.Clear()
Flt = "Select ID , AtachAdres + AtachNM AS 'Fname' , AtachFile from TBLAtach where ID = " & T1.Text & ""
ItDataset = GeneralDataManager.InquireData(ItDataset, Flt, "TBLAtach")
If Me.BindingContext(ItDataset, "TBLAtach").Count > 0 Then
Dim FName As String = ItDataset.Tables("TBLAtach").Rows(0).Item("Fname")
Dim FAttach() As Byte = CType(ItDataset.Tables("TBLAtach").Rows(0).Item("AtachFile"), Byte())
Dim FStream As New FileStream(FName.ToString, FileMode.OpenOrCreate, FileAccess.Write)
FStream.Write(FAttach, 0, (FAttach.Length))
Process.Start(FName)
FStream.Close()
End If
WaitPic.Visible = False
Catch ex As Exception
MsgBox(ex.Message)
End Try
And Change Your Connection To Your Data Base Con Connection
i hope this Answer Is Good For You .
Thank You .
I am developing a form application using C# and using mysql as database. I simply need to add or insert any type of files (.pdf, .doc, .xls etc) into mysql table column (say attachment table , column name is files, database name say MYDB).
Can anyone suggest the code in C# or the procedure in mysql to do the same.
I searched through the Internet but no relevant answer I found.
Any answer would be most appreciated.
You can insert any type of file by using this code....
uFileExpiryCapping pass 0 in this parameter.
In most of case uFilePhysicalPath will be same as uFilePath
public int UploadFileToDB(string uFilePath, string uFilename, string uFileType, int uFileExpiryCapping, string uFilePhysicalPath)
{
int intResult = 0;
try
{
string strConnectionString = string.Empty;
FileStream fs = new FileStream(uFilePath, FileMode.OpenOrCreate, FileAccess.Read);
byte[] fileData = new byte[fs.Length];
fs.Read(fileData, 0, System.Convert.ToInt32(fs.Length));
DataSet ds = new DataSet("UploadedFiles");
// Set up parameters (7 input and 1 output)
SqlParameter[] arParms = new SqlParameter[6];
//#UserName Input Parameter
arParms[0] = new SqlParameter("#UploadedFile", SqlDbType.Image);
arParms[0].Value = fileData;
arParms[0].Direction = ParameterDirection.Input;
//#FirstName Input Parameter
arParms[1] = new SqlParameter("#UploadedFileName", SqlDbType.NVarChar, 100);
arParms[1].Value = uFilename;
arParms[1].Direction = ParameterDirection.Input;
//#LastName Input Parameter
arParms[2] = new SqlParameter("#UploadedFileType", SqlDbType.NVarChar, 50);
arParms[2].Value = uFileType;
arParms[2].Direction = ParameterDirection.Input;
//#MiddleName Input Parameter
arParms[3] = new SqlParameter("#UploadedFileExpiryCapping", SqlDbType.Int);
arParms[3].Value = uFileExpiryCapping;
arParms[3].Direction = ParameterDirection.Input;
//#MobileNo Input Parameter
arParms[4] = new SqlParameter("#UploadedFileSaveLocation", SqlDbType.NVarChar, int.MaxValue);
arParms[4].Value = uFilePhysicalPath;
arParms[4].Direction = ParameterDirection.Input;
//#DataInserted Output Parameter
arParms[5] = new SqlParameter("#ErrorCode", SqlDbType.Int);
arParms[5].Direction = ParameterDirection.Output;
strConnectionString = ""; // initialise connection string
using (SqlConnection sqlConnection = new SqlConnection(strConnectionString))
{
intResult = SqlHelper.ExecuteNonQuery(sqlConnection, CommandType.StoredProcedure, "Your Procedure", arParms);
}
}
catch (Exception ex)
{
}
finally
{
fs.Dispose();
}
return intResult;
}
You can either store them as BINARY or VARCHAR fields or FILESTREAM by submitting them to your database as byte[] (a byte array). Whether you prefer one approach over the other will depend on your personal preference and use case (ie. How many objects are stored? What are the average filesizes?)
Recommended usage for uploading images/BLOB in this manner is explained on MSDN.
In C#, I am trying to save and load an image. I am saving it into a mysql database (type longblob) and trying to load it back into an picture box. The problem i keep getting is the error "Parameter is not valid", see code below
ConnectionClass Sqlconnection = new ConnectionClass();
Sqlconnection.ConnectionOpen();
OdbcCommand cmd = new OdbcCommand("Insert into pictest(pic) values('"+ Encoding.Unicode.GetBytes(richTextBox1.Rtf) + "')", Sqlconnection.connection);
int num = cmd.ExecuteNonQuery();
MessageBox.Show(num + " Rows inserted ");
Sqlconnection.ConnectionClose();
OdbcDataReader rd = null;
try
{
Sqlconnection.ConnectionOpen();
string query = "select * from pictest where id = 1";
cmd = new OdbcCommand(query, Sqlconnection.connection);
rd = cmd.ExecuteReader();
if (rd.Read())
{
byte[] bytes = (byte[])rd[1];
ImageConverter converter = new ImageConverter();
pictureBox1.Image = Image.FromStream(new MemoryStream(bytes)); <--Parameter is not valid
pictureBox1.Refresh();
pictureBox1.Image = Encoding.Unicode.GetString(bytes);
}
Sqlconnection.ConnectionClose();
rd.Close();
}
catch (Exception asd)
{
MessageBox.Show("Problem " + asd.Message);
Sqlconnection.ConnectionClose();
if (rd != null)
{
rd.Close();
}
}
what exact is the problem? Is the image not saving correctly? it should be as it is saving to a longblob. The record for the image says System.Byte[]
you should be able to inspect (via the debugger) the values inside OdbcDataReader before trying to cast the first field to byte[]. Take a look at what type is actually stored in the OdbcDataReader
Using SELECT * is problematic performance wise. It also leaves your rd[1] up for interpretation. If the order of columns ever changes, your code could break. Use rd["your_column_name"] to access the values. As of right now I can't tell if index 1 is correct due to the SELECT * and non-named indexing into the Items array.
First of all why you need to store image in MySql?
Why not in physical drive? If its not a crucial data go for saving it in physical drive.
However, here is code to retrieve:
public byte [] getImage(int imageNumber)
{
string strSql = "SELECT * FROM File";
DataSet ds = new DataSet("Image");
OdbcDataAdapter tempAP = new OdbcDataAdapter(strSql,this._objConn);
OdbcCommandBuilder objCommand = new OdbcCommandBuilder(tempAP);
tempAP.Fill(ds,"Table");
try
{
this._objConn.Open();
byte [] buffer = (byte [])ds.Tables["Table"].Rows[imageNumber]["Data"];
return buffer;
}
catch{this._objConn.Close();return null;}
finally{this._objConn.Close();}
}
Courtesy:
http://www.codeproject.com/Articles/6750/Storing-Images-in-MySQL-using-ASP-NET
For physical drive
http://www.codeproject.com/Articles/2113/C-Photo-Album-Viewer
I want to check if file exist in database or not using asp.net. I searched about that but I didn't find comparing with byte file.
I used Visual Studio 2010, SQL Server 2008 and C# language .
So, I tried to write this code but display error:
Incorrect syntax near 'System.Byte[])'.
Also, is there anther solution about this problem ?
code
if (ext == ".doc" || ext == ".docx" || ext == ".pdf" || ext == ".txt")
{
Stream fs = FileUpload1.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
//insert the file into database
strQuery = "insert into [Text File](User_id, T_Title, T_Extension, T_Data, Course_code, Course_num, T_Description, T_Keyword,Date)" +
" values (#User_id, #T_Title, #T_Extension, #T_Data, #Course_code, #Course_num, #T_Description, #T_Keyword, #Date)";
SqlCommand cmd = new SqlCommand(strQuery);
cmd.Parameters.Add("#User_id", (string)Session["ID"]);
cmd.Parameters.Add("#T_Title", SqlDbType.VarChar).Value = filename;
cmd.Parameters.Add("#T_Extension", SqlDbType.VarChar).Value = ext;
cmd.Parameters.Add("#T_Data", SqlDbType.VarBinary).Value = bytes;
strQueryCount = "select count(*) from [Text File] where T_Data.SequenceEqual ('" + bytes + ")'";
cmd.Parameters.Add("#Date", SqlDbType.DateTime).Value = DateTime.Now;
cmd.Parameters.Add("#Course_code", Course_code.SelectedItem.Text);
cmd.Parameters.Add("#Course_num", Course_num.SelectedItem.Text);
cmd.Parameters.Add("#T_Description", Description.Text);
cmd.Parameters.Add("#T_Keyword", keywords.Text);
InsertUpdateData(cmd, bytes, strQueryCount);
}
private Boolean InsertUpdateData(SqlCommand cmd, Byte[] bytes, string strQueryCount)
{
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(strConnString);
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
try
{
con.Open();
command = new SqlCommand(strQueryCount, con);
int num = Convert.ToInt16(command.ExecuteScalar());
Label2.Text = num.ToString();
if (num == 0)
{
cmd.ExecuteNonQuery();
return true;
}
else
{
Label2.ForeColor = System.Drawing.Color.Red;
Label2.Text = "error ";
Description.Text = " ";
keywords.Text = " ";
Course_code.SelectedItem.Text = " ";
Course_num.SelectedItem.Text = " ";
return false;
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
return false;
}
finally
{
con.Close();
con.Dispose();
}
}
Thanks..
You cannot compare files in byte stream as we do on other data types. You can generate some unique values for a file like hash or check-sum and store it along with byte stream in DB, which can be used to check for whether the file exists or not. Normally these mechanisms are not used for this. This only works if file contents are exactly the same. Even the slightest of variation will be failed to identify the match.
OR alternatively, you can decide to store some alternate information like we normally do. Like file name or user-based validations to check whether the file exists.
EDIT:
You can find hash like
string hash;
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
}
see it here
I agree, as suggested in above post, you can maintain hash to manage file comparing.
Since you asked how to compare using query, i am adding one more suggestion here.
Write a function in C# to get MD5 hash. Following is the code for function.
public static string GetMD5Hash(string input)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.UTF8.GetBytes(input);
bs = x.ComputeHash(bs);
System.Text.StringBuilder s = new System.Text.StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToLower());
}
return s.ToString();
}
So get MD5 hash of file, and then using HASHBYTES('MD5', VarbinaryColumn)), you can compare values . This will work,because you will have MD5 hash generated C# and used HASHBYTES in SQL server to compare.
You can also do other type hashing like SHA1 in SQL server as well as C# side.
More on hashbytes - http://codepieces.tumblr.com/post/31006268297/sql-server-hashbytes-function-and-net-hashing-md5
Again, this has same limitation, slight change in content implies mismatch between posted file and stored file in SQL .
I have an asp.net web forms site, I am looking to create a control that allows the user to browse for an image then save the image into the database. I know that saving images into a database is bad practice, but thats what I've been told to do!
Does anyone have any suggestions for the best approach to do this?
thanks
Essentially all you need is a FileUpload control and some code to save it to the database. (And you'll want to do some input checking as well, naturally.) There's a pretty old tutorial which explains the concept well here. This one is a little more recent. But there's no shortage of others.
from a sample:
var intDoccumentLength = FileUpload1.PostedFile.ContentLength;
var newDocument = new byte[intDoccumentLength];
var stream = FileUpload1.PostedFile.InputStream;
stream.Read(newDocument, 0, intDoccumentLength);
var sqlConnection = new SqlConnection(sqlConnectionString);
sqlConnection.Open();
var sqlQuery = "INSERT INTO dbo.DocumentData (DocName, DocBytes, DocData, DocCreatedAt) VALUES (#DocName, #DocBytes, #DocData, #DocCreatedAt);"
+ "SELECT CAST(SCOPE_IDENTITY() AS INT)";
sqlCommand = new SqlCommand(sqlQuery, sqlConnection);
sqlCommand.Parameters.Add("#DocName", SqlDbType.NVarChar, 255);
sqlCommand.Parameters.Add("#DocBytes", SqlDbType.Int);
sqlCommand.Parameters.Add("#DocData", SqlDbType.VarBinary);
sqlCommand.Parameters.Add("#DocCreatedAt", SqlDbType.DateTime);
sqlCommand.Parameters["#DocName"].Value = FileUpload1.PostedFile.FileName;
sqlCommand.Parameters["#DocBytes"].Value = intDoccumentLength;
sqlCommand.Parameters["#DocData"].Value = newDocument;
sqlCommand.Parameters["#DocCreatedAt"].Value = DateTime.Now;
var newDocumentId = (Int32) sqlCommand.ExecuteScalar();
sqlConnection.Close();
There is fileupload tool available in toolbox. You just have to writ the below code in the click event of button..
string filename = FileUpload1.FileName.ToString();
if (filename != "")
{
ImageName = FileUpload1.FileName.ToString();
ImagePath = Server.MapPath("Images");
SaveLocation = ImagePath + "\\" + ImageName;
SaveLocation1 = "~/Image/" + ImageName;
sl1 = "Images/" + ImageName;
FileUpload1.PostedFile.SaveAs(SaveLocation);
}
and I hope you have an image column in your database so then just insert the string sl1 in your insert query..