Hey guys I have a problem im uploading images to my project path the images are contained within ~/userdata/UserID/uploadedimage/image.jpg
I used the below method to upload and to store the path of the picture in my database.
protected void UploadButton_Click(object sender, EventArgs e)
{
if (FileUploadControl.HasFile)
{
try
{
string theUserId = Session["UserID"].ToString();
OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;");
cn.Open();
//string filename = Path.GetFileName(FileUploadControl.FileName);
string fileuploadpath = Server.MapPath("~/userdata/" + theUserId + "/uploadedimage/") + Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
StatusLabel.Text = "Upload status: File uploaded!";
OdbcCommand cmd = new OdbcCommand("INSERT INTO Pictures (UserID, picturepath) VALUES ('" + theUserId + "' , '" + fileuploadpath + "')", cn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
}
}
}
What I found is the path isnt the path of my project directory its something strange:
Here is a snippet from my database the first one idPictures = 1 is the correct path name I need.
idPictures = 2 is the one that the fileupload is inserting into my database?
How can I get it so it will give a path name like this:
~/userdata/2/uploadedimage/batman-for-facebook.jpg
Edit:
If I try this:
string fileuploadpath = ("~/userdata/"+theUserId+"/uploadedimage/")+Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
StatusLabel.Text = "Upload status: File uploaded!";
OdbcCommand cmd = new OdbcCommand("INSERT INTO Pictures (UserID, picturepath) VALUES ('"+theUserId+"','"+fileuploadpath+"')", cn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
}
}
}
I get the error:
The file could not be uploaded. The following error occured: The SaveAs method is configured to require a rooted path, and the path '~/userdata/1/uploadedimage/holypally.jpg' is not rooted.
I suspect it's treating backslashes as escape characters in your SQL statement. Don't forget, you're using Server.MpaPath - i.e. you're trying to find the Windows absolute filename for the file.
This is exactly the kind of thing that happens when you don't use parameterized SQL statements, but instead include what is essentially user-specified text into your SQL directly. Don't do that. Use a parameterized SQL command, specify the values separately and then you at least won't need to worry about wonky values.
Of course, you'll still need to work out whether you really wanted to store the translated path or not, but that's a different matter.
In order to answer my own question I had to create two strings one purely for fileupload and the other purely for database pathname storage:
string filenameDB = Path.GetFileName(FileUploadControl.FileName);
string fileuploadpath = Server.MapPath("~/userdata/"+theUserId+"/uploadedimage/")+Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
string fileuploadpaths = ("~/userdata/"+theUserId+"/uploadedimage/")+filenameDB;
StatusLabel.Text = "Upload status: File uploaded!";
OdbcCommand cmd = new OdbcCommand("INSERT INTO Pictures (UserID, picturepath) VALUES ('"+theUserId+"','"+fileuploadpaths+"')", cn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
}
}
}
Related
I'm new to C#, am still teaching myself it and am coming from Visual FoxPro programming. The problem I have is I want to insert a value from a textbox in a form that only contains computer directories. In that field I select C:\ and when I run the code I get the error: Incorrect syntax near 'C:'.
The field name that contains the directory value is lblVault and is a label object.
The code I run looks like this:
using (SqlConnection connect = new SqlConnection(#"Data Source=(LocalDB)\v11.0;" +
"AttachDbFilename=C:\\Development\\C-Sharp\\LockItUp\\Lockitup.mdf;Integrated Security=True"))
{
string stmt = "INSERT INTO Users(username,password,folderloc,fullname,email,cellphone) " +
"VALUES (" + #txtUsrName.Text + "," + #txtUserPassword.Text + "," + #lblVault.Text + "," +
#txtFullname.Text + "," + #txtEmail.Text + "," + #txtCellPhone.Text + ")";
using (SqlCommand cmd = new SqlCommand(stmt, connect))
{
try
{
connect.Open();
cmd.ExecuteNonQuery();
connect.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex);
return;
}
}
}
Thanks for the help!
Easiest and safest way (google "SQL injection") is use parameters even with SQL queries. Not just it would take care of formatting strings for you, but also save you from simplest security problems.
using (SqlConnection connect = new SqlConnection(#"Data Source=(LocalDB)\v11.0;" +
"AttachDbFilename=C:\\Development\\C-Sharp\\LockItUp\\Lockitup.mdf;Integrated Security=True"))
{
string stmt = "INSERT INTO Users(username,password,folderloc,fullname,email,cellphone) " +
"VALUES (#username,#password,#folderloc,#fullname,#email,#cellphone)";
using (SqlCommand cmd = new SqlCommand(stmt, connect))
{
cmd.Parameters.Add("#username",txtUsrName.Text);
cmd.Parameters.Add("#password", txtUserPassword.Text);
cmd.Parameters.Add("#folderloc",lblVault.Text);
cmd.Parameters.Add("#fullname", txtFullname.Text);
cmd.Parameters.Add("#email",txtEmail.Text)
cmd.Parameters.Add("#cellphone",txtCellPhone.Text);
try
{
connect.Open();
cmd.ExecuteNonQuery();
connect.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex);
return;
}
}
}
Similar to how your connection string has extra slashes in it, you need extra slashes in your concatenated string to let C# understand the difference between a slash char, and a slash meant to escape into a different char. (For example \n means new line.)
#lblVault.Text.Replace(#"\", #"\\")
or
#lblVault.Text.Replace("\\", "\\\\")
The # symbol means don't allow any escaping. Slash means slash and only slash.
Beginner's question - please can I ask for advice on creating local database files programmatically at run time. I want to be able later to rename, delete them etc using Windows Explorer in the same way as for text and other files, and to copy them to other computers.
This is using Visual Studio Community 15 with C#, installed SQL server Data Tools 14.0.50616.0. The computer has Microsoft SQL Server 2014.
For an example I have removed the surplus parts of my program to leave the code below, which uses a Windows Form Application with 3 buttons (btnCreateDb, btnDeleteDb, and btnDoesDbExist) and a combobox cbxDb for the database name. It makes databases in an existing folder C:\DbTemp.
It will apparently create and delete a new database and make files, for example mydb1.mdf and mydb1.ldf in the folder, and state that they exist. However, if I delete the two files using Explorer, it throws an exception if an attempt is made to delete or to create the database; and btnDoesDbExist shows that it still exists.
Why does the database still appear to exist when the files have been deleted by Windows Explorer? The code under btnDoesDatabaseExist doesn't refer to the path of the files, so it must be seeing something else, but where? Is this a correct method for the user of the program to create, delete, and detect these databases?
using System;
using System.Data;
using System.Windows.Forms;
//my additions
using System.Data.SqlClient;
namespace DataProg15
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static string form1ConnectionString = "Data Source = (LocalDB)\\MSSQLLocalDB; Integrated Security = True; Connect Timeout = 30; ";
private string form1DatabasePath = "C:\\DbTemp";
private void btnCreateDb_Click(object sender, EventArgs e)
{
string nameToCreate = cbxDb.Text;
SqlConnection myConn = new SqlConnection(form1ConnectionString);
string str = "CREATE DATABASE " +nameToCreate+ " ON PRIMARY " +
"(NAME = " +nameToCreate+ "_Data, " +
"FILENAME = '" +form1DatabasePath+ "\\" +nameToCreate+ ".mdf', " +
"SIZE = 4MB, MAXSIZE = 10MB, FILEGROWTH = 10%) " +
"LOG ON (NAME = " +nameToCreate+ "_Log, " +
"FILENAME = '" +form1DatabasePath+ "\\" +nameToCreate+ ".ldf', " +
"SIZE = 1MB, " +
"MAXSIZE = 5MB, " +
"FILEGROWTH = 10%)";
SqlCommand myCommand = new SqlCommand(str, myConn);
try
{
myConn.Open();
myCommand.ExecuteNonQuery();
MessageBox.Show("DataBase '" + nameToCreate + "' was created successfully");
}
catch (System.Exception ex)
{
MessageBox.Show("Exception in CreateDatabase " + ex.ToString(), "Exception in CreateDatabase", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
}
}
private void btnDeleteDb_Click(object sender, EventArgs e)
{
string nameToDelete = cbxDb.Text;
string myConnectionString = form1ConnectionString + "AttachDBFileName = " + form1DatabasePath + "\\" + nameToDelete + ".mdf ";
string str = "USE MASTER DROP DATABASE " + nameToDelete;
SqlConnection myConn = new SqlConnection(myConnectionString);
SqlCommand myCommand = new SqlCommand(str, myConn);
myConn.Open();
try
{
myCommand.ExecuteNonQuery();
MessageBox.Show("DataBase '" + nameToDelete + "' was deleted successfully");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString(), "Exception in DeleteDatabase '" +nameToDelete+ "'", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
}
}
private void btnDoesDbExist_Click(object sender, EventArgs e)
{
string nameToTest = cbxDb.Text;
using (var connection = new SqlConnection(form1ConnectionString))
{
using (var command = new SqlCommand(string.Format(
"SELECT db_id('" +nameToTest+ "')", nameToTest), connection))
{
connection.Open();
if ((command.ExecuteScalar() != DBNull.Value))
{
MessageBox.Show("DataBase '" +nameToTest+ "' exists");
}
else
{
MessageBox.Show("Database '" +nameToTest+ "' does not exist");
}
}
}
}
}
}
Thank you to all for replies, and your trouble is greatly appreciated.
I now understand that I'm using the wrong database so I've tried to use SQL Server Compact instead. Have uninstalled, downloaded again, and reinstalled SQL Server Compact including SP1. Have also downloaded and installed SQL Server Compact/SQLite Toolbox from https://visualstudiogallery.msdn.microsoft.com/0e313dfd-be80-4afb-b5e9-6e74d369f7a1 . But Visual Studio has throughout shown an error when I type using System.Data.SqlServerCe . Also when I type SqlCeEngine or SqlCecommand, I assume for the same reason.
In Visual Studio, SQL Server Data Tools and SQL Server Compact & SQLite Toolbox are shown as installed products, but not SQL Server Compact. Do I need to install this into Visual Studio, and if so how is it done?
In Solution Explorer under References, check that System.Data.SqlServerCe is listed. If not, right click on References then Add Reference -> Browse button and select the file System.Data.SqlServerCe.dll, probably in C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Desktop. System.Data.SqlServerCe should now appear under References.
The program below appears to work, and is much simpler. Thanks to all for assistance.
using System;
using System.Data;
using System.Windows.Forms;
//my additions
using System.Data.SqlServerCe;
using System.IO;
namespace DataProg15
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static string form1DatabasePath = "C:\\DbTemp\\dbtemp1.sdf";
public static string form1ConnectionString = "Data Source = " +form1DatabasePath;
private void btnCreateDb_Click(object sender, EventArgs e)
{
SqlCeEngine engine = new SqlCeEngine(form1ConnectionString);
try
{
engine.CreateDatabase();
MessageBox.Show("DataBase '" +form1DatabasePath+ "' was created successfully");
}
catch (System.Exception ex)
{
MessageBox.Show("Exception in CreateDatabase " + ex.ToString(), "Exception in CreateDatabase", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
engine.Dispose();
}
}
private void btnDeleteDb_Click(object sender, EventArgs e)
{
if (File.Exists(form1DatabasePath))
{
try
{
File.Delete(form1DatabasePath);
MessageBox.Show("DataBase '" +form1DatabasePath+ "' was deleted successfully");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString(), "Exception in DeleteDatabase '" +form1DatabasePath+ "'", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void btnDoesDbExist_Click(object sender, EventArgs e)
{
if (File.Exists(form1DatabasePath))
{
MessageBox.Show("DataBase '" +form1DatabasePath+ "' exists");
}
else
{
MessageBox.Show("DataBase '" +form1DatabasePath+ "' does not exist");
}
}
}
}
SQL Server will not let you delete the physical files of a database if that database is active - EVER. The only you would ever be able to do this is if the database is DETACHED ( as mentioned earlier )
So I suspect something your telling us isn't quite right ??
I would change your "check database exists" logic to be;
select * from sys.databases where name = 'yourdatabasename'
I would run this query anyway when you have deleted your database, just to see what it returns.
I have a file upload function that throws sql exception
System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near ','.
The identifier that starts with
'PGFzcDpHcmlkVmlldyBJRD0iR3JpZFZpZXcyIiANCiAgICAgICAgcnVuYXQ9InNlcnZlciI
gV2lkdGg9IjgyMHB4IiBBdXRvR2VuZXJhdGVTZWxlY3RCdXR0b249IlRy' is too long.
Maximum length is 128" whenever the file name contains a single quote character (')
File upload function below :
protected void btn_file_upload_Click(object sender, EventArgs e)
{
try
{
if (FileUpload1.HasFile)
{
byte[] byte_file = FileUpload1.FileBytes;
string str_file = Convert.ToBase64String(byte_file);
SqlCommand cmd = new SqlCommand("insert into spt_files values('" + FileUpload1.FileName + "','" + str_file + "','" + dd_students.Text + "')", conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
lbl_file_upload.Text = "File uploaded!";
}
else
lbl_file_upload.Text = "Choose a file";
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
How to resolve this?
You can use
protected void btn_file_upload_Click(object sender, EventArgs e)
{
try
{
if (FileUpload1.HasFile)
{
byte[] byte_file = FileUpload1.FileBytes;
string str_file = Convert.ToBase64String(byte_file);
SqlCommand cmd = new SqlCommand("insert into spt_files values('" + FileUpload1.FileName.Replace("'", "''") + "','" + str_file + "','" + dd_students.Text + "')", conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
lbl_file_upload.Text = "File uploaded!";
}
else
lbl_file_upload.Text = "Choose a file";
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
And increase the size of column in table .
I've spent a lot of time trying to research outside resources, but different solutions seem to be more involved than I was hoping.
I am trying to achieve the following:
create simple database on existing SQL instance on this local computer.
security should just be a simple user name and password
other options are unnecessary (log, growth, max size, etc)
This is my first attempt at database integration with my program. using SQLite or SMO seemed slightly overwhelming to start. I've been trying to modify this sample code to work:
private void createDatabase()
{
String str;
SqlConnection myConn = new SqlConnection("Server=" + serverName + ";Integrated security=SSPI;database=master");
str = "CREATE DATABASE " + dbName + " ON PRIMARY " +
"(NAME = " + dbName + "_Data, " +
"FILENAME = 'C:\\" + dbName + ".mdf', " +
"SIZE = 2MB, MAXSIZE = 10MB, FILEGROWTH = 10%) " +
"LOG ON (NAME = " + dbName + "_Log, " +
"FILENAME = 'C:\\" + dbName + ".ldf', " +
"SIZE = 1MB, " +
"MAXSIZE = 5MB, " +
"FILEGROWTH = 10%)";
SqlCommand myCommand = new SqlCommand(str, myConn);
try
{
myConn.Open();
myCommand.ExecuteNonQuery();
MessageBox.Show("DataBase is Created Successfully", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
}
}
Any ideas on how to create a simple query string or something to create a database? If there's a better way, that's fine but keep in mind I'm trying to keep it as simple as possible just to start with.
Using SMO:
Server server = new Server("servername");
Database db = new Database(server, "MyDatabaseName");
db.Create();
To build an SMO application, you need to reference the SMO assemblies. Click ‘Add Reference’ and navigate to the folder
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies
Add references to these assemblies:
Microsoft.SqlServer.ConnectionInfo.dll
Microsoft.SqlServer.Smo.dll
Microsoft.SqlServer.Management.Sdk.Sfc.dll
Microsoft.SqlServer.SqlEnum.dll
Add this using statement to the file containing the above code:
using Microsoft.SqlServer.Management.Smo;
On a Side Note:
Fixing Slow SQL Server Management Objects (SMO) Performance
Ok new problem this is my full code I will explain what I'm trying to do and segment each part so you can see what it is I'm trying to achieve:
Full Code:
protected void UploadButton_Click(object sender, EventArgs e)
{
if (FileUploadControl.HasFile)
{
try
{
string theUserId = Session["UserID"].ToString();
OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=x; Password=x;");
cn.Open();
OdbcCommand sc = new OdbcCommand(string.Format("SELECT picturepath FROM Pictures WHERE UserID ='{0}'", theUserId), cn);
OdbcDataReader reader = sc.ExecuteReader();
while (reader.Read())
{
if (System.IO.File.Exists(Convert.ToString(reader[0])))
{
System.IO.File.Delete(Convert.ToString(reader[0]));
}
}
string filenameDB = Path.GetFileName(FileUploadControl.FileName);
string fileuploadpath = Server.MapPath("~/userdata/" + theUserId +
"/uploadedimage/") +
Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
string fileuploadpaths = ("~/userdata/" + theUserId + "/uploadedimage/") +
filenameDB;
StatusLabel.Text = "Upload status: File uploaded!";
OdbcCommand cmd = new OdbcCommand("INSERT INTO Pictures (UserID, picturepath) VALUES ('" + theUserId + "','" + fileuploadpaths + "')", cn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
}
}
}
Ok the first part I'm trying to do is select the picture path related to the userid then if a userid is there with the same userid as im trying to upload delete the file that exists(not stored in database hence the IO) this part doesn't work the file pathname of the current userid isn't being deleted.
OdbcCommand sc = new OdbcCommand(string.Format("SELECT picturepath FROM Pictures WHERE UserID ='{0}'", theUserId), cn);
OdbcDataReader reader = sc.ExecuteReader();
while (reader.Read())
{
if (System.IO.File.Exists(Convert.ToString(reader[0])))
{
System.IO.File.Delete(Convert.ToString(reader[0]));
}
}
The second part just inserts the new file upload path and name into my database related to the current userid (this works) the file is uploaded to the correct folder and its inserted into my database. I could change this to UPDATE rather than insert but atm its either or not to fussy.
string filenameDB = Path.GetFileName(FileUploadControl.FileName);
string fileuploadpath = Server.MapPath("~/userdata/" + theUserId +
"/uploadedimage/") +
Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
string fileuploadpaths = ("~/userdata/" + theUserId + "/uploadedimage/") +
filenameDB;
StatusLabel.Text = "Upload status: File uploaded!";
OdbcCommand cmd = new OdbcCommand("INSERT INTO Pictures (UserID, picturepath) VALUES ('" + theUserId + "','" + fileuploadpaths + "')", cn);
cmd.ExecuteNonQuery();
So my problem is why is my if statement not deleting the currently held record in my database for the path of the current image? All that happens is my new image is uploaded into the same folder but the old image still remains?
Remember though I'm not trying to delete the "same" file name a simple saveas would overwrite it which is already in my code, what I need is for my code to delete any image that is currently in the userid specific folder when I'm trying to save the new image upload.
Any thoughts some help on the code?
Thanks guys
Looking at your code, I believe SystemDown has the answer in the comments:
When you save the file to disk you use the following code:
// Even though you've just calculated the result of Path.GetFileName you
// redo it here?
string fileuploadpath = Server.MapPath("~/userdata/" + theUserId
+ "/uploadedimage/")
+ Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
Then you store it in the DB as:
string filenameDB = Path.GetFileName(FileUploadControl.FileName);
string fileuploadpaths = ("~/userdata/" + theUserId + "/uploadedimage/") +
filenameDB;
However when you delete the file you're not performing Server.MapPath:
System.IO.File.Delete(Convert.ToString(reader[0]));
Change that line to:
System.IO.File.Delete(Server.MapPath(Convert.ToString(reader[0])));
And it should all work.
you should use the server.mappath to find that if image is already exist or not then try to delete that im