I have a WebApp running under the default AppPool in IIS.
In my webApi project, I have an [HttpGet] method and an [HttpPost] method.
I have a custom bit of code that basically tries to create a text file in the app location write to it and close.
string path = AppDomain.CurrentDomain.BaseDirectory;
Reporting.PrepareChannel("log", path + ".log");
Reporting.Report("WooOrders", "order created from webhook - Woo order no: ");
Reporting.Shutdown();
placing the above in my [HttpGet] method all works fine, but in my [HttpPost] method It drops onto my catch block and returns the above error?
I'm at a loss as to why this is?
In my [HttpGet] method it creates the file in the physical location that I expect it to be in which is on our 'D' drive.
Here's the full code for both methods. Although I've deployed to our live environment they are not being used yet. I've cut the methods down to literally just create the file write to it and close. I've commented out all other processing for the moment.
[Route("api/woo/createOrder")]
[HttpPost]
public string CreateOrder([FromBody] Models.Order order)
{
try
{
string path = AppDomain.CurrentDomain.BaseDirectory;
Reporting.PrepareChannel("log", path + ".log");
Reporting.Report("WooOrders", "order created from webhook - Woo order no: ");
Reporting.Shutdown();
return "all good";
}
catch (Exception ex)
{
Reporting.Shutdown();
return ex.Message;
}
}
[Route("api/woo/getOrder/{id}")]
[HttpGet]
public string OrderGet([FromUri] string Id)
{
try
{
string path = AppDomain.CurrentDomain.BaseDirectory;
Reporting.PrepareChannel("log", path + ".log");
Reporting.Report("WooOrders", "Get Order ");
Reporting.Shutdown();
return "all good";
}
catch (Exception ex)
{
Reporting.Shutdown();
return ex.Message;
}
}
Related
I tried to update file to physically via my controller. But my controller save in local (actually Visual Studio run) perfectly but when I tried to publish and setup to on my server and use www.mywebsite.com then controller couldn't save to path without an error.
My scenerio is like this:
In client side onReady js method, I get physical root path from my database (this is work both side, no problem i watching debug console). My physical path like this: \\192.168.1.1\MYFILE-1.1
I pass to value with POST method file and root path via Model
In a controller side, I create timestamp for a file name, and combine more path file. Like this my controller:
[HttpPost]
public JsonResult SavePhysicalPath(FileModel model)
{
//create timestamp of file name
string filesMimeType = MimeTypesMap.GetMimeType(model.FormFile.FileName);
string filesExtType = MimeTypesMap.GetExtension(filesMimeType);
string fnTimeStamp = DateTime.Now.ToString("ddMMyyyy_HHmmssffff");
string edittedFileName = fnTimeStamp + "." + filesExtType;
string edittedFmAndSubPath = "MyDocs\\OtherFiles\\" +edittedFileName ;
var savingRootPath = "";
savingRootPath =model.FileFolderPath; // FileFolderPath is string get from view "\\192.168.1.1\MYFILE-1.1"
try
{
string SavePath = Path.Combine(Directory.GetCurrentDirectory(), savingRootPath, edittedFmAndSubPath );
using (var stream = new FileStream(SavePath, FileMode.Create))
{
model.FormFile.CopyTo(stream);
}
stringOutput = "OK";
return Json(stringOutput);
}
catch (Exception ex)
{
stringOutput = "ERR";
return Json(stringOutput);
throw;
}
}
if there is no directory, then create one.
bool exists = System.IO.Directory.Exists(SavePath);
if (!exists)
System.IO.Directory.CreateDirectory(SavePath);
or you can create one in manually on server.
EDIT:
My problem has been solved thanks to the user Chris Larabell, thank you to all that responded.
The issue that is happening with my code is that when the said file is not present in the Desktop directory, the console will close and will not go to the else statement for what happens when the file is not present. When the file is present however, the console will work completely fine, it is just the else statement.
Here is my code that is being used.
if (inputDrive == "search.system")
{
try
{
string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string DeleteFile = #"delete.txt";
string[] fileList = System.IO.Directory.GetFiles(Desktop, DeleteFile);
foreach (string file in fileList)
{
if (System.IO.File.Exists(file))
{
System.IO.File.Delete(file);
Console.WriteLine("File has been deleted");
Console.ReadLine();
}
else
{
Console.Write("File could not be found");
Console.ReadLine();
}
}
}
catch (System.IO.FileNotFoundException)
{
Console.WriteLine("search has encountered an error");
Console.ReadLine();
}
}
What I am trying to accomplish is to find a file through the Desktop directory with the name of 'delete.txt' and to delete it when the user enters "search.system". the console would then say back to you that the file has been deleted. If the file has not been found, it would say that "the file could not be found" back to you through console. If an error would to occur, it would go to catch and say "search has encountered an error"
I also want to say that I am sorry if this code is messy and/or if this is completely wrong from what I am trying to accomplish. I am new to C#, and new to coding in general.
You would want to put an if statement to check that the fileList length is > 0. If the file length is zero, the file was not found. Otherwise, you can proceed to delete the file.
Also, don’t be discouraged as a new coder. Set a breakpoint at the line where you use the GetFiles() method and step (F11) to the next line. Hover your cursor over the fileList variable and see if the number of items in the array is zero.
System.IO.Directory.GetFiles()
It looks like you are simply looking for a specific file by name and deleting it if it exists. You could simplify your code by doing this:
if (inputDrive == "search.system")
{
try
{
string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string DeleteFile = #"delete.txt";
string filePath = System.IO.Path.Combine(Desktop, DeleteFile);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
Console.WriteLine("File has been deleted");
Console.ReadLine();
}
else
{
Console.Write("File could not be found");
Console.ReadLine();
}
}
catch (System.Exception ex)
{
Console.WriteLine($"search has encountered an error: {ex}");
Console.ReadLine();
}
}
I have an strange problem I have an app that scan a directory and gets a list of files. it processes each file by reading it and doing some stuff. it works fine in the development computer but when I deploy it to the client it gives me the error. Here is the code
public void ProcessIMFiles()
{
DirectoryInfo di = new DirectoryInfo(Globals.ITMDIR);
FileInfo[] Files = di.GetFiles("*.txt");
foreach(FileInfo file in Files)
{
try
{
processThisIMFile(file.FullName);
movefile(file.FullName);
}
catch (Exception ex)
{
MessageBox.Show("error : " + ex.Message);
}
}
}
The error happens in the call to processThisIMFile(file.FullName) see below.
Globals.ITMDIR is a valid path.
private void processThisIMFile(string FileName)
{
string[] Fields = null;
setconnection();
DataTable dt = null;
try
{
string[] Lines = System.IO.File.ReadAllLines(FileName);
foreach (string line in Lines)
{
Fields = line.Split(Globals.delimiter);
if (Fields.Length == 7)
{
//stuff happens here
}
}//Try
catch (Exception e)
{
if (Interactive)
{
MessageBox.Show("Error in the Path: ->" + FileName);
writeToLog(true, "error opening file " + FileName);
}
}
}//end of processThisItemFile
the error happens in the "string[] Lines = System.IO.File.ReadAllLines(FileName)"
line. FileName comes from the di.GetFiles("*.txt"); when I show the actual path it looks ok to me. I have tried with UNC paths and with drive letters path as in C:\tmp\filename.txt or \\server\tmp\filename.txt both fail in the deplopyment machine with "The given path's is not supported" but it works fine in the development machine.
What is going on?
I'm wondering if this could be related to file.fullname somehow altering the file path string and giving an unacceptable result. Can you troubleshoot by using processThisIMFile(Path.GetFullPath(file))? Also, use messagebox.show(file.FullName) prior to processthisimfile to confirm that the result is as expected.
I have a windows service which polls for a specific folder for creation of new files. This works fine when the folder is in one of the local drives such as C: or D:
The service fails to find a folder on a mapped drive.
Here is the code which does the checking for folder exist before polling:
System.Security.Principal.WindowsIdentity userIdentity =
System.Security.Principal.WindowsIdentity.GetCurrent();
System.Security.Principal.WindowsPrincipal principal =
new System.Security.Principal.WindowsPrincipal(userIdentity);
MappedDriveResolver mdr = new MappedDriveResolver();
if (mdr.isNetworkDrive(folderPath))
{
LoggingAppWrapper.LogDeveloperMessage(folderPath + " is on a Mapped drive", 1, TraceEventType.Information, string.Empty);
}
MappedDriveResolver is a class that I found hereHow do I determine a mapped drive's actual path?
The code in that link works fine from a simple console application, but fails when it is part of windows service.
Any suggestions as to what has to be done for the code to work for a windows service?
Regards.
I would recommend you configure your service to use UNC paths for folders not on the server running the service.
Mapped drives are a usability feature for users and as such they are specific to that users profile/environment. Meaning, when you login you may have a drive X: that is mapped to \\server1\share1 but when I login my drive X: could be mapped to \\server2\share2 instead. The actual mapping process is either saved as part of your profile with the "Reconnect at logon" or is handled by a logon script.
You need to check what account the service is running under and make sure that mapped drive exists for that user environment (This might help How to map a network drive to be used by a service).
Edit:
The reason your console application works and the service doesn't is because of the differences between the environment they are running in.
To illustrate this, take this console application, compile it and then run it as a Schedule Task. Set the "path" variable to be a mapped drive that your user can access.
static void Main(string[] args) {
MappedDriveResolver mdr = new MappedDriveResolver();
string logfile;
string path = #"I:\";
string[] files;
// Write out "log" file to where this is running from
logfile = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
logfile = Path.Combine(logfile, "log.txt");
using (StreamWriter sw = new StreamWriter(logfile, true)) {
try {
sw.WriteLine("Checking path " + path);
if (mdr.isNetworkDrive(path)) {
sw.WriteLine("Network Drive: Yes");
} else {
sw.WriteLine("Network Drive: No");
}
} catch (Exception ex) {
sw.WriteLine("Exception: " + ex.Message);
}
try {
sw.WriteLine("Resolve path " + path);
string newpath = mdr.ResolveToUNC(path);
sw.WriteLine("Resolved path " + newpath);
} catch (Exception ex) {
sw.WriteLine("Exception: " + ex.Message);
}
try {
sw.WriteLine("Get file list from " + path);
files = Directory.GetFiles(path);
if (files == null || files.Length == 0) {
sw.WriteLine("No files found");
} else {
sw.WriteLine(string.Format("Found {0} files.", files.Length));
}
} catch (Exception ex) {
sw.WriteLine("Exception: " + ex.Message);
}
sw.Flush();
sw.Close();
}
}
Note: This is with the Windows 7 Task Scheduler
Test 1: Just run the app by double-clicking on it.
Result: Success
Test 2: Configure scheduled task to run as your user account with "Run only when user is logged on"
Result: Success
Test 3: Configure scheduled task to run as your user account with "Run whether user is logged on or not"
Result: Exceptions
Test 4: Configure schedule task to run as "Local Service" account.
Result: Exceptions
Test 1 & 2 work because they are using the currently logged in user environment including the mapped drives that are part of it.
Test 3 & 4 fail because they have their own user environment created for them, which does not have any mapped drives configured. It escapes me at the moment what the differences there are, but an "interactive" and "non-interactive" environment are different in some significant ways.
I have this simple code:
System.Drawing.Bitmap bm = bitmapSourceToBitmap(source);
try
{
bm.Save(#"C:\Seva\testeImagem.jpg");
}
catch (Exception ex)
{
}
This throws: Generic Error GDI+.
Anyway, I seached and people say that the problem is with permissions. How can I give permissions to it? Thanks
First find out under what credentials the code is running.
Then check (and, when needed, fix) the security/NTFS settings of the Seva folder.
Especially when this code is running from within a website or service the account will not have permissions to write to the folder.
instead of saving to C:\Seva\testeImagem.jpg why not try saving to
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"testeImagem.jpg");
You must ensure that the Seva folder exists under C:\ and ensure that the current user has permissions to write to\create this folder. Also, its considered bad practice to write to folders that the user doesn't own. If the user is Running As A Normal User (not an admin) failure to do so results in permission exceptions.
Could you test if the folder exists?
void BitmapCopy(System.Drawing.Bitmap source, string filename) {
if (!String.IsNullOrEmpty(filename) && (source != null)) {
string dirName = #"C:\Seva";
if (!System.IO.Directory.Exists(dirName)) {
dirName = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
string bmpFile = System.IO.Path.Combine(dirName, filename);
System.Drawing.Bitmap bm = bitmapSourceToBitmap(source);
try {
bm.Save(bmpFile);
} catch (ArgumentNullException ex) {
Console.WriteLine(ex.Message);
} catch (System.Runtime.InteropServices.ExternalException ex) {
Console.WriteLine(ex.Message);
}
}
}