C#: Add a new check without affecting existing checks - c#

I hope I can explain my scenario the best I can.
I have code that when the "Load" button is clicked, all file names (if any) located in a predefined network directory path, are loaded to a text-area.
Currently there can be .txt, .xml files.
Contents could look like:
first_file_found.xml
second_file_found.xml
third_file_found.txt
Also, in the code there is another function "isCoValid" that performs an additional validation of the contents of these files, based on return value (true/false) of this function, the "Process" button is enabled:
if (IsFlatFile(fileName) || IsXMLFile(fileName))
{
if (isCoValid(fileName))
{
btnProcess.Enabled = true;
}
else
{
btnProcess.Enabled = false;
break;
}
}
Now I have to add a .csv file type, but this file does not required to perform the isCoValid function.
The text-area contents now look like:
first_file_found.xml
second_file_found.xml
third_file_found.txt
fourht_file_found.csv
My request for help is to ask how can the check to find out if there is a CSV file can be done, and also controlling the enabling of the "Process" button, but still respect the existing check for .txt, and .xml and the validation of contents?
I might have xml and text files, that aren't valid, but I still need to be able to process the .csv. file.
I did change it like this:
if (IsFlatFile(fileName) || IsXMLFile(fileName))
{
if (isCoValid(fileName))
{
btnProcess.Enabled = true;
}
else
{
btnProcess.Enabled = false;
break;
}
}
if (IsCSVFile(fileName))
{
btnProcess.Enabled = true;
}
But I am sure this is not correct and I would like to ask for some help if possible.
I hope I explained my problem with some clarity and straightforwardness, if not, please let me know and I can try to provide more information.
Thank you,
Erasmo
Additional Code Requested
public bool IsFlatFile(string FileName)
bool ReturnValue = false;
if (FileName.ToUpper().Right(4) == ".TXT")
{
if ((FileName.Substring(0, 2).ToUpper() == "MN") ||
(FileName.Substring(0, 2).ToUpper() == "CH"))
{
ReturnValue = true;
}
}
return ReturnValue;
}
public bool IsXMLFile(string FileName)
bool ReturnValue = false;
if (FileName.ToUpper().Right(4) == ".XML")
{
if ((FileName.Substring(0, 2).ToUpper() == "TR") ||
(FileName.Substring(0, 2).ToUpper() == "SK"))
{
ReturnValue = true;
}
}
return ReturnValue;
}
protected bool isCoValid(string fName)
{
bool retCode = false;
Parameters parms;
var reader = new AppSettingsReader();
Application app = new Application();
Package package = null;
try
{
package = app.LoadPackage(packagePath + "ValidateContents.dtsx", null);
parms = package.Parameters;
parms["ID"].Value = "";
parms["ImportFileName"].Value = fName;
parms["UserID"].Value = userName;
DTSExecResult results = package.Execute();
if (results == Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure)
{
foreach (Microsoft.SqlServer.Dts.Runtime.DtsError local_DtsError in package.Errors)
{
retCode = false;
resultText = resultText + "DTSX Package Execution results: " + local_DtsError.Description.ToString() + Environment.NewLine;
}
}
else
{
resultText = resultText + "Successful Process Completion." + Environment.NewLine + Environment.NewLine;
string sqlStr = "SELECT TOP 1 * FROM Validation WHERE Type = 'VALCO' AND CAST(CreatedDate AS DATE) = CAST(GETDATE() AS DATE)";
DataTable dt = new DataTable();
dt = GetDataSet(sqlStr);
if (dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
if (row["Status"].ToString() == "Valid")
{
retCode = true;
resultText = "Output: Valid" + Environment.NewLine + "Press the 'Process' button to proceed.";
}
else
{
retCode = false;
resultText = "Output: " + row["Status"].ToString() + Environment.NewLine + "Validation Fail: " + row["Error"].ToString();
}
}
}
else
{
resultText = "Unable to read Validation Table for this file.";
retCode = false;
}
}
}
catch (Exception)
{
throw;
}
return retCode;
}

Your code will look like so:
if (IsFlatFile(fileName) || IsXMLFile(fileName) || IsCSVFile(fileName))
{
btnProcess.Enabled = isCoValid(fileName);
if (!btnProcess.Enabled) break;
}
public static bool IsCSVFile(string FileName) =>
Path.GetExtension(FileName).Equals(".csv", StringComparison.OrdinalIgnoreCase);
when you write your own IsCSVFile() method and update isCoValid() method to fit your needs.
Sorry, but I can't guess what happens inside classes that are used in isCoValid() method.

Related

C# How to rename a file without using File.Move

I have a c# application that connects to a server, gets the datagrid, manipulates each row and then according to each updated row the new row gets uploaded to the server and one file per row gets renamed on the hdd.
The application works totally fine but i analyzed it with the profiler and realised that this line of code:
File.Move(symbolsOldPath, symbolsPath);
takes 80% of the time my application needs to complete its task.
I went through all the questions on StackOverflow and other questions out there if there is a different way for a better performance but i wasnt succesful. The only other way i found was implementing VB to use the Rename method, but as it calls the File.Move method it is no improvement. Do you guys know an alternative way with better performance?
Here is my code of the class that changes the data.
public DataTable ChangeData(DataTable unchangedData, string searchPathSymbols, string searchPathImages, ProgressBar pbForm)
{
pbtemp = pbForm;
int rowCount = unchangedData.Rows.Count;
foreach (DataRow row in unchangedData.Rows)
{
counter++;
if (counter == 10)
{
pbtemp.Value += counter;
counter = 0;
Application.DoEvents();
}
number = row[1].ToString();
symbolsPath = row[2].ToString();
symbolsPathCopy = symbolsPath;
imagesPath = row[3].ToString();
imagesPathCopy = imagesPath;
aliasSymbols = symbolsPath.Substring(0, symbolsPath.IndexOf('>') + 1);
if (symbolsPath == imagesPath)
{
if (aliasSymbols.Contains("Symbole"))
{
if (!string.IsNullOrEmpty(symbolsPath))
{
SymbolsChanger(searchPathSymbols, row);
row[3] = row[2];
}
}
else
{
if (!string.IsNullOrEmpty(imagesPath))
{
ImagesChanger(searchPathImages, row);
row[2] = row[3];
}
}
}
else
{
if (!string.IsNullOrEmpty(symbolsPath))
{
SymbolsChanger(searchPathSymbols, row);
}
if (!string.IsNullOrEmpty(imagesPath))
{
ImagesChanger(searchPathImages, row);
}
}
}
pbtemp.Value += (rowCount - pbtemp.Value);
return unchangedData;
}
private void SymbolsChanger(string searchPathSymbols, DataRow row)
{
string symbolsOldPath;
//Symbols
//Get and delete Alias and get filepath
int countAliasSymbolsIndex = symbolsPath.LastIndexOf('>') + 1;
symbolsPath = symbolsPath.Remove(0, countAliasSymbolsIndex);
symbolsOldPath = searchPathSymbols + "\\" + symbolsPath;
//Remove and replace numbers
int startSymbolsIndex = 0;
int endSymbolsIndex = symbolsPath.IndexOf('_') == -1 ? symbolsPath.LastIndexOf('.') : symbolsPath.IndexOf('_');
int countSymbolsIndex = endSymbolsIndex - startSymbolsIndex;
symbolsPath = symbolsPath.Remove(startSymbolsIndex, countSymbolsIndex);
string nameSymbols = number + symbolsPath;
symbolsPath = searchPathSymbols + "\\" + nameSymbols;
try
{
//Rename file
File.Move(symbolsOldPath, symbolsPath);
}
catch(FileNotFoundException)
{
try
{
File.Move(symbolsPath, symbolsPath);
}
catch (FileNotFoundException)
{
logArrayDataChange.Add(symbolsPathCopy);
}
}
row[2] = aliasSymbols + nameSymbols;
}
private void ImagesChanger(string searchPathImages, DataRow row)
{
string imagesOldPath;
//Images
//Get and delete Alias and get filepath
string aliasImage = imagesPath.Substring(0, imagesPath.IndexOf('>') + 1);
int countAliasImagesIndex = imagesPath.LastIndexOf('>') + 1;
imagesPath = imagesPath.Remove(0, countAliasImagesIndex);
imagesOldPath = imagesPath.StartsWith("\\") == true ? searchPathImages + imagesPath : searchPathImages + "\\" + imagesPath;
//Remove and replace numbers
int startImagesIndex = imagesPath.LastIndexOf("\\") == -1 ? 0 : imagesPath.LastIndexOf("\\");
int endImagesIndex = imagesPath.IndexOf('_') == -1 ? imagesPath.LastIndexOf('.') : imagesPath.IndexOf('_');
int countImagesIndex = endImagesIndex - startImagesIndex;
imagesPath = imagesPath.Remove(startImagesIndex + 1, countImagesIndex - 1);
int insertIndex = imagesPath.LastIndexOf("\\") == -1 ? 0 : imagesPath.LastIndexOf("\\");
string nameImages = imagesPath.Insert(insertIndex + 1, number);
imagesPath = searchPathImages + "\\" + nameImages;
try
{
//Rename file
File.Move(imagesOldPath, imagesPath);
}
catch (FileNotFoundException)
{
try
{
File.Move(imagesPath, imagesPath);
}
catch (FileNotFoundException)
{
logArrayDataChange.Add(imagesPathCopy);
}
}
row[3] = aliasImage + nameImages;
}
}
}
I would keep File.Move to do the job. Besides a little overhead (checks), File.Move uses only the native MoveFile Windows call to move the file:
[DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool MoveFile(String src, String dst);
You can call that method yourself, but I doubt it will get any faster than that.
From the documentation it seems that move is already built to rename efficiently:
The MoveFile function will move (rename) either a file or a directory ...

Create new user and comparison for two textbox

I have to do a form for new user in my project.
I do not know what is wrong with it.
This is the method:
private void NewUserMethod() {
try {
NewUserTbl newUserTbl = new NewUserTbl();
newUserTbl.FName = txtFName.Text;
newUserTbl.LName = txtLName.Text;
newUserTbl.UserName = txtUserName.Text;
newUserTbl.NewPassword = txtPass.Text;
newUserTbl.ConfirmPassword = txtAgainPass.Text;
txtFName.Text = "";
txtLName.Text = "";
txtUserName.Text = "";
txtPass.Text = "";
txtAgainPass.Text = "";
if (txtPass == txtAgainPass) {
DB_Admin.NewUserTbls.InsertOnSubmit(newUserTbl);
DB_Admin.SubmitChanges();
MessageBox.Show("new user created");
} else {
MessageBox.Show("Wrong Password");
}
} catch (Exception)
{
MessageBox.Show("You entered wrong data");
}
}
I'm new at C# programming.
You were comparing two controls instead of their text property
if (txtPass == txtAgainPass)
{
}
However if you start comparing with it's Text property
like this
if (txtPass.Text == txtAgainPass.Text)
{
}
this won't bring any change because you are making empty
txtPass.Text = "";
txtAgainPass.Text = "";
Try like this
if (newUserTbl.NewPassword == newUserTbl.ConfirmPassword)
{
}
I'm assuming these are textboxes : if (txtPass == txtAgainPass). hence, they are different and not the same ...
try comparing the actual strings in them
to get the text of TextBox for comparison or any thing ,
you should write " .text " after the name
Like txtName.Text

Excel Interop Problems - C#

I have a problem with Excel Interop objects. I can't seem to pinpoint the problem either. (My code is at the bottom). Basically, sometimes it reads the cells correctly, but sometimes it doesn't. After two passes, it stops reading entirely. I think I have a math issue, but I can't find it. I would get someone else to read my code, but I don't have anyone nearby. I'll be on for awhile to answer questions. Thanks for the help, its a bit frustrating on why it doesn't work.
if(requiredEnd == true && requiredPass == true && requiredPath == true && requiredStart == true && requiredUser == true && requiredSheet == true)
{
errorCheck = false;
try
{
//starting Excel
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = false;
Excel.Workbook workBook = excelApp.Workbooks.Open(filePath);
Excel.Sheets sheet = workBook.Worksheets;
Excel.Worksheet workSheet = (Excel.Worksheet)sheet.get_Item(sheetName);
//Generating User and Password
int startCoordI = Int32.Parse(startCoord);
int endCoordI = Int32.Parse(endCoord);
int value = startCoordI;
string combinedUser = userCoord + startCoord;
string combinedPassword = passwordCoord + startCoord;
string Username = Convert.ToString(workSheet.Cells.Named(combinedUser).Value);
MessageBox.Show(Username);
string Password = Convert.ToString(workSheet.Cells.Named(combinedPassword).Value);
MessageBox.Show(Password);
try
{
System.Diagnostics.ProcessStartInfo proccessStartInfo = new System.Diagnostics.ProcessStartInfo("net", "user " + Username + " " + Password + " /add /passwordchg:no");
System.Diagnostics.Process proc = new System.Diagnostics.Process { StartInfo = proccessStartInfo };
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proccessStartInfo.CreateNoWindow = true;
for (I = startCoordI; I <= endCoordI; I++)
{
proc.Start();
//new user
value++;
combinedUser = userCoord + value;
combinedPassword = passwordCoord + value;
Username = Convert.ToString(workSheet.Cells.Named(combinedUser).Value);
MessageBox.Show(Username);
Password = Convert.ToString(workSheet.Cells.Named(combinedPassword).Value);
MessageBox.Show(Password);
}
//Clean up Excel
Marshal.ReleaseComObject(excelApp);
Marshal.ReleaseComObject(workBook);
Marshal.ReleaseComObject(sheet);
Marshal.ReleaseComObject(workSheet);
//Executing.Show
proc.WaitForExit();
//Executing.Close
if(proc.HasExited == true)
{
if(errorCheck == false)
{
MessageBox.Show("The Process Has Been Completed!");
}
else
{
MessageBox.Show("Operation Ended With Errors. Exiting Excel Reader.");
}
proc.Close();
this.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
if(requiredEnd == false || requiredPass == false || requiredStart == false || requiredUser == false || requiredSheet == false)
{
MessageBox.Show("You Have Missing Required Fields!");
}
else
{
MessageBox.Show("That Is Not A Valid File!");
}
There is a lot of "un-needed" parts there, but I thought giving the whole thing would be more helpful. (Most of the textboxes are just debug things, BTW)
EDIT: I forgot .Named wasn't part of the normal code. Its a function someone made for me:
public static class ExcelExtensions
{
public static Range Named(this Range Cells, string CellName)
{
char cellLetter = CellName.Substring(0, 1).ToUpper()[0];
int xCoordinate = (cellLetter - 'A') + 1;
int yCoordinate = int.Parse(CellName.Substring(1));
return Cells[xCoordinate, yCoordinate];
}
}
It basically allows you to use PowerShell themed coordinates, i.e (A1, B3 etc.)
Gusman has answered my question in the comments, so I will explain here. My problem was that I had the x and y coordinates swapped, and that I didn't have the process inside the loop. Thank you Gusman!

Strange behaviour of ViewState

I have an Asp.Net page (named 'PostAD') which allows user to upload up to 4 pictures. The file upload button function is as follows:
protected void btnUpload_Click(object sender, EventArgs e)
{
if ((ViewState["Img1"] != null) && (ViewState["Img2"] != null) && (ViewState["Img3"] != null) && (ViewState["Img4"] != null))
{
lblUploadMsg.Text = "You cannot upload more than 4 pictures";
return;
}
if (FileUpload1.HasFile)
{
//FileUpload1.Attributes.Clear();
string fileExtension = System.IO.Path.GetExtension(FileUpload1.FileName);
if (fileExtension.ToLower() == ".jpg")
{
int fileSize = FileUpload1.PostedFile.ContentLength;
if (FileUpload1.PostedFile.ContentLength < 2097152)
{
//FileUpload1.SaveAs(Server.MapPath("~/Temp/" + FileUpload1.FileName));
//Response.Write("Successfully Done");
string sp = Server.MapPath("~/ItemPictures/");
String fn = Guid.NewGuid().ToString() + FileUpload1.FileName.Substring(FileUpload1.FileName.LastIndexOf("."));
if (sp.EndsWith("\\") == false)
sp += "\\";
sp += fn;
FileUpload1.PostedFile.SaveAs(sp);
lblUploadMsg.ForeColor = System.Drawing.Color.Green;
lblUploadMsg.Text = "Picture Uploaded successfully. You can upload upto 4 pictures";
if (ViewState["Img1"] == null)
{
ViewState["Img1"] = "~/ItemPictures/" + fn;
}
else if (ViewState["Img2"] == null)
{
ViewState["Img2"] = "~/ItemPictures/" + fn;
}
else if (ViewState["Img3"] == null)
{
ViewState["Img3"] = "~/ItemPictures/" + fn;
}
else if (ViewState["Img4"] == null)
{
ViewState["Img4"] = "~/ItemPictures/" + fn;
}
}
else
{
lblUploadMsg.Text = "Maximum 2MB files are allowed";
}
}
else
{
lblUploadMsg.Text = "Only JPG files are allowed";
}
}
else
{
lblUploadMsg.Text = "No File was Selected";
}
ShowAvailblImgs();
}
I have four Asp.Net images that are invisible at page load time. To show them i have the following code.
private void ShowAvailblImgs()
{
if (ViewState["Img1"] != null)
{
//The string URL variable is used just to show what value ViewState["image1"] currently has.
string URL = (string)ViewState["img1"];
Response.Write(URL);
Image1.ImageUrl = (string)ViewState["img1"];
Image1.Width = 130;
Image1.Height = 130;
Image1.Visible = true;
}
else
Image1.Visible = false;
if (ViewState["Img2"] != null)
{
Image2.ImageUrl = (string)ViewState["img2"];
Image2.Width = 130;
Image2.Height = 130;
Image2.Visible = true;
}
else
Image2.Visible = false;
if (ViewState["Img3"] != null)
{
Image3.ImageUrl = (string)ViewState["img3"];
Image3.Width = 130;
Image3.Height = 130;
Image3.Visible = true;
}
else
Image3.Visible = false;
if (ViewState["Img4"] != null)
{
Image4.ImageUrl = (string)ViewState["img4"];
Image4.Width = 130;
Image4.Height = 130;
Image4.Visible = true;
}
else
Image4.Visible = false;
}
I am having very strange behaviour of ViewState variable. Upon loading images, they are not shown in Asp.Net image control. Instead empty image areas are shown. Though the URL variable i used print exact path to the image. Upon saving the image (which are really blank image areas), it get saved my .aspx page. I was using Session variable which worked fine but due to some reasons, i want to use ViewState variable.
ViewState is fine. You are using different case for your ViewState index string, so they don't refer to the same ViewState property. "Img1" is not equal to "img1".
ViewState["Img1"] != null)
{
Image2.ImageUrl = (string)ViewState["img1"];
I recommend either using a constant for the value name, as below.
const string image1 = "img1";
const string image2 = "img2";
const string image3 = "img3";
const string image4 = "img4";
Or refer to my blog post to create strongly-typed pseudo-properties using extension methods.
http://coding.grax.com/2013/06/simple-strongly-typed-pattern-for.html
I don't want to say a wrong thing, but, reading from documentation, it was written that
"Viewstate is used to preserve page and control values between round trips"
http://msdn.microsoft.com/en-us/library/ms178198(v=vs.85).aspx
Have you tried to put the URLs in variables, and then assigning to ViewState["imgX"], and try to do another Postback and see if the ViewState["imgX"] contains the URL?

Process.Start Catch all FileName/Arguments code

I have some code that I wanted to improve. It uses Process.Start and should be able to handle any input any argument, and still work.
I don't think I have covered all the bases. Can anyone suggest a better/more thorough approach?
ToMaybeUri is an extension method that tries to create a Uri.
ToValidMailToArgument is an extension method that adds "attachments="
IsValidEmail is an extension method that does a RegEx on the email address.
public static void RunProcess(string fileName, string Params)
{
var useProcessStart = true;
var validFile = false;
var validDir = false;
var validEmail = false;
var validURL = false;
var proc = new Process();
var info = new ProcessStartInfo(fileName);
info.UseShellExecute = true;
info.Arguments = Params;
//try catches here in case the syntax of the string has invalid characters for dir/file
try
{
var di = new DirectoryInfo(fileName);
validDir = di == null ? false : di.ExistsNow();
}
catch (Exception ex) { }
try
{
var fi = new FileInfo(fileName);
validFile = fi == null ? false : fi.Exists();
}
catch (Exception ex) { }
if (Params == "")
{
if (validFile)
{
if (Path.GetExtension(fileName).ToUpper() == ".CHM")
{
var helpProvider1 = new HelpProvider();
helpProvider1.HelpNamespace = fileName;
Help.ShowHelp(Application.OpenForms[0], helpProvider1.HelpNamespace);
MessageBox.Show(msg);
return;
}
}
else if (validDir)
{
//skip
}
else if (fileName.IsValidEmail())
{
validEmail = true;
info.FileName = "mailto:" + info.FileName;
info.Arguments = "";
}
else if (fileName.IsValidUrl())
{
validURL = true;
info.FileName = fileName.ToMaybeUri().Value.ToString();
info.Arguments = "";
}
else
{
MessageBox.Show(fileName + " does not exist.");
}
}
else
{
//and has params
if (Path.GetExtension(fileName).ToUpper() == ".PDF" && Params.ToLower().StartsWith("p"))
{
int pageNum = 0;
string pageNumString = Grazer.Utilities.Strings.Right(Params, Params.Length - 1);
int.TryParse(pageNumString, out pageNum);
//PDFLocation = "/A \"page=" + pageNum + "=OpenActions\" \"" + ssGlobals.ssStartDir + "\\Example.pdf\""
string app = GrRegistry.GetApplicationFromExtension(".PDF");
if (Path.GetFileNameWithoutExtension(app).ToUpper() == "ACROBAT" || Path.GetFileNameWithoutExtension(app).ToUpper() == "ACRORD32")
{
string PDFLocation = String.Format("/A \"page={0}=OpenActions\" \"{1}\"", pageNum, Path.GetFullPath(fileName));
info = new ProcessStartInfo(app);
info.Arguments = PDFLocation;
}
}
else if (fileName.IsValidEmail())
{
validFile = false;
try
{
var fi = new FileInfo(info.Arguments);
validFile = fi == null ? false : fi.ExistsNow();
}
catch (Exception ex) { }
info.FileName = String.Format("mailto:{0}{1}", fileName, new FileInfo(info.Arguments).ToValidMailToArgument());
info.Arguments = "";
}
}
if (useProcessStart)
{
proc.StartInfo = info;
try
{
if (validURL || validFile || validDir || validEmail)
proc.Start();
}
catch (Exception ex)
{
switch (ex.Message)
{
case "No process is associated with this object.":
break;
default:
MessageBox.Show(ex);
if (info.Arguments.ToEmptyIfNull().Length > 0)
MessageBox.Show(String.Format("{0} could not be opened with parameters: {1}", info.FileName, info.Arguments));
else
MessageBox.Show(String.Format("{0} could not be opened", info.FileName));
break;
}
}
}
}
To start with, you don't want to swallow exceptions. On your catch blocks, make sure you're doing something after catching an exception. Also, find out what specific exceptions can be thrown by methods you're calling in your try blocks and catch those specific exceptions, like so:
try
{
SomeMethod();
}
catch (SpecificExceptionType1)
{
//do something based on what this exception means
}
catch (SpecificExceptionType2)
{
//ditto here
}
catch
{
//handle unexpected exceptions here
}
Also, this smells suspiciously like homework - perhaps implementing a command shell? If so, retag it as homework. If not, just tell me to stuff it.

Categories

Resources