In my IHttpHandler class (for an .ashx page), I want to search a directory for certain files, and return relative urls. I can get the files, no problem:
string dirPath = context.Server.MapPath("~/mydirectory");
string[] files = Directory.GetFiles(dirPath, "*foo*.txt");
IEnumerable<string> relativeUrls = files.Select(f => WHAT GOES HERE? );
What is the easiest way to convert file paths to relative urls? If I were in an aspx page, I could say this.ResolveUrl(). I know I could do some string parsing and string replacement to get the relative url, but is there some built-in method that will take care of all of that for me?
Edit: To clarify, without doing my own string parsing, how do I go from this:
"E:\Webs\WebApp1\WebRoot\mydirectory\foo.txt"
to this:
"/mydirectory/foo.txt"
I'm looking for an existing method like:
public string GetRelativeUrl(string filePath) { }
I can imagine a lot of people having this question... My solution is:
public static string ResolveRelative(string url)
{
var requestUrl = context.Request.Url;
string baseUrl = string.Format("{0}://{1}{2}{3}",
requestUrl.Scheme, requestUrl.Host,
(requestUrl.IsDefaultPort ? "" : ":" + requestUrl.Port),
context.Request.ApplicationPath);
if (toresolve.StartsWith("~"))
{
return baseUrl + toresolve.Substring(1);
}
else
{
return new Uri(new Uri(baseUrl), toresolve).ToString();
}
}
update
Or from filename to virtual path (haven't tested it; you might need some code similar to ResoveRelative above as well... let me know if it works):
public static string GetUrl(string filename)
{
if (filename.StartsWith(context.Request.PhysicalApplicationPath))
{
return context.Request.ApplicationPath +
filename.Substring(context.Request.PhysicalApplicationPath.Length);
}
else
{
throw new ArgumentException("Incorrect physical path");
}
}
try System.Web.Hosting.HostingEnvironment.MapPath method, its static and can be accessed everywhere in web application.
Related
I have a URL and from which i need to get names after "bussiness" and Before the Page Name i.e. "paradise-villas-little.aspx" from below URL.
http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx
I am not getting how can i get this. i have tried the RawUrl, but it fetched the full. Please help me how can i do this.
UPDATE: This is a type of URL, i need to check it for dynamically.
You can create a little helper, and parse the URL from it's Uri Segments :
public static class Helper
{
public static IEnumerable<String> ExtractSegments(this Uri uri, String exclusiveStart)
{
bool startFound = false;
foreach (var seg in uri.Segments.Select(i => i.Replace(#"/","")))
{
if (startFound == false)
{
if (seg == exclusiveStart)
startFound = true;
}
else
{
if (!seg.Contains("."))
yield return seg;
}
}
}
}
And call it like this :
Uri uri = new Uri(#"http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx");
var found = uri.ExtractSegments("bussiness").ToList();
Then found contains "accommo" and "resort", and this method is extensible to any URL length, with or without file name at the end.
Nothing sophisticated in this implementation, just regular string operations:
string url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
string startAfter = "business";
string pageName = "paradise-villas-little.aspx";
char delimiter = '/'; //not platform specific
var from = url.IndexOf(startAfter) + startAfter.Length + 1;
var to = url.Length - from - pageName.Length - 1;
var strings = url.Substring(from, to).Split(delimiter);
You may want to add validations though.
You have to use built-in string methods. The best is to use String Split.
String url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
String[] url_parts = url.Split('/'); //Now you have all the parts of the URL all folders and page. Access the folder names from string array.
Hope this helps
how to access a text file based on its prefix
var str = GrvGeneral.Properties.Resources.ResourceManager.GetString(configFile + "_Nlog_Config");
var str1 = GrvGeneral.Properties.Resources.ResourceManager.GetObject(configFile + "_Nlog_Config");
where the configfile is the prefix of the resourcefile A & B .
Based on the configfile contents (prefix) the resource file A & B has to be accessed .
Use the DirectoryInfo class (documentation). Then you can call the GetFiles with a search pattern.
string searchPattern = "abc*.*"; // This would be for you to construct your prefix
DirectoryInfo di = new DirectoryInfo(#"C:\Path\To\Your\Dir");
FileInfo[] files = di.GetFiles(searchPattern);
Edit: If you have a way of constructing the actual file name you're looking for, you can go directly to the FileInfo class, otherwise you'll have to iterate through the matching files in my previous example.
Your question is rather vague...but it sounds like you want to get the text contents of an embedded resource. Usually you would do that using Assembly.GetManifestResourceStream. You can always use LINQ along with Assembly.GetManifestResourceNames() to find the name of an embedded file matching a pattern.
The ResourceManager class is more often used for automatically retrieving localized string resources, such as labels and error messages in different languages.
update: A more generalized example:
internal static class RsrcUtil {
private static Assembly _thisAssembly;
private static Assembly thisAssembly {
get {
if (_thisAssembly == null) { _thisAssembly = typeof(RsrcUtil).Assembly; }
return _thisAssembly;
}
}
internal static string GetNlogConfig(string prefix) {
return GetResourceText(#"Some\Folder\" + prefix + ".nlog.config");
}
internal static string FindResource(string pattern) {
return thisAssembly.GetManifestResourceNames()
.FirstOrDefault(x => Regex.IsMatch(x, pattern));
}
internal static string GetResourceText(string resourceName) {
string result = string.Empty;
if (thisAssembly.GetManifestResourceInfo(resourceName) != null) {
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) {
result = new StreamReader(stream).ReadToEnd();
}
}
return result;
}
}
Using the example:
string aconfig = RsrcUtil.GetNlogConfig("a");
string bconfigname = RsrcUtil.FindResource(#"b\.\w+\.config$");
string bconfig = RsrcUtil.GetResourceText(bconfigname);
Thanks all for the suggestion made for my earlier query regarding to the getlist and copy.
I have only one issue here
String realname= "test" //am getting this value from Db,so is this anyway i can use like that rather than
string realname="test"//i know i can do like string realname=""+Dbvalue+"";
Am just wondering why it doesn't return anyvalue if don't use "*" ?
class Program
{
static void Main(string[] args)
{
var getfiles = new fileshare.Program();
string realname = "*test*";
foreach (var file in getfiles.GetFileList(realname))
{getfiles.copytolocal(file.FullName); }
}
private FileInfo[] GetFileList(string pattern)
{
var di = new DirectoryInfo(#"\\testserv01\dev");
return di.GetFiles(pattern);
}
private void copytolocal(string filename)
{
string nameonly = Path.GetFileName(filename);
File.Copy(filename,Path.Combine(#"c:\",nameonly));
}
}
Thanks in Advance.
I know this is a bit glib but really you need to start looking at the documentation of the functionality you are using: http://msdn.microsoft.com/en-us/library/8he88b63.aspx
that said the reason is that * is a wildcard - if you use "test" then you will only retrieve exact matches for "test".
the link above has some more examples.
I have to get the path excluding the relative path from the full path,
say
The relative path is ,C:\User\Documents\
fullpath ,C:\User\Documents\Test\Folder2\test.pdf
I want to get only the path after the relative path i.e \Test\Folder2\test.pdf
how can i achieve this.
I am using C# as the programming language
You are not talking about relative, so i will call it partial path.
If you can be sure that the partial path is part of your full path its a simple string manipulation:
string fullPath = #"C:\User\Documents\Test\Folder2\test.pdf";
string partialPath = #"C:\User\Documents\";
string resultingPath = fullPath.Substring(partialPath.Length);
This needs some error checking though - it will fail when either fullPath or partialPath is null or both paths have the same length.
Hmmmm, but what if the case is different? Or one of the path uses short-names for its folders? The more complete solution would be...
public static string GetRelativePath(string fullPath, string containingFolder,
bool mustBeInContainingFolder = false)
{
var file = new Uri(fullPath);
if (containingFolder[containingFolder.Length - 1] != Path.DirectorySeparatorChar)
containingFolder += Path.DirectorySeparatorChar;
var folder = new Uri(containingFolder); // Must end in a slash to indicate folder
var relativePath =
Uri.UnescapeDataString(
folder.MakeRelativeUri(file)
.ToString()
.Replace('/', Path.DirectorySeparatorChar)
);
if (mustBeInContainingFolder && relativePath.IndexOf("..") == 0)
return null;
return relativePath;
}
To expand on Jan's answer, you could create an extension method on the string class (or the Path class if you wanted) such as:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static string GetPartialPath(this string fullPath, string partialPath)
{
return fullPath.Substring(partialPath.Length)
}
}
}
And then use:
using ExtensionMethods;
string resultingPath = string.GetPartialPath(partialPath);
I haven't tested that this extension method works, but it should do.
If I have managed to locate and verify the existence of a file using Server.MapPath and I now want to send the user directly to that file, what is the fastest way to convert that absolute path back into a relative web path?
Perhaps this might work:
String RelativePath = AbsolutePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);
I'm using c# but could be adapted to vb.
Wouldn't it be nice to have Server.RelativePath(path)?
well, you just need to extend it ;-)
public static class ExtensionMethods
{
public static string RelativePath(this HttpServerUtility srv, string path, HttpRequest context)
{
return path.Replace(context.ServerVariables["APPL_PHYSICAL_PATH"], "~/").Replace(#"\", "/");
}
}
With this you can simply call
Server.RelativePath(path, Request);
I know this is old but I needed to account for virtual directories (per #Costo's comment). This seems to help:
static string RelativeFromAbsolutePath(string path)
{
if(HttpContext.Current != null)
{
var request = HttpContext.Current.Request;
var applicationPath = request.PhysicalApplicationPath;
var virtualDir = request.ApplicationPath;
virtualDir = virtualDir == "/" ? virtualDir : (virtualDir + "/");
return path.Replace(applicationPath, virtualDir).Replace(#"\", "/");
}
throw new InvalidOperationException("We can only map an absolute back to a relative path if an HttpContext is available.");
}
I like the idea from Canoas. Unfortunately I had not "HttpContext.Current.Request" available (BundleConfig.cs).
I changed the methode like this:
public static string RelativePath(this HttpServerUtility srv, string path)
{
return path.Replace(HttpContext.Current.Server.MapPath("~/"), "~/").Replace(#"\", "/");
}
If you used Server.MapPath, then you should already have the relative web path. According to the MSDN documentation, this method takes one variable, path, which is the virtual path of the Web server. So if you were able to call the method, you should already have the relative web path immediately accessible.
For asp.net core i wrote helper class to get pathes in both directions.
public class FilePathHelper
{
private readonly IHostingEnvironment _env;
public FilePathHelper(IHostingEnvironment env)
{
_env = env;
}
public string GetVirtualPath(string physicalPath)
{
if (physicalPath == null) throw new ArgumentException("physicalPath is null");
if (!File.Exists(physicalPath)) throw new FileNotFoundException(physicalPath + " doesn't exists");
var lastWord = _env.WebRootPath.Split("\\").Last();
int relativePathIndex = physicalPath.IndexOf(lastWord) + lastWord.Length;
var relativePath = physicalPath.Substring(relativePathIndex);
return $"/{ relativePath.TrimStart('\\').Replace('\\', '/')}";
}
public string GetPhysicalPath(string relativepath)
{
if (relativepath == null) throw new ArgumentException("relativepath is null");
var fileInfo = _env.WebRootFileProvider.GetFileInfo(relativepath);
if (fileInfo.Exists) return fileInfo.PhysicalPath;
else throw new FileNotFoundException("file doesn't exists");
}
from Controller or service inject FilePathHelper and use:
var physicalPath = _fp.GetPhysicalPath("/img/banners/abro.png");
and versa
var virtualPath = _fp.GetVirtualPath(physicalPath);