Path functions for URL - c#

I want to use functions of Path class (GetDirectoryName, GetFileName, Combine,etc.) with paths in URL format with slash (/).
Example of my path:
"xxx://server/folder1/folder2/file"
I tried to do the job with Path functions and in the end just replaced the separator.
I've found that the GetDirectoryName function does not correctly replace the slashes:
Path.GetDirectoryName(#"xxx://server/folder/file") -> #"xxx:\server\folder"
Like you see one slash is lost.
How can I cause the Path functions to use the 'alternative' separator?
Can I use another class with the same functionality?

I'm afraid GetDirectoryName, GetFileName, Combine,etc. use Path.DirectorySeparatorChar in the definition and you want Path.AltDirectorySeparatorChar.
And since Path is a sealed class, I think the only way to go about is string replacement.You can replace Path.DirectorySeparatorChar('\') with Path.AltDirectorySeparatorChar('/') and Path.VolumeSeparatorChar(':') with ":/"

For GetDirectoryName(), you can use
pageRoot = uri.Remove(uri.LastIndexOf('/') + 1);

Have you considered using a combination of System.Uri, System.UriBuilder, and (if necessary) custom System.UriParser subclass(es)?

If the URI is a local file URI of the form file://whatever then you can call string path = new Uri(whatever).LocalPath and call the Path methods on it. If you cannot guarantee the Uri is to a local path, you cannot guarantee components of the Uri correspond to machines, folders, files, extensions, use directories, separator characters, or anything else.

Long time after...I was looking for a solution and found this topic, so i decided to make my (very simple) code
string dirRootUpdate = string.Empty;
string fileNameupdate = string.Empty;
string pathToGetUpdate = string.Empty;
string[] _f = Properties.Settings.Default.AutoUpdateServerUrl.Split('/');
for (int i = 0; i < _f.Count() - 1; i++)
{
dirRootUpdate += _f[i];
if (i == 0) // is the first one
{
dirRootUpdate += "/";
}
else if (i != _f.Count() - 2) // not the last one ?
{
dirRootUpdate += "/";
}
}
fileNameupdate = _f[_f.Count() - 1];
the setting "Properties.Settings.Default.AutoUpdateServerUrl" contains the string to be verified
Works fine, may require some refination to look better.
Hope could help someone

Related

How can I get a part/subdomain of my URL in C#?

I have a URL like the following
http://yellowcpd.testpace.net
How can I get yellowcpd from this? I know I can do that with string parsing, but is there a builtin way in C#?
Assuming your URLs will always be testpace.net, try this:
var subdomain = Request.Url.Host.Replace("testpace.net", "").TrimEnd('.');
It'll just give you the non-testpace.net part of the Host. If you don't have Request.Url.Host, you can do new Uri(myString).Host instead.
try this
string url = Request.Url.AbsolutePath;
var myvalues= url.Split('.');
How can I get yellowcpd from this? I know I can do that with string
parsing, but is there a builtin way in C#?
.Net doesn't provide a built-in feature to extract specific parts from Uri.Host. You will have to use string manipulation or a regular expression yourself.
The only constant part of the domain string is the TLD. The TLD is the very last bit of the domain string, eg .com, .net, .uk etc. Everything else under that depends on the particular TLD for its position (so you can't assume the next to last part is the "domain name" as, for .co.uk it would be .co
This fits the bill.
Split over two lines:
string rawURL = Request.Url.Host;
string domainName = rawURL .Split(new char[] { '.', '.' })[1];
Or over one:
string rawURL = Request.Url.Host.Split(new char[] { '.', '.' })[1];
The simple answer to your question is no there isn't a built in method to extract JUST the sub-domain. With that said this is the solution that I use...
public enum GetSubDomainOption
{
ExcludeWWW,
IncludeWWW
};
public static class Extentions
{
public static string GetSubDomain(this Uri uri,
GetSubDomainOption getSubDomainOption = GetSubDomainOption.IncludeWWW)
{
var subdomain = new StringBuilder();
for (var i = 0; i < uri.Host.Split(new char[]{'.'}).Length - 2; i++)
{
//Ignore any www values of ExcludeWWW option is set
if(getSubDomainOption == GetSubDomainOption.ExcludeWWW && uri.Host.Split(new char[]{'.'})[i].ToLowerInvariant() == "www") continue;
//I use a ternary operator here...this could easily be converted to an if/else if you are of the ternary operators are evil crowd
subdomain.Append((i < uri.Host.Split(new char[]{'.'}).Length - 3 &&
uri.Host.Split(new char[]{'.'})[i+1].ToLowerInvariant() != "www") ?
uri.Host.Split(new char[]{'.'})[i] + "." :
uri.Host.Split(new char[]{'.'})[i]);
}
return subdomain.ToString();
}
}
USAGE:
var subDomain = Request.Url.GetSubDomain(GetSubDomainOption.ExcludeWWW);
or
var subDomain = Request.Url.GetSubDomain();
I currently have the default set to include the WWW. You could easilly reverse this by switching the optional parameter value in the GetSubDomain() method.
In my opinion this allows for an option that looks nice in code and without digging in appears to be 'built-in' to c#. Just to confirm your expectations...I tested three values and this method will always return just the "yellowcpd" if the exclude flag is used.
www.yellowcpd.testpace.net
yellowcpd.testpace.net
www.yellowcpd.www.testpace.net
One assumption that I use is that...splitting the hostname on a . will always result in the last two values being the domain (i.e. something.com)
As others have pointed out, you can do something like this:
var req = new HttpRequest(filename: "search", url: "http://www.yellowcpd.testpace.net", queryString: "q=alaska");
var host = req.Url.Host;
var yellow = host.Split('.')[1];
The portion of the URL you want is part of the hostname. You may hope to find some method that directly addresses that portion of the name, e.g. "the subdomain (yellowcpd) within TestSpace", but this is probably not possible, because the rules for valid host names allow for any number of labels (see Valid Host Names). The host name can have any number of labels, separated by periods. You will have to add additional restrictions to get what you want, e.g. "Separate the host name into labels, discard www if present and take the next label".

Getting string after a specific slash

I have a string and I want to get whatever is after the 3rd slash so.
I don't know of any other way I can do this, I don't really want to use regex if I dont need it.
http://www.website.com/hello for example would be hello
I have used str.LastIndexOf('/') before like:
string str3 = str.Substring(str.LastIndexOf('/') + 1);
However I am still trying to figure out how to do this for a slash that is not the first or last
string s = "some/string/you/want/to/split";
string.Join("/", s.Split('/').Skip(3).ToArray());
As suggested by C.Evenhuis, you should rely on the native System.Uri class:
string url = "http://stackoverflow.com/questions/20213490/getting-string-after-a-specific-slash"
Uri asUri = new Uri(url);
string result = asUri.LocalPath;
Console.WriteLine(result);
(live at http://csharpfiddle.com/LlLbriBm)
This will output:
/questions/20213490/getting-string-after-a-specific-slash
If you don't want the first / in the result, simply use:
string url = "http://stackoverflow.com/questions/20213490/getting-string-after-a-specific-slash"
Uri asUri = new Uri(url);
string result = asUri.LocalPath.TrimStart('/');
Console.WriteLine(result);
You should take a look in the System.Uri class documentation. There's plenty of property that can you can play with, depending on what you want to actually keep in the url (url parameters, hashtag, etc.)
If you're manipulating URLs, then use the Uri class instead of rolling your own.
But if you want to do it manually for educational reasons, you could do something like this:
int startPos = 0;
for(int i = 0; i < 3; i++)
{
startPos = s.IndexOf('/', startPos)+1;
}
var stringOfInterest = s.Substring(startPos);
There are lots of ways this might fail if the string isn't in the form you expect, so it's just an example to get you started.
Although this is premature optimisation, this sort of approach is more efficient than smashing the whole string into components and putting them back together again.

How to get the second to last directory in a path string in C#

For example,
string path = #"C:\User\Desktop\Drop\images\";
I need to get only #"C:\User\Desktop\Drop\
Is there any easy way of doing this?
You can use the Path and Directory classes:
DirectoryInfo parentDir = Directory.GetParent(Path.GetDirectoryName(path));
string parent = parentDir.FullName;
Note that you would get a different result if the path doesn't end with the directory-separator char \. Then images would be understood as filename and not as directory.
You can also use a subsequent call of Path.GetDirectoryName
string parent = Path.GetDirectoryName(Path.GetDirectoryName(path));
This behaviour is documented here:
Because the returned path does not include the DirectorySeparatorChar
or AltDirectorySeparatorChar, passing the returned path back into the
GetDirectoryName method will result in the truncation of one folder
level per subsequent call on the result string. For example, passing
the path "C:\Directory\SubDirectory\test.txt" into the
GetDirectoryName method will return "C:\Directory\SubDirectory".
Passing that string, "C:\Directory\SubDirectory", into
GetDirectoryName will result in "C:\Directory".
This will return "C:\User\Desktop\Drop\" e.g. everything but the last subdir
string path = #"C:\User\Desktop\Drop\images";
string sub = path.Substring(0, path.LastIndexOf(#"\") + 1);
Another solution if you have a trailing slash:
string path = #"C:\User\Desktop\Drop\images\";
var splitedPath = path.Split('\\');
var output = String.Join(#"\", splitedPath.Take(splitedPath.Length - 2));
var parent = "";
If(path.EndsWith(System.IO.Path.DirectorySeparatorChar) || path.EndsWith(System.IO.Path.AltDirectorySeparatorChar))
{
parent = Path.GetDirectoryName(Path.GetDirectoryName(path));
parent = Directory.GetParent(Path.GetDirectoryName(path)).FullName;
}
else
parent = Path.GetDirectoryName(path);
As i commented GetDirectoryName is self collapsing it returns path without tralling slash - allowing to get next directory.Using Directory.GetParent for then clouse is also valid.
Short Answer :)
path = Directory.GetParent(Directory.GetParent(path)).ToString();
Example on the bottom of the page probably will help:
http://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname(v=vs.110).aspx
using System;
namespace Programs
{
public class Program
{
public static void Main(string[] args)
{
string inputText = #"C:\User\Desktop\Drop\images\";
Console.WriteLine(inputText.Substring(0, 21));
}
}
}
Output:
C:\User\Desktop\Drop\
There is probably some simple way to do this using the File or Path classes, but you could also solve it by doing something like this (Note: not tested):
string fullPath = "C:\User\Desktop\Drop\images\";
string[] allDirs = fullPath.split(System.IO.Path.PathSeparator);
string lastDir = allDirs[(allDirs.length - 1)];
string secondToLastDir= allDirs[(allDirs.length - 2)];
// etc...

Shorthand way to remove last forward slash and trailing characters from string

If I have the following string:
/lorem/ipsum/dolor
and I want this to become:
/lorem/ipsum
What is the short-hand way of removing the last forward slash, and all characters following it?
I know how I can do this by spliting the string into a List<> and removing the last item, and then joining, but is there a shorter way of writing this?
My question is not URL specific.
You can use Substring() and LastIndexOf():
str = str.Substring(0, str.LastIndexOf('/'));
EDIT (suggested comment)
To prevent any issues when the string may not contain a /, you could use something like:
int lastSlash = str.LastIndexOf('/');
str = (lastSlash > -1) ? str.Substring(0, lastSlash) : str;
Storing the position in a temp-variable would prevent the need to call .LastIndexOf('/') twice, but it could be dropped in favor of a one-line solution instead.
If there is '/' at the end of the url, remove it.
If not; just return the original one.
var url = this.Request.RequestUri.ToString();
url = url.EndsWith("/") ? url.Substring(0, url.Length - 1) : url;
url += #"/mycontroller";
You can do something like str.Remove(str.LastIndexOf("/")), but there is no built-in method to do what you want.
Edit: you could also use the Uri object to traverse directories, although it does not give exactly what you want:
Uri baseUri = new Uri("http://domain.com/lorem/ipsum/dolor");
Uri myUri = new Uri(baseUri, ".");
// myUri now contains http://domain.com/lorem/ipsum/
One simple way would be
String s = "domain.com/lorem/ipsum/dolor";
s = s.Substring(0, s.LastIndexOf('/'));
Console.WriteLine(s);
Another maybe
String s = "domain.com/lorem/ipsum/dolor";
s = s.TrimEnd('/');
Console.WriteLine(s);
You can use the regex /[^/]*$ and replace with the empty string:
var fixed = new Regex("/[^/]*$").Replace("domain.com/lorem/ipsum/dolor", "")
But it's probably overkill here. #newfurniturey's answer of Substring with LastIndexOf is probably best.
I like to create a String Extension for stuff like this:
/// <summary>
/// Returns with suffix removed, if present
/// </summary>
public static string TrimIfEndsWith(
this string value,
string suffix)
{
return
value.EndsWith(suffix) ?
value.Substring(0, value.Length - suffix.Length) :
value;
}
You can then use like this:
var myString = "/lorem/ipsum/dolor";
myStringClean = myString.TrimIfEndsWith("/dolor");
You now have a re-usable extension across all of your projects that can be used to remove one trailing character or multiple.
using System.IO;
mystring.TrimEnd(Path.AltDirectorySeparatorChar); // To remove "/"
mystring.TrimEnd(Path.DirectorySeparatorChar); // To remove "\"
while (input.Last() == '/' || input.Last() == '\\')
{
input = input.Substring(0, input.Length - 1);
}
Thank you #Curt for your question.
I slightly improved #newfurniturey's code, and here is my version.
if(str.Contains('/')){
str = str.Substring(0, str.LastIndexOf('/'));
}
I'm way late to the party, but if you're using C# 8.0+, another clean approach would be to use the range operator:
if (urlStr.EndsWith("/")) urlStr = urlStr[..^1];
If you're curious as to how this works, take a look at the spec for ranges in C#:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/ranges
tldr; urlStr[..^1] roughly translates to something along the lines of "Give me a substring comprised of the characters contained within the range of index 0 to whatever index is 1 away from the last index.".
In other words, it's similar to...
urlStr.Substring(0, urlStr.Length-1)

find string using c#?

I am trying find a string in below string.
http://example.com/TIGS/SIM/Lists/Team Discussion/DispForm.aspx?ID=1779
by using http://example.com/TIGS/SIM/Lists string. How can I get Team Discussion word from it?
Some times strings will be
http://example.com/TIGS/SIM/Lists/Team Discussion/DispForm.aspx?ID=1779
I need `Team Discussion`
http://example.com/TIGS/ALIF/Lists/Artifical Lift Discussion Forum 2/DispForm.aspx?ID=8
I need `Artifical Lift Discussion Forum 2`
If you're always following that pattern, I recommend #Justin's answer. However, if you want a more robust method, you can always couple the System.Uri and Path.GetDirectoryName methods, then perform a String.Split. Like this example:
String url = #"http://example.com/TIGS/SIM/Lists/Team Discussion/DispForm.aspx?ID=1779";
System.Uri uri = new System.Uri(url);
String dir = Path.GetDirectoryName(uri.AbsolutePath);
String[] parts = dir.Split(new[]{ Path.DirectorySeparatorChar });
Console.WriteLine(parts[parts.Length - 1]);
The only major problem, however, is you're going to wind up with a path that's been "encoded" (i.e. your space is now going to be represented by a %20)
This solution will get you the last directory of your URL regardless of how many directories are in your URL.
string[] arr = s.Split('/');
string lastPart = arr[arr.Length - 2];
You could combine this solution into one line, however it would require splitting the string twice, once for the values, the second for the length.
If you wanted to see a regular expression example:
string input = "http://example.com/TIGS/SIM/Lists/Team Discussion/DispForm.aspx?ID=1779";
string given = "http://example.com/TIGS/SIM/Lists";
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(given + #"\/(.+)\/");
System.Text.RegularExpressions.Match match = regex.Match(input);
Console.WriteLine(match.Groups[1]); // Team Discussion
Here's a simple approach, assuming that your URL always has the same number of slashes before the are you want:
var value = url.Split(new[]{'/'}, StringSplitOptions.RemoveEmptyEntries)[5];
Here is another solution that provides the following advantages:
Does not require the use of regular expressions.
Does not require a certain 'count' of slashes be present (indexing based of a specific number). I consider this a key benefit because it makes the code less likely to fail if some part of the URL changes. Ultimately it is best to base your parsing logic off which part of the text's structure you consider least likely to change.
This method, however, DOES rely on the following assumptions, which I consider to be the least likely to change:
URL must have "/Lists/" right before target text.
URL must have "/" right after target text.
Basically, I just split the string twice, using text that I expect to be surrounding the area I am interested in.
String urlToSearch = "http://example.com/TIGS/SIM/Lists/Team Discussion/DispForm.aspx";
String result = "";
// First, get everthing after "/Lists/"
string[] temp1 = urlToSearch.Split(new String[] { "/Lists/" }, StringSplitOptions.RemoveEmptyEntries);
if (temp1.Length > 1)
{
// Next, get everything before the first "/"
string[] temp2 = temp1[1].Split(new String[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
result = temp2[0];
}
Your answer will then be stored in the 'result' variable.

Categories