How to combine address for web or file system? - c#

In C# I must create a method that receives as parameters webPath or fileSystemPath plus a file name. Consider that this method is going to be called from a asp.net and also from a windows form project.
This are the cases I assume that could be, and the code I wrote so far:
string webPath1 = "//someaddress";
string webPath2 = "//someaddress/";
string fsPath1 = #"\\somefolder";
string fsPath2 = #"\\somefolder\";
string filename = "somefilename.txt";
string WebPathFileName1 = System.IO.Path.Combine(webPath1, filename);
string WebPathFileName2 = System.IO.Path.Combine(webPath2, filename);
string s1 = Path.GetFullPath(WebPathFileName1);
string FsPathFileName1 = System.IO.Path.Combine(fsPath1, filename);
string FsPathFileName2 = System.IO.Path.Combine(fsPath2, filename);
string s2 = Path.GetFullPath(FsPathFileName1);
If you test the code you will see that WebPathFileName1 returns "//someaddress\\somefilename.txt" but I should response with "//someaddress//somefilename.txt".
The input path could end or not with \
What other methods could I use to combine paths? Thanks.
I may come with more details from my project leader as I know. The idea is that, as I said, this method will be called from 2 kind of projects. So it should compose a web path or a files system path.

Related

string value obtained from reading from json file , displays weirdly when using Path.Combine

I have a functionality where I would scan a given path for a certain file and process some information based on the information in that file . this file info.json in json syntax has a name and a relative path to a certain directory .
What I am trying to do is simply obtain the relative path from the json file and print out an absoulute path
the relative file specified in the info.json file is as below,
{
"Name": "testName",
"OriginalPath": "new/File"
}
The absolute path that I am trying to print out is something like :- D:\testDel\new\File but the actual value is always something like D:\testDel\new/File , while I must say this path is still a valid path (when I do a win key + R I can navigate to that directory) but in terms of how its been displayed it looks messy .
Any Idea as to why I might be facing this problem , am I doing something wrong ,
my code is as follows
string path = #"D:\testDel";
IEnumerable<string> foundFiles = Directory.EnumerateFiles(path, "info.json", SearchOption.AllDirectories);
foreach (string file in foundFiles)
{
DataModel data = JsonConvert.DeserializeObject<DataModel>(File.ReadAllText(file));
string Name = data.Name;
string absolutePath = data.OriginalPath;
string folderpath = Path.GetDirectoryName(file);
string fullPath = Path.Combine(folderpath, absolutePath);
Console.WriteLine(fullPath);
}
public class DataModel
{
public string Name { get; set; }
public string OriginalPath { get; set; }
}
Wrap the Path.Combine(folderpath, absolutePath) statement in a Path.GetFullPath() as
fullPath=Path.GetFullPath(Path.Combine(folderpath, absolutePath));
this will also resolve reletive paths like ../NewFil to D:\NewFile
You can update a path, coming from JSON using Replace method and built-in Path.AltDirectorySeparatorChar and Path.DirectorySeparatorChar fields
string absolutePath = data.OriginalPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
string folderpath = Path.GetDirectoryName(file);
You are right, that path D:\testDel\new/File is valid, because Windows supports both, forward slash and backslash

C# : File rename using ASP:NET MVC and IISExpress

I have a utility to rename a file in a specified directory using a certain condition. Running the code using a console application works well and the file is renamed appropriately. However, when I attempt the same in a web application the file is not getting renamed. I am using VS2017 Development Server for the web application debugging.
What am I missing?
Using the console application code as below the file successfully gets renamed :
Rename method:
public static string AddSuffix(string filename, string suffix)
{
string fDir = Path.GetDirectoryName(filename);
string fName = Path.GetFileNameWithoutExtension(filename);
string fExt = Path.GetExtension(filename);
string renamedFilePath = Path.Combine(fDir, String.Concat(fName, suffix, fExt));
return renamedFilePath;
}
Usage in main program:
static void Main(string[] args)
{
string batchperiod = "_70_";
string realPath = #"C:\Users\myuser\source\repos\Solution\Project\BatchIn";
IEnumerable<string> fileList = Directory.EnumerateFiles(realPath);
var CurrentBatchName = (from file in fileList
let fileName = Path.GetFileName(file)
where fileName.Contains(batchperiod)
select fileName).FirstOrDefault();
string absolutePath = (#"C:\Users\myuser\source\repos\Solution\Project\BatchIn\" + CurrentBatchName);
string newPath = Helpers.AddSuffix(absolutePath, String.Format("({0})", Helpers.parameters.IsProcessed));
System.IO.FileInfo fi = new System.IO.FileInfo(absolutePath);
if (fi.Exists)
{
fi.MoveTo(newPath);
}
}
With this code the file is successfully renamed from
GL_Export_70_201907081058.xml
to
GL_Export_70_201907081058(P).xml
The only difference using web application is that the absolutePath is stored in a Session variable .. its derived from a preceding operation/ActionResult :
var absolutePath = (#"C:\Users\myuser\source\repos\Solution\Project\BatchIn\" + CurrentBatchName);
files.FileName = CurrentBatchName;
Session["AbsoluteBatchPath"] = absolutePath;
and later invoked in another ActionResult as :
var sourceFile = Convert.ToString(Session["AbsoluteBatchPath"]);
string newPath = AddSuffix(sourceFile, String.Format("({0})", parameters.IsProcessed));
System.IO.FileInfo fi = new System.IO.FileInfo(sourceFile);
if (fi.Exists)
{
// Move file with a new name. Hence renamed.
fi.MoveTo(newPath);
}
What am I missing?
I do suspect there are some permissions I may need to configure when attempting the rename using the Visual Studio Development Server.
Your code see perfect there is no missing ,debug and check whether in MVC your code entered fi.exist if condition..
Please confirmed the same

How to convert a local file path in PC to a Network Relative or UNC path?

String machineName = System.Environment.MachineName;
String filePath = #"E:\folder1\folder2\file1";
int a = filePath.IndexOf(System.IO.Path.DirectorySeparatorChar);
filePath = filePath.Substring(filePath.IndexOf(System.IO.Path.DirectorySeparatorChar) +1);
String networdPath = System.IO.Path.Combine(string.Concat(System.IO.Path.DirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar), machineName, filePath);
Console.WriteLine(networdPath);
I wrote the above code using String.Concat and Path.Combine to get network path. But it is just a workaround and not a concrete solution and may fail.
Is there a concrete solution for getting a network path?
You are assuming that your E:\folder1 local path is shared as \\mypc\folder1, which in general is not true, so I doubt a general method that does what you want to do exists.
You are on the right path in implementing what you are trying to achieve. You can get more help from System.IO.Path; see Path.GetPathRoot on MSDN for returned values according to different kind of path in input
string GetNetworkPath(string path)
{
string root = Path.GetPathRoot(path);
// validate input, in your case you are expecting a path starting with a root of type "E:\"
// see Path.GetPathRoot on MSDN for returned values
if (string.IsNullOrWhiteSpace(root) || !root.Contains(":"))
{
// handle invalid input the way you prefer
// I would throw!
throw new ApplicationException("be gentle, pass to this function the expected kind of path!");
}
path = path.Remove(0, root.Length);
return Path.Combine(#"\\myPc", path);
}

Get folder on in same directory as App domain path

I have an asp.net web app and i need to get the string path of a folder in the same directory as my web app.
Currently im using this code to get the add domain path.
string appPath = HttpRuntime.AppDomainAppPath;
Which returns "c:/path/webapp", i need "c:/path/folder".
Thanks.
If you'd like a more generic approach that doesn't require knowing the starting folder:
//NOTE: using System.IO;
String startPath = Path.GetDirectoryName(HttpRuntime.AppDomainAppPath);
Int32 pos = startPath.LastIndexOf(Path.DirectorySeparatorChar);
String newPath = Path.Combine(startPath.Substring(0, pos), "folder"); //replace "folder" if it's really something else, of course
This way, whatever directory your web app is running from, you can get it, reduce it by one level, and tack on "folder" to get your new sibling directory.
You can use String.Replace method.
Returns a new string in which all occurrences of a specified string in
the current instance are replaced with another specified string.
string appPath = HttpRuntime.AppDomainAppPath;
appPath = appPath.Replace("webapp", "folder");
Here is a DEMO.
Thanks to DonBoitnott comments, here is the right answer;
string appPath = #"C:\mydir\anotherdir\webapp\thirddir\webapp";
int LastIndex = appPath.LastIndexOf("webapp", StringComparison.InvariantCulture);
string RealappPath = Path.Combine(appPath.Substring(0, LastIndex), "folder");
Console.WriteLine(RealappPath);
This will print;
C:\mydir\anotherdir\webapp\thirddir\folder

How to navigate a few folders up?

One option would be to do System.IO.Directory.GetParent() a few times. Is there a more graceful way of travelling a few folders up from where the executing assembly resides?
What I am trying to do is find a text file that resides one folder above the application folder. But the assembly itself is inside the bin, which is a few folders deep in the application folder.
Other simple way is to do this:
string path = #"C:\Folder1\Folder2\Folder3\Folder4";
string newPath = Path.GetFullPath(Path.Combine(path, #"..\..\"));
Note This goes two levels up. The result would be:
newPath = #"C:\Folder1\Folder2\";
Additional Note
Path.GetFullPath normalizes the final result based on what environment your code is running on windows/mac/mobile/...
if c:\folder1\folder2\folder3\bin is the path then the following code will return the path base folder of bin folder
//string directory=System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString());
string directory=System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString();
ie,c:\folder1\folder2\folder3
if you want folder2 path then you can get the directory by
string directory = System.IO.Directory.GetParent(System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString()).ToString();
then you will get path as c:\folder1\folder2\
You can use ..\path to go one level up, ..\..\path to go two levels up from path.
You can use Path class too.
C# Path class
This is what worked best for me:
string parentOfStartupPath = Path.GetFullPath(Path.Combine(Application.StartupPath, #"../"));
Getting the 'right' path wasn't the problem, adding '../' obviously does that, but after that, the given string isn't usable, because it will just add the '../' at the end.
Surrounding it with Path.GetFullPath() will give you the absolute path, making it usable.
public static string AppRootDirectory()
{
string _BaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
return Path.GetFullPath(Path.Combine(_BaseDirectory, #"..\..\"));
}
Maybe you could use a function if you want to declare the number of levels and put it into a function?
private String GetParents(Int32 noOfLevels, String currentpath)
{
String path = "";
for(int i=0; i< noOfLevels; i++)
{
path += #"..\";
}
path += currentpath;
return path;
}
And you could call it like this:
String path = this.GetParents(4, currentpath);
C#
string upTwoDir = Path.GetFullPath(Path.Combine(System.AppContext.BaseDirectory, #"..\..\"));
The following method searches a file beginning with the application startup path (*.exe folder). If the file is not found there, the parent folders are searched until either the file is found or the root folder has been reached. null is returned if the file was not found.
public static FileInfo FindApplicationFile(string fileName)
{
string startPath = Path.Combine(Application.StartupPath, fileName);
FileInfo file = new FileInfo(startPath);
while (!file.Exists) {
if (file.Directory.Parent == null) {
return null;
}
DirectoryInfo parentDir = file.Directory.Parent;
file = new FileInfo(Path.Combine(parentDir.FullName, file.Name));
}
return file;
}
Note: Application.StartupPath is usually used in WinForms applications, but it works in console applications as well; however, you will have to set a reference to the System.Windows.Forms assembly. You can replace Application.StartupPath by
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) if you prefer.
I use this strategy to find configuration and resource files. This allows me to share them for multiple applications or for Debug and Release versions of an application by placing them in a common parent folder.
Hiding a looped call to Directory.GetParent(path) inside an static method is the way to go.
Messing around with ".." and Path.Combine will ultimately lead to bugs related to the operation system or simply fail due to mix up between relative paths and absolute paths.
public static class PathUtils
{
public static string MoveUp(string path, int noOfLevels)
{
string parentPath = path.TrimEnd(new[] { '/', '\\' });
for (int i=0; i< noOfLevels; i++)
{
parentPath = Directory.GetParent(parentPath ).ToString();
}
return parentPath;
}
}
this may help
string parentOfStartupPath = Path.GetFullPath(Path.Combine(Application.StartupPath, #"../../")) + "Orders.xml";
if (File.Exists(parentOfStartupPath))
{
// file found
}
If you know the folder you want to navigate to, find the index of it then substring.
var ind = Directory.GetCurrentDirectory().ToString().IndexOf("Folderame");
string productFolder = Directory.GetCurrentDirectory().ToString().Substring(0, ind);
I have some virtual directories and I cannot use Directory methods. So, I made a simple split/join function for those interested. Not as safe though.
var splitResult = filePath.Split(new[] {'/', '\\'}, StringSplitOptions.RemoveEmptyEntries);
var newFilePath = Path.Combine(filePath.Take(splitResult.Length - 1).ToArray());
So, if you want to move 4 up, you just need to change the 1 to 4 and add some checks to avoid exceptions.
Path parsing via System.IO.Directory.GetParent is possible, but would require to run same function multiple times.
Slightly simpler approach is to threat path as a normal string, split it by path separator, take out what is not necessary and then recombine string back.
var upperDir = String.Join(Path.DirectorySeparatorChar, dir.Split(Path.DirectorySeparatorChar).SkipLast(2));
Of course you can replace 2 with amount of levels you need to jump up.
Notice also that this function call to Path.GetFullPath (other answers in here) will query whether path exists using file system. Using basic string operation does not require any file system operations.

Categories