I have the following code, just to test connection:
public void Test()
{
SqlCeConnection conn = new SqlCeConnection(#"Data Source=/Application/Database.sdf;");
try
{
conn.Open();
label1.text = "Connection!";
}
catch (Exception ee)
{
label1.text = "No connection!";
}
}
When trying to connect to this database, the application throws an exception at conn.Open() saying
SqlCeException was unhandled
and nothing more. The exception message is blank, so I'm having a hard time figuring out what went wrong.
The database file is there, and the application returns true with
File.Exist(#"/Application/Database.sdf");
so it does have access to the file.
I'm probably doing something really wrong here, can anyone help me out with this?
I'm using Compact Framework 2.0 on Windows CE 5, and the application in question is an existing one. I'm trying to add a database to it so I can load large amounts of data much more easier.
What Erik is saying is change your code to this:
public void Test()
{
SqlCeConnection conn = new SqlCeConnection(#"Data Source=/Application/Database.sdf;");
try
{
conn.Open();
label1.text = "Connection!";
}
catch (SqlCeException ee) // <- Notice the use of SqlCeException to read your errors
{
SqlCeErrorCollection errorCollection = ee.Errors;
StringBuilder bld = new StringBuilder();
Exception inner = ee.InnerException;
if (null != inner)
{
MessageBox.Show("Inner Exception: " + inner.ToString());
}
// Enumerate the errors to a message box.
foreach (SqlCeError err in errorCollection)
{
bld.Append("\n Error Code: " + err.HResult.ToString("X"));
bld.Append("\n Message : " + err.Message);
bld.Append("\n Minor Err.: " + err.NativeError);
bld.Append("\n Source : " + err.Source);
// Enumerate each numeric parameter for the error.
foreach (int numPar in err.NumericErrorParameters)
{
if (0 != numPar) bld.Append("\n Num. Par. : " + numPar);
}
// Enumerate each string parameter for the error.
foreach (string errPar in err.ErrorParameters)
{
if (String.Empty != errPar) bld.Append("\n Err. Par. : " + errPar);
}
}
label1.text = bld.ToString();
bld.Remove(0, bld.Length);
}
}
The generic Exception you are catching right now can not give you the details of the SqlCeException.
Related
sorry if its noob question but I am System Administrator, not developer, but willing to learn more :)
I am writing small console application in C# to verify backup files with MD5 hash. I Actually wrote and it works fine, except it counts error files as good because application works after try-catch even if exception is catch. I will paste part of the code with try catch finally block, my question is can I by any chance in "finally" say "if exception is thrown log filename and exception and go to beginning (start calculating next file) else if stream !=null ....continue Computing hash?
Thank you very much
Ervin
Here is my code in try-catch-finally block
try
{
myHash = null;
myFileMd5 = null;
stream = new FileStream(myFilename, FileMode.Open);
}
catch (FileNotFoundException)
{
File.AppendAllTextAsync(hashList, "The file " + myFilename + " or directory cannot be found." + "\n");
badcounter++;
}
catch (DirectoryNotFoundException)
{
File.AppendAllTextAsync(hashList,"The file " + myFilename + "or directory cannot be found." + "\n");
badcounter++;
}
catch (DriveNotFoundException)
{
File.AppendAllTextAsync(hashList, "The drive specified in 'path' is invalid." + "\n");
badcounter++;
}
catch (PathTooLongException)
{
File.AppendAllTextAsync(hashList, "'path' exceeds the maximum supported path length." + "\n");
badcounter++;
}
catch (UnauthorizedAccessException)
{
File.AppendAllTextAsync(hashList, "You do not have permission to access this file: " + myFilename + "\n");
badcounter++;
}
catch (IOException e) when ((e.HResult & 0x0000FFFF) == 32)
{
File.AppendAllTextAsync(hashList, myFilename + " " + "Sharing violation." + "\n");
badcounter++;
}
catch (IOException e) when ((e.HResult & 0x0000FFFF) == 80)
{
File.AppendAllTextAsync(hashList, myFilename + " " + "The file already exists." + "\n");
badcounter++;
}
catch (IOException e)
{
File.AppendAllTextAsync(hashList, $"An exception occurred:\nError code: " + $"{e.HResult & 0x0000FFFF}\nMessage: {e.Message}" + myFilename + "\n");
badcounter++;
}
finally
{
if (stream != null)
{
myFileMd5 = md5.ComputeHash(stream);
stream.Close();
}
}
return (myFileMd5);
}
Usually it is not a good practice to use the finally block to continue your processing logic. The finally block is executed in any case even if there is an exception catched or not. So your logic inside the finally block needs to be protected by the stream open failure and, not probable, but what if the same ComputeHash throws an exception?
So, I would move the logic inside the try block. If there is an exception the ComputeHash is not executed anyway and with the using statement you don't need to close the stream.
// This class will be used to comunicate back to the caller the result of the hash
// Try to avoid using too many global variables if possible. They make your code very
// unmaintenable.
public class ComputeStatus
{
public string errorText {get;set;} = "";
public byte[] hash {get;set;}
}
public ComputeStatus MyComputeHash(string filename)
{
ComputeStatus status = new ComputeStatus();
try
{
using var stream = new FileStream(myFilename, FileMode.Open);
status.hash = md5.ComputeHash(stream);
return status;
}
catch (FileNotFoundException)
{
string error = $"The file {myFilename} or directory cannot be found.";
// This can now be moved outside the method as well and done just one
// time by the caller in case of error text.
// File.AppendAllTextAsync(hashList, error);
status.errorText = error;
}
..... all the other catch blocks follow
return status;
}
Now the calling code just need to check if the ComputeStatus instance returned contains an error message or not. Let the error counting be handled at that level.
Something like this should work:
private void button1_Click(object sender, EventArgs e)
{
List<string> files = new List<string>();
files.Add(#"C:\file1.txt");
files.Add(#"C:\file2.txt");
files.Add(#"C:\file3.txt");
foreach(string myFilename in files)
{
//... your existing code...
}
}
I am developing a WebService in C # however I am facing an error.
This is the error :
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message or signature supplied for verification has been altered
So I sometimes get this error when I open my MySQL connection in my WebService.
I had this error by launching my webService twice at the same time then I tried again and no more errors.
My web service is on a Windows server 2012 R2 and i'm using .NET Framework 4.7.2 (It is called by the website php).
I did quite a bit of internet research and came across this in C# :
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
But it doesn't work, Do you have any idea so that I do not face this problem again ?
There is my MySQL open connection method :
public MySqlConnection OpenConnectionDB(string clientId)
{
listVerifs = new List<string>();
int iConn = 0;
try
{
MySqlConnection sqlCo = new MySqlConnection("server=MyServer;database=" + this.db + ";username=MyUID;password=MyPwd;AllowLoadLocalInfile=true");
if (sqlCo.State != ConnectionState.Open)
{
sqlCo.Open();
}
listVerifs.Add("CO SQL");
dataSourceDBF = #"//ntserver/Winbooks_Data/winbooks/data/" + clientId + "/";
dbfCo = new AdsConnection(#"data Source=//ntserver/Winbooks_Data/winbooks/data/" + clientId + "/" + clientId + ".add;User ID=mYUID;Password=;ServerType=local;ReadOnly=true;pooling=true;TrimTrailingSpaces=true;TableType=CDX;LockMode=COMPATIBLE");
if (dbfCo.State == ConnectionState.Closed)
{
dbfCo.Open();
}
listVerifs.Add("CO DBF");
Console.WriteLine("Databases connections open succesfull");
return sqlCo;
}
catch (Exception e)
{
dbfCo = null;
Console.WriteLine("Error connection " + e.Message);
test = e.Message;
log.AddLog("Erreur Fonction OpenConnectionDB : " + e.ToString(), 3, "WebServiceMySQL");
return null;
}
Thank's in advance !
I will be amazed if I find a solution for this, since it is very specific and vague, but I figured I would try. I'll try to give as much information as humanly possible, since I've been searching for answers for some time now.
I am building a utility in C# which copies records from a file in a library on the i-series/AS400 and builds an encrypted text file with each record from the AS400 as a comma separated string. In the file, it will have values like filename, fieldvalue1, fieldvalue2, fieldvalue3. I then take that text file to another PC, and run a C# utility which copies that record into the same file name in a library over there on a different i-series machine. Unfortunately, I receive the outside bounds of the array exception in some cases, but I cannot determine why. In the record just prior to the exception, the record looks pretty much the same and it works fine. My code is below in a nutshell. I usually don't give up, but I don't expect to ever figure this out. If someone does, I'll probably sing karaoke tonight.
// Select records from AS400 file and write them to text file
Recordset rs = new Recordset();
sqlQuery = "SELECT * FROM " + dataLibrary + "." + fileName;
try
{
rs.Open(sqlQuery, con);
while (!rs.EOF)
{
int[] fieldLengths;
fieldLengths = new int[rs.Fields.Count];
String[] fieldValues;
fieldValues = new String[rs.Fields.Count];
String fullString = "";
for (i = 0; i < rs.Fields.Count; i++)
{
fieldLengths[i] += rs.Fields[i].DefinedSize;
fieldValues[i] += rs.Fields[i].Value;
}
fullString = fileName + "," + String.Join(",", fieldValues);
fullString = Functions.EncryptString(fullString);
File.AppendAllText(savefile.FileName, fullString + Environment.NewLine);
rs.MoveNext();
}
}
catch (Exception ex)
{
}
cmd.Dispose();
// This gives me a text file of filename, fieldvalue1, fieldvalue2, etc...
// Next, I take the file to another system and run this process:
while ((myString = inputFile.ReadLine()) != null)
{
int stringLength = myString.Length;
String[] valuesArray = myString.Split(',');
for (i = 0; i < valuesArray.Length; i++)
{
if (i == 0)
{
fileName = valuesArray[0];
// Create file if it doesn't exist already
createPhysicalFile(newLibrary, fileName);
SQLStatement = "INSERT INTO " + newLibrary + "." + fileName + "VALUES(";
}
else
{
if (i == valuesArray.Length - 1)
{
SQLStatement += "#VAL" + i + ")";
}
else
{
SQLStatement += "#VAL" + i + ", ";
}
}
}
try
{
using (connection)
{
try
{
connection.Open();
}
catch (Exception ex)
{
}
// Create a new SQL command
iDB2Command command = new iDB2Command(SQLStatement, connection);
for (i = 1; i < valuesArray.Length; i++)
{
try
{
command.Parameters.AddWithValue("#VAL" + i, (valuesArray[i]));
}
catch (Exception ex)
{
}
}
// Just split the array into a string to visually check
// differences in the records
String arraySplit = ConvertStringArrayToString(valuesArray);
// The query gets executed here. The command looks something
// like:
// INSERT INTO LIBNAME.FILENAME VALUES(#VAL!, #VAL2, #VAL3, #VAL4)
// There are actually 320 fields in the file I'm having a problem with,
// so it's possible I'm overlooking something. I have narrowed it down to
// field # 316 when the exception occurs, but in both cases
// field 316 is blanks (when it works and when it doesn't).
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
// Here I get the exception out of bounds error in MSCORLIB.DLL.
// Some records are added fine, while others cause this exception.
// I cannot visibly tell any major differences, nor do I see any
// errors in the AS400 job log or anything in C# that would lead me
// down a certain path.
String error = ex.Message;
}
}
For what it's worth, I found this happening one a smaller file in the system and was able to figure out what going on, after painstaking research into the code and the net. Basically, the file file has numeric fields on the i-series. Somehow, the records were written to the file on the original system with null values in the numeric fields instead of numeric values. When storing the original records, I had to do this calculation:
String fieldType = rs.Fields[i].Type.ToString();
object objValue = rs.Fields[i].Value;
if (fieldType == "adNumeric" && objValue is DBNull)
{
fieldValues[i] += "0";
}
else
{
fieldValues[i] += rs.Fields[i].Value;
}
After this, if null values were found in one of the numeric fields, it just put "0" in it's place so that when writing to the new machine, it would put a valid numeric character in there and continue on writing the rest of the values. Thanks for all the advice and moral support. :)
i have a cloud database server like application on my computer that i'm hosting my game on. However, every time an user tries to save data i get an UnauthorizedAccessException.
Im running it by admin and i dont have any specias right in my folder so i have no idea what's the problem.
Here's my code:
public const string root = "D:/DATABASE/";
public static void WriteData(string playername, string type, string data)
{
if (!Directory.Exists("D:/DATABASE/" + playername))
{
Directory.CreateDirectory("D:/DATABASE/" + playername);
Directory.CreateDirectory("D:/DATABASE/" + playername + "/weapons");
}
if (type != "Weapon")
{
using (StreamWriter sw = new StreamWriter("D:/DATABASE/" + playername + "/" + type + ".sav"))
{
sw.WriteLine(data);
}
}
else
{
string[] dat = data.Split('%');
using (StreamWriter sw = new StreamWriter("D:/DATABASE/" + playername + "/weapons/" + dat[0] + ".gfa"))
{
string[] lines = dat[1].Split('#');
foreach (string cline in lines)
{
sw.WriteLine(cline);
}
}
}
}
public static string ReadLoadout(string playername)
{
string output = "";
string[] items = new string[2];
using (StreamReader sr = new StreamReader(root + playername + "/loadout.gfl"))
{
items[0] = sr.ReadLine();
items[1] = sr.ReadLine();
}
int c = 0;
foreach (string citem in items)
{
if (c > 0) output += "$";
output += citem + "%" + GetCompressedWeaponFile(playername, citem);
c++;
}
return output;
}
public static string GetCompressedWeaponFile(string playerName, string weaponName)
{
string output = "";
using (StreamReader sr = new StreamReader(root + playerName + "/weapons/" + weaponName))
{
string line = " ";
int c = 0;
while (line != null)
{
line = sr.ReadLine();
if (line != null)
{
if (c > 0) output += "#";
output += line;
}
c++;
}
}
return output;
}
public static void RegisterNewUser(string username, string password, string email)
{
string udir = root + username;
Directory.CreateDirectory(udir);
Directory.CreateDirectory(udir + "/weapons");
Directory.CreateDirectory(udir + "/loadouts");
File.WriteAllText(udir + "/password.sav", password);
File.WriteAllText(udir + "/level.sav", "1");
File.WriteAllText(udir + "/money.sav", "1000");
File.WriteAllText(udir + "/email.sav", email);
File.WriteAllText(udir + "/loadout.gfl", "");
using (StreamWriter sw = new StreamWriter(root + "emails.txt", true))
{
sw.WriteLine(email);
}
Email.Send(email, "New Account Registration", string.Format(mailTemplate, username, password));
}
public static void EditLoadout(string username, string items)
{
File.WriteAllLines(root + username + "/loadout.gfl",items.Split('#'));
}
It is difficult to provide specific help without more information. Here are a few of troubleshooting suggestions:
1) Try running your code on a different machine. Specifically your development computer. Do you still have the same error? If not, then there is indeed a permission problem.
2) Have you tried checking the stack trace of the exception?
When you run the application on your own computer, try using the IDE to display the exception. Yes, the problem may ultimately be in a low-level class, but you should be able to break on the error and go back in the call stack to see which method in your code is actually throwing the error.
3) Check the actual exception, even for a system-level exception.
Chances are, if you are able to debug this in the IDE, that you will see property information that will give you a hint. Is it in a directory method or a file write method? Check additional properties. Somewhere it might give you the text of the path (assuming it's a file issue) that it failed on that that could help narrow things down too.
4) Add Exception handling to your code
This is a good rule of thumb, and you should really do this anyway to make a stronger program. Regardless of who's method you are calling (yours, someone else's, or a system method) you need to determine where it should be handled.
For example, in your code, in the RegisterNewUser() method, consider something like:
public static void RegisterNewUser(string username, string password, string email)
{
try
{
string udir = root + username;
Directory.CreateDirectory(udir);
Directory.CreateDirectory(udir + "/weapons");
Directory.CreateDirectory(udir + "/loadouts");
File.WriteAllText(udir + "/password.sav", password);
File.WriteAllText(udir + "/level.sav", "1");
File.WriteAllText(udir + "/money.sav", "1000");
File.WriteAllText(udir + "/email.sav", email);
File.WriteAllText(udir + "/loadout.gfl", "");
using (StreamWriter sw = new StreamWriter(root + "emails.txt", true))
{
sw.WriteLine(email);
}
Email.Send(email, "New Account Registration", string.Format(mailTemplate, username, password));
}
catch (Exception ex)
{
// Create a method to display or log the exception, with it's own error handler
LogAndDisplayExceptions(ex);
// Send the user a message that we failed to add them. Put this in it's own try-catch block
// ideally, for readability, in it's own method.
try
{
Email.Send(email, "Failed to register", "An error occurred while trying to add your account.");
}
catch (Exception exNested)
{
LogAndDisplayExceptions(exNested);
}
}
}
5) Add a "crash-and-burn" exception handler to "main"
In the method that is your "top method" (it's hard to tell in the snippet you provided since there are few methods that would attempt to write to the disk) you could wrap your code in a try - catch block and print the exception or write it to disk.
If you have having trouble writing the exception to disk, I would suggest creating an error file first, make sure that the user account that is running the program can write to it, and then in the catch block open the file for APPEND. This should make it easier to get to the error text.
6) When all else fails, use the Debug class or Console class to write the traditional "I made it to line x."
While this will not solve your problem, it should help you get more information that will provide more insight into where your code is causing an error.
I'm new to C# (worked in PHP, Python, and Javascript) and I'm trying to more or less make a duplicate of another page and change some things - to make a form and database submission.
Anyway, here's the code:
public partial class commenter : System.Web.UI.Page
{
string employee_reviewed;
//public Commenter();
public void SaveBtn_Click(object sender, EventArgs e)
{
if (CommentTB.Text == "Please enter a comment.")
{
String csname = "Email Error";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsStartupScriptRegistered(cstype, csname))
{
String cstext = "alert('Please submit at least one comment.');";
cs.RegisterStartupScript(cstype, csname, cstext, true);
}
FormMessage.Text = "Please submit at least one comment.";
return;
}
string comment = CommentTB.Text;
comment = comment.Replace("'", "''");
comment = comment.Replace("’", "''");
comment = comment.Replace("`", "''");
try
{
//myCommand.Connection.Open();
//myCommand.ExecuteNonQuery();
//myCommand.Connection.Close();
MySqlCommand myCommand;
MySqlConnection connection;
string connStringName = "server=localhost;database=hourtracking;uid=username;password=password";
connection = new MySqlConnection(connStringName);
string sql_query;
sql_query = "insert into peer_review_comment " + " (emp_id, comment)" + " values(?employeeid, ?comment) ";
//String csname = "Email Error";
//Type cstype = this.GetType();
//ClientScriptManager cs = Page.ClientScript;
//cs.RegisterStartupScript(cstype, csname, sql_query, true);
myCommand = new MySqlCommand(sql_query, connection);
//FormMessage.Text = sql_query;
//return;
Trace.Write("comment = ", comment);
myCommand.Parameters.Add(new MySqlParameter("?employeeid", ViewState["employeeid"].ToString()));
myCommand.Parameters.Add(new MySqlParameter("?comment", comment));
try
{
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
}
catch (Exception ex)
{
FormMessage.Text = "Error:SaveBtn_Click - " + ex.Message;
}
//SendNotification(from, to, cc, subject, body, attach);
FormMessage.Text = "\n Thank you for leaving anonymous feedback for " + employee_reviewed; ;
ThankyouDiv.Visible = true;
FormFieldDiv.Visible = false;
reviewHeader.Visible = false;
}
catch (Exception ex)
{
FormMessage.Text = "Error:SaveBtn_Click - " + ex.Message;
}
}
}
I really have little idea what I'm doing - I'm reading the tutorials, but C# is a significantly different language than I am used to.
I get the Javascript alert when I do not change the text currently, but submission isn't working - I want it to submit to peer_review_comment database table, and fill in employeeid as well as the submitted comment.
Sorry if my understanding is so spotty, I am a TOTAL C# newbie (currently reading http://www.csharp-station.com/Tutorial/CSharp/)
My guess is the problem is here:
try
{
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
}
catch (Exception ex)
{
FormMessage.Text = "Error:SaveBtn_Click - " + ex.Message;
// no "return;" !!
}
//SendNotification(from, to, cc, subject, body, attach);
FormMessage.Text = "\n Thank you for leaving anonymous feedback for " +
employee_reviewed; ;
Your catch block is setting the FormMessage.Text value bot not exiting the method, so the method keeps executing where the catch block finishes off, resetting the Text value and appearing that no exception was thrown.
add a return; at the end of your catch block to see the excpetion message.
Some general guidelines to make these kinds of problems easier to trap:
Don't try to do too much in one method. Have one method that validates the message (or do it client-side using Validators, another to do the DB call, etc.
Learn to use the debugger. You can step through code and get a better idea of what causes these kinds of errors.
Unless you can DO something about an exception, there's no harm in letting them bubble up to a higher level event handler (like Elmah) so exceptions don't get accidentally swallowed like it does here. In general it's preferrable to re-throw exceptions in lower-level methods (maybe adding some context or a user-friendly message) so the higher level exception handling can decide what to do (show a message, log, etc.)
I have taken the liberty of refactoring your code. This shows some better code practices but may also show you the problem. Along with these code changes I would also recommend reading D. Stanley's answer; there are some helpful tips in there as well.
if (CommentTB.Text == "Please enter a comment.")
{
String csname = "Email Error";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsStartupScriptRegistered(cstype, csname))
{
String cstext = "alert('Please submit at least one comment.');";
cs.RegisterStartupScript(cstype, csname, cstext, true);
}
FormMessage.Text = "Please submit at least one comment.";
return;
}
// This helps some but very little, just wanted to show an alternative to writing three statements
string comment = CommentTB.Text.Replace("'", "''").Replace("’", "''").Replace("`", "''");
//string comment = CommentTB.Text;
//comment = comment.Replace("'", "''");
//comment = comment.Replace("’", "''");
//comment = comment.Replace("`", "''");
try
{
// No need to do string concatenation...just make it one string.
// sql_query = "insert into peer_review_comment " + " (emp_id, comment)" + " values(?employeeid, ?comment) ";
string sql_query = "insert into peer_review_comment (emp_id, comment) values (?employeeid, ?comment) ";
string connStringName = "server=localhost;database=hourtracking;uid=username;password=password";
// Use a "using" clause because it guarantees the connection is closed even when an exception occurs.
using (MySqlConnection connection = new MySqlConnection(connStringName))
{
connection.Open();
// Again, use a "using" clause
using (MySqlCommand myCommand = new MySqlCommand(sql_query, connection))
{
Trace.Write("comment = ", comment);
myCommand.Parameters.Add(new MySqlParameter("?employeeid", ViewState["employeeid"].ToString()));
myCommand.Parameters.Add(new MySqlParameter("?comment", comment));
myCommand.ExecuteNonQuery();
// No need for a Close statement with "using" clause.
//myCommand.Connection.Close();
}
}
FormMessage.Text = "\n Thank you for leaving anonymous feedback for " + employee_reviewed;
ThankyouDiv.Visible = true;
FormFieldDiv.Visible = false;
reviewHeader.Visible = false;
}
catch (Exception ex)
{
FormMessage.Text = "Error:SaveBtn_Click - " + ex.Message;
}