set default image path - c#

how do i set a default image when the image file was not found or not exist ?
the error i got was
because file with name 8813.jgp was not exist. and i want to set it default as 1.jpg. how do i check if its exist or not.
iam using this code
public void profilepicture()
{
DataTable dtprofile = new DataTable();
DataSet dsprofile = new DataSet();
string path;
SqlCommand command = new SqlCommand();
SqlDataAdapter adapter = new SqlDataAdapter();
try
{
dsprofile.Clear();
dtprofile.Clear();
command.Connection = myConnection;
command.CommandText = "//some query//'";
myConnection.Open();
adapter.SelectCommand = command;
adapter.Fill(dtprofile);
adapter.Fill(dsprofile);
}
catch (Exception ex)
{
MessageBox.Show("error" + ex);
myConnection.Close();
}
path = dsprofile.Tables[0].Rows[0][0].ToString() + "\\" + number + ".jpg";
pictureEdit2.Image = Image.FromFile(path);
myConnection.Close();
}

You can check to see if the file exists using File.Exists() in the System.IO namespace.
https://msdn.microsoft.com/en-us/library/system.io.file.exists(v=vs.110).aspx
if(File.Exists("filePath"))
{
// Load file.
}
else
{
// Load default file.
}

Its quite trivial actually!
path = dsprofile.Tables[0].Rows[0][0].ToString() + "\\" + number + ".jpg";
if(File.Exists(path)){
pictureEdit2.Image = Image.FromFile(path);
}
else
{
pictureEdit2.Image = Image.FromFile("NotFound.jpg");
}

I suggest you to create a separate method to get the SQL Table, so you can use it in every method you need and then you create a different method for the profile picture using the code as below:
public DataTable GetSqlTable(string query)
{
using (SqlConnection dbConnection = new SqlConnection(#"Data Source={ServerName};Initial Catalog={DB_Name};UID={UserID}; Password={PWD}"))
{
dbConnection.Open();
SqlDataAdapter da = new SqlDataAdapter(query, dbConnection);
da.SelectCommand.CommandTimeout = 600000; //optional
try
{
DataTable dt = new DataTable();
da.Fill(dt);
da.Update(dt);
dbConnection.Close();
return dt;
}
catch
{
dbConnection.Close();
return null;
}
}
}
public void profilepicture()
{
DataTable dt = GetSqlTable("/* some query */");
string number = "some value";
string defaultImg = "defaultImgPath";
if(dt.Rows.Count > 0)
{
string path = dt.Rows[0][0].ToString() + "\\" + number + ".jpg";
pictureEdit2.Image = Image.FromFile(File.Exists(path) ? path : defaultImg);
}
else
{
pictureEdit2.Image = Image.FromFile(defaultImg);
}
}
Sorry for my English

Standalone applications
If your application is a standalone application (requires only exe and no other files in hard disk), you can add the default image in a resource file and use it as required. Following stack overflow link explains how to access images added into a resource file Load image from resources area of project in C#
pictureEdit2.Image = File.Exists(path) ? Image.FromFile(path) : Resources.myImage;
Installed applications
If your application is not a standalone application, you can use Environment.GetFolderPath method or Application.StartupPath to store the default image.
To avoid file not found exception, you may need to use File.Exists in your code something like below
string defaultImagePath = Application.StartupPath + "\\1.jpg";
pictureEdit2.Image = Image.FromFile( File.Exists(path) ? path : defaultImagePath) ;

Related

Program won't load to selected database, makes a copy in debug folder

This program is supposed to take a csv file and load it to a sqlite database that the use specifies a path to. Rather than trying to load the values to the selected database it creates a copy of the database in the debug folder and then throws an error because the table doesn't exist in the new db. I can't find where it's deciding to make a new file rather than using the existing one.
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=" + db3FilePath + "; Synchronous=Off"))
{
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn))
{
conn.Open();
foreach (KeyValuePair<string, CSVRecord> kvp in csvDictionary.Skip(1))
{
//checks for duplicate records
cmd.CommandText = "SELECT COUNT(*) FROM Accounts WHERE SDM_ACCT='" + kvp.Value.sdmacct + "'";
int count = Convert.ToInt32(cmd.ExecuteScalar());
if (count < 1)
{
WritetoDatabase.WritetoAccountsTable(kvp.Value.description, kvp.Value.priority, db3FilePath);
WritetoDatabase.WritetoDirectoryTable(kvp.Value.number, kvp.Value.active, db3FilePath);
recordCount++;
//updates the progress bar and text field showing %
int progress = y++ * 100 / (csvDictionary.Keys.Count -1);
progressBar1.Invoke((MethodInvoker)(() => progressBar1.Value = progress));
progressBar1.Invoke((MethodInvoker)(() => progressBar1.Update()));
lblStatus.Invoke((MethodInvoker)(() => lblStatus.Text = "Writing records to database: " + progress.ToString() + "% Complete"));
lblStatus.Invoke((MethodInvoker)(() => lblStatus.Update()));
}
else
{
WritetoDatabase.WritetoDirectoryTable(kvp.Value.number, kvp.Value.active, db3FilePath);
y++;
}
}
conn.Close();
}
}
Here is a copy of the method that writes to the database.
public static int WritetoAccountsTable(string Comment, int PriorityInt, string filePath)
{
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=" + filePath + "; Synchronous=Off"))
{
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn))
{
conn.Open();
cmd.CommandText = #"INSERT INTO Accounts(Description,Priority)
values(#Comment,#PriorityInt)";
cmd.Parameters.AddWithValue("#Comment", Comment);
cmd.Parameters.AddWithValue("#PriorityInt", PriorityInt);
return cmd.ExecuteNonQuery();
}
}
}
I've changed everything I can think of trying to find what's causing the problem. Maybe you will see something I can't.
One of the all-time dumbest things I have seen break a program. The Connection String using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=" + filePath + "; Synchronous=Off")) has "data source". If it is not capitalized, "Data Source", it doesn't recognize it and goes to a default setting.

Can only read Excel file when it is actually open in Ms Excel

I am using the following code to open an excel file (XLS) and populate a DataTable with the first worksheet:
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", filename);
OleDbConnection connExcel = new OleDbConnection(connectionString);
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
connExcel.Close();
var adapter = new OleDbDataAdapter("SELECT * FROM [" + SheetName + "]", connectionString);
var ds = new DataSet();
int count = 0;
adapter.Fill(ds, SheetName);
DataTable dt = ds.Tables[0];
It works only when the file is already open in Ms Excel. Why could that be?
If the file is not open, I get an error message (on line connExcel.Open): External table is not in the expected format.
I'm facing the same problem and accordingly to this site, many developers are struggling for the same:
-When I try read Excel with OLE DB all values are empty
-Can't connect to excel file unless file is already open
Actually I'm using the classic connection string (note that I'm trying to read a 97/2003 file):
Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " + GetFilename(filename) + "; Extended Properties ='Excel 8.0;HDR=NO;IMEX=1'
but the file can be read properly only if:
Is open in Excel or even in Word! (the file of course appears corrupted and unreadable, but then the OleDb procedure can read every line of the file), I didn't try with other Office apps
The file is not in read-only mode
I also tried to lock the file manually or to open it with other non-office applications, but the result is not the same. If I follow the two previous rules (file opened in Word or Excel in not read-only mode) I can see all the cells, otherwise it seems the first column is ignored completely (so F2 became F1, F3 became F2,... and F6, the last one, should became F5 otherwise it throws and out-of-index error).
In order to keep compatibility with OleDb without using 3rd parties libraries I found a very stupid workaround using Microsoft.Office.Interop.Excel assembly.
Excel.Application _app = new Excel.Application();
var workbooks = _app.Workbooks;
workbooks.Open(_filename);
// OleDb Connection
using (OleDbConnection conn = new OleDbConnection(connectionOleDb))
{
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = String.Format("SELECT * FROM [{0}$]", tableName);
OleDbDataReader myReader = cmd.ExecuteReader();
int i = 0;
while (myReader.Read())
{
//Here I read through all Excel rows
}
}
catch (Exception E)
{
MessageBox.Show("Error!\n" + E.Message);
}
finally
{
conn.Close();
workbooks.Close();
if (workbooks != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks);
_app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(_app);
}
}
Essentially the first 3 lines run an Excel instance that lasts exactly the time needed to OleDb to perform its tasks.
The last 4 lines, inside the finally block, let the Excel instance to be closed correctly, immediately after the task and avoid ghost Excel processes.
I repeat it's a very stupid workaround that also requires a 1,5 MB dll (Microsoft.Office.Interop.Excel.dll) to be added to the project.
Anyway seems impossible that OleDb cannot manage by itself the missing data...
I had the same problem. If the file was open the read was ok but if the file was closed... some thing was strange... in my case I received strange data from columns and values.. Debugging I found the name of the first sheet and was strange ["xls _xlnm#_FilterDatabase"] looking on the internet I found that's a name of hidden sheet and a trick to avoid read this sheet (HERE) and so I've implemented a method:
private string getFirstVisibileSheet(DataTable dtSheet, int index = 0)
{
string sheetName = String.Empty;
if (dtSheet.Rows.Count >= (index + 1))
{
sheetName = dtSheet.Rows[index]["TABLE_NAME"].ToString();
if (sheetName.Contains("FilterDatabase"))
{
return getFirstVisibileSheet(dtSheet, ++index);
}
}
return sheetName;
}
To me worked very well.
My complete example code is:
string excelFilePath = String.Empty;
string stringConnection = String.Empty;
using (OpenFileDialog openExcelDialog = new OpenFileDialog())
{
openExcelDialog.Filter = "Excel 2007 (*.xlsx)|*.xlsx|Excel 2003 (*.xls)|*.xls";
openExcelDialog.FilterIndex = 1;
openExcelDialog.RestoreDirectory = true;
DialogResult windowsResult = openExcelDialog.ShowDialog();
if (windowsResult != System.Windows.Forms.DialogResult.OK)
{
return;
}
excelFilePath = openExcelDialog.FileName;
using (DataTable dt = new DataTable())
{
try
{
if (!excelFilePath.Equals(String.Empty))
{
stringConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelFilePath + ";Extended Properties='Excel 8.0; HDR=YES;';";
using (OleDbConnection conn = new OleDbConnection(stringConnection))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
DataTable dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetName = getFirstVisibileSheet(dtSheet);
cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
dt.TableName = sheetName;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dt);
cmd = null;
conn.Close();
}
}
//Read and Use my DT
foreach (DataRow row in dt.Rows)
{
//On my case I need data on first and second Columns
if ((row.ItemArray.Count() < 2) ||
(row[0] == null || String.IsNullOrWhiteSpace(row[0].ToString()))
||
(row[1] == null ||String.IsNullOrWhiteSpace(row[1].ToString())))
{
continue;
}
//Get the number from the first COL
int colOneNumber = 0;
Int32.TryParse(row[0].ToString(), out colOneNumber);
//Get the string from the second COL
string colTwoString = row[1].ToString();
//Get the string from third COL if is a file path valid
string colThree = (row.ItemArray.Count() >= 3
&& !row.IsNull(2)
&& !String.IsNullOrWhiteSpace(row[2].ToString())
&& File.Exists(row[2].ToString())
) ? row[2].ToString() : String.Empty;
}
}
catch (Exception ex)
{
MessageBox.Show("Import error.\n" + ex.Message, "::ERROR::", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private string getFirstVisibileSheet(DataTable dtSheet, int index = 0)
{
string sheetName = String.Empty;
if (dtSheet.Rows.Count >= (index + 1))
{
sheetName = dtSheet.Rows[index]["TABLE_NAME"].ToString();
if (sheetName.Contains("FilterDatabase"))
{
return getFirstVisibileSheet(dtSheet, ++index);
}
}
return sheetName;
}
Is it failing on ToString(), like here?
Error is "Object reference not set to an instance of an object"
Does Convert.ToString() fix anything?

How to read data from database & write it on a txt file?

I want to retrieve data from the server database using windows services on a text file?Can i do that?How will i do that?I mean i know to create a window service but i am confused with the SQL connection and file writing part where to execute it?i have tried something
class Program
{
static void Main(string[] args)
{
RunSchedule();
}
public static void RunSchedule()
{
string path = Path.GetFullPath("d:\\MyTest") + "\\" + DateTime.Now.ToString("MM_dd_yyyy_HH_mm") + "_Log.txt";
try
{
if (!File.Exists(path))
{
File.Create(path);
SqlConnection conn = new SqlConnection("Data Source=...;Initial Catalog=Test;User ID=s_a;Password=sa56ta112;");
String sql = #"SELECT Id,UserName, Email,Password,CreatedDate
FROM Register";
SqlCommand com = new SqlCommand();
com.CommandText = sql;
//com.Connection = conn;
conn.Open();
StreamWriter tw = File.AppendText("d:\\MyTest");
SqlDataReader reader = com.ExecuteReader();
tw.WriteLine("Id,UserName,Email,Password,CreatedDate");
while (reader.Read())
{
tw.Write(reader["Id"].ToString());
tw.Write(" , " + reader["UserName"].ToString());
tw.Write(" , " + reader["Email"].ToString());
tw.Write(" , " + reader["Password"].ToString());
tw.Write(" , " + reader["CreatedDate"].ToString());
}
tw.WriteLine(DateTime.Now);
tw.WriteLine("---------------------------------");
tw.Close();
reader.Close();
conn.Close();
}
}
catch (Exception ex)
{
string errorLogPath = #"D:\MyTest.txt";
File.AppendAllText(errorLogPath, Environment.NewLine + ex.Message);
}
}
}
am i doing it correct? Please guide me.
while (reader.Read())
{
row = new DataRow();
row.ItemArray = new object[reader.FieldCount];
reader.GetValues(row.ItemArray);
foreach (object item in row.ItemArray)
{
streamWriter.Write((string)item + "\t");
}
streamWriter.WriteLine();
}
If you get "Access to the path 'd:\MyTest' is denied." error than go to the txt file properties in the solution explorer and than change the Copy to output directory property from Do not copy into Copy if newer or Copy always

Want to see the ouput "data.csv" in the desktop or any location

public void CreateFileOutput(object parameter)
{
string workSheetName, targetFile;
workSheetName = "data"; targetFile = "data.csv";
string strConn = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + SourceAppFilePath + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1;';";
OleDbConnection conn = null;
StreamWriter wrtr = null;
OleDbCommand cmd = null;
OleDbDataAdapter da = null;
try
{
conn = new OleDbConnection(strConn);
conn.Open();
cmd = new OleDbCommand("SELECT * FROM [" + workSheetName + "$]", conn);
cmd.CommandType = CommandType.Text;
wrtr = new StreamWriter(targetFile);
da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
for (int x = 0; x < dt.Rows.Count; x++)
{
string rowString = "";
for (int y = 0; y < dt.Columns.Count; y++)
{
rowString += "\"" + dt.Rows[x][y].ToString() + "\",";
}
wrtr.WriteLine(rowString);
}
Console.WriteLine();
Console.WriteLine("Done! Your " + SourceAppFilePath + " has been converted into " + targetFile + ".");
Console.WriteLine();
}
catch (Exception exc)
{
Console.WriteLine(exc.ToString());
Console.ReadLine();
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
conn.Dispose();
cmd.Dispose();
da.Dispose();
wrtr.Close();
wrtr.Dispose();
}
}
XLS file is being converted to csv.I am able to see that in the for loop wrtr.WriteLine(rowString);
But I want to see the final output file "Data.csv" in the desktop location as I am taking the source .xls file from the desktop. Provide me a solution. Thanks.
You need to use the full path to save the file to the desktop. You can get the path using the Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory, like this:
string targetFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string targetPath = Path.Combine(targetFolder, "Data.csv");
Then use FileStream with the full path:
fs = new FileStream(targetPath, FileMode.Create);
Edited Per Comments Below
The key to this is specifying the path to where you want to save the file. Just giving a file name will put it in the directory the application is excuting from. An easy way to do this would be to use the GetDirectoryName method of the Path class. Assuming the file was passed in, read from a config file, hard coded, etc:
string path = Path.GetDirectoryName(sourceFile);
string target = path + #"\" + "Data.csv";
If the sourceFile was C:\Data\Input.xml, then path would equal "C:\Data", and target would be C:\Data\Data.csv.
The advantage here is that you can pass a filename with the path, and it will always place the targetfile in the same location. This lends itself nicely to parameterization of the method, or maybe even having the user select the file through an OpenFileDialog box or similar mechanism.
Additional Edit Per John's Comment
Based on the code you posted, the Data.xsl file is in the executing application's folder. In that case, you'd simply need to do the following:
fs = new FileStream("data.csv", FileMode.Create);
No need to mess with paths, as the filestream will also go to the executing application's directory.
In the end, it's all about using the information available from the sourcefile (i.e., it's location/path data) and applying it to the target file's full path and name.

How to take Excel file uploaded from website and import data to SQL Server programmatically?

I'm trying to do something like this:
public void ImportClick(object sender, EventArgs e) //the button used after selecting the spreadsheet file
{
if (fileUpload.HasFile) //ASP.Net FileUpload control
{
if (fileUpload.FileName.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || fileUpload.FileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{
Excel sheet = new Excel(fileUpload.Open()); //not sure how to do this part
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["our_database"].ConnectionString))
{
using (SqlCommand command = new SqlCommand("INSERT INTO table_name SELECT * FROM " + sheet, connection))
{
connection.Open();
command.ExecuteQuery(); //Intellisense only has "ExecuteNonQuery()" method, but that's for T-SQL
connection.Close();
}
}
}
else
{
error.Text = "File must be either *.xls or *.xlsx";
error.Visible = true;
}
}
else
{
error.Text = "No file was selected";
error.Visible = true;
}
}
There are a lot of classes and interfaces in the Microsoft.Office.Interop.Excel namespace, and I don't know which one to use.
I know making the Excel object, along with the SQL command, probably won't be as easy as what I have here, but those are the two things I need help with.
Any suggestions/advice would be greatly appreciated!
I would suggest using Microsoft Jet Engine.
private static void UploadExcelToDB(string p)
{
try
{
using (SqlConnection conn = new SqlConnection(DBConnString))
{
conn.Open();
if (conn.State == ConnectionState.Open)
{
Log("Opened connection to DB");
}
SqlBulkCopy sbk = new SqlBulkCopy(conn);
sbk.BulkCopyTimeout = 600;
sbk.DestinationTableName = DbTableName;
DataTable excelDT = new DataTable();
OleDbConnection excelConn = new OleDbConnection(ExcelConnString.Replace("xFILEx",p));
excelConn.Open();
if (excelConn.State == ConnectionState.Open)
{
Log("Opened connection to Excel");
}
OleDbCommand cmdExcel = new OleDbCommand();
OleDbDataAdapter oda = new OleDbDataAdapter();
cmdExcel.CommandText = "SELECT * FROM ["+ExcelTableName+"]";
cmdExcel.Connection = excelConn;
oda.SelectCommand = cmdExcel;
oda.Fill(excelDT);
if (excelDT != null)
{
Log("Fetched records to local Data Table");
}
excelConn.Close();
SqlCommand sqlCmd = new SqlCommand("TRUNCATE TABLE ICN_NUGGET_REPORT_RAW",conn);
sqlCmd.CommandType = CommandType.Text;
Log("Trying to clear current data in table");
int i = sqlCmd.ExecuteNonQuery();
Log("Table flushed");
Log("Trying write new data to server");
sbk.WriteToServer(excelDT);
Log("Written to server");
conn.Close();
}
}
catch (Exception ex)
{
Log("ERROR: " + ex.Message);
SendErrorReportMail();
}
finally
{
#if (DEBUG)
{
}
#else
{
string archive_file = ArchiveDir+"\\" + DateTime.Now.ToString("yyyyMMdd-Hmmss") + ".xlsx";
File.Move(p, archive_file);
Log("Moved processed file to archive dir");
Log("Starting archive process...");
}
#endif
}
}
This is how ExcelConnString looks like:
public static string ExcelConnString { get { return "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=xFILEx;Extended Properties=\"Excel 12.0;HDR=YES\";";} }
HDR=YES - this means that if you have column names in spreadsheet it will be treated as target table column names for matching each other.
I am thinking of creating an instance of excel.application class and writing codes to loop through the cells. And using SQL insert query to copy the rows one by one to the SQL table. I'm still working it out anyway and would paste the code when i'm done.

Categories

Resources