Get host domain from URL? - c#

how to get host domain from a string URL?
GetDomain has 1 input "URL", 1 Output "Domain"
Example1
INPUT: http://support.domain.com/default.aspx?id=12345
OUTPUT: support.domain.com
Example2
INPUT: http://www.domain.com/default.aspx?id=12345
OUTPUT: www.domain.com
Example3
INPUT: http://localhost/default.aspx?id=12345
OUTPUT: localhost

You can use Request object or Uri object to get host of url.
Using Request.Url
string host = Request.Url.Host;
Using Uri
Uri myUri = new Uri("http://www.contoso.com:8080/");
string host = myUri.Host; // host is "www.contoso.com"

Try like this;
Uri.GetLeftPart( UriPartial.Authority )
Defines the parts of a URI for the Uri.GetLeftPart method.
http://www.contoso.com/index.htm?date=today --> http://www.contoso.com
http://www.contoso.com/index.htm#main --> http://www.contoso.com
nntp://news.contoso.com/123456#contoso.com --> nntp://news.contoso.com
file://server/filename.ext --> file://server
Uri uriAddress = new Uri("http://www.contoso.com/index.htm#search");
Console.WriteLine("The path of this Uri is {0}", uriAddress.GetLeftPart(UriPartial.Authority));
Demo

Use Uri class and use Host property
Uri url = new Uri(#"http://support.domain.com/default.aspx?id=12345");
Console.WriteLine(url.Host);

try following statement
Uri myuri = new Uri(System.Web.HttpContext.Current.Request.Url.AbsoluteUri);
string pathQuery = myuri.PathAndQuery;
string hostName = myuri.ToString().Replace(pathQuery , "");
Example1
Input : http://localhost:4366/Default.aspx?id=notlogin
Ouput : http://localhost:4366
Example2
Input : http://support.domain.com/default.aspx?id=12345
Output: support.domain.com

The best way, and the right way to do it is using Uri.Authority field
Load and use Uri like so :
Uri NewUri;
if (Uri.TryCreate([string with your Url], UriKind.Absolute, out NewUri))
{
Console.Writeline(NewUri.Authority);
}
Input : http://support.domain.com/default.aspx?id=12345
Output : support.domain.com
Input : http://www.domain.com/default.aspx?id=12345
output : www.domain.com
Input : http://localhost/default.aspx?id=12345
Output : localhost
If you want to manipulate Url, using Uri object is the good way to do it.
https://msdn.microsoft.com/en-us/library/system.uri(v=vs.110).aspx

var url = Regex.Match(url, #"(http:|https:)\/\/(.*?)\/");
INPUT = "https://stackoverflow.com/questions/";
OUTPUT = "https://stackoverflow.com/";

Try this
Console.WriteLine(GetDomain.GetDomainFromUrl("http://support.domain.com/default.aspx?id=12345"));
It will output support.domain.com
Or try
Uri.GetLeftPart( UriPartial.Authority )

You should construct your string as URI object and Authority property returns what you need.

public static string DownloadImage(string URL, string MetaIcon,string folder,string name)
{
try
{
WebClient oClient = new WebClient();
string LocalState = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
string storesIcons = Directory.CreateDirectory(LocalState + folder).ToString();
string path = Path.Combine(storesIcons, name + ".png");
//si la imagen no es valida ej "/icon.png"
if (!TextBoxEvent.IsValidURL(MetaIcon))
{
Uri uri = new Uri(URL);
string DownloadImage = "https://" + uri.Host + MetaIcon;
oClient.DownloadFile(new Uri(DownloadImage), path);
}
//si la imagen tiene todo ej https://www.mercadolibre.com/icon.png
else
{
oClient.DownloadFile(new Uri(MetaIcon), path);
}
return path;
}
catch (Exception ex)
{
return ex.ToString();
}
}

Here's a solution that will work for all kinds of URLs.
public string GetDomainFromUrl(string url)
{
url = url.Replace("https://", "").Replace("http://", "").Replace("www.", ""); //Remove the prefix
string[] fragments = url.Split('/');
return fragments[0];
}

it will take only domain name (www.bla.com -> bla)
no Uri required
static string GetDomainNameOnly(string s)
{
string domainOnly = "";
if (!string.IsNullOrEmpty(s))
{
if (s.Contains("."))
{
string domain = s.Substring(s.LastIndexOf('.', s.LastIndexOf('.') - 1) + 1);
string countryDomain = s.Substring(s.LastIndexOf('.'));
domainOnly = domain.Replace(countryDomain, "");
}
else
domainOnly = s;
}
return domainOnly;
}

WWW is an alias, so you don't need it if you want a domain.
Here is my litllte function to get the real domain from a string
private string GetDomain(string url)
{
string[] split = url.Split('.');
if (split.Length > 2)
return split[split.Length - 2] + "." + split[split.Length - 1];
else
return url;
}

Related

How to get the extension from ContentDisposition [duplicate]

How do I get Content-Disposition parameters I returned from WebAPI controller using WebClient?
WebApi Controller
[Route("api/mycontroller/GetFile/{fileId}")]
public HttpResponseMessage GetFile(int fileId)
{
try
{
var file = GetSomeFile(fileId)
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(new MemoryStream(file));
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = file.FileOriginalName;
/********* Parameter *************/
response.Content.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("MyParameter", "MyValue"));
return response;
}
catch(Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
}
Client
void DownloadFile()
{
WebClient wc = new WebClient();
wc.DownloadDataCompleted += wc_DownloadDataCompleted;
wc.DownloadDataAsync(new Uri("api/mycontroller/GetFile/18"));
}
void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
WebClient wc=sender as WebClient;
// Try to extract the filename from the Content-Disposition header
if (!String.IsNullOrEmpty(wc.ResponseHeaders["Content-Disposition"]))
{
string fileName = wc.ResponseHeaders["Content-Disposition"].Substring(wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 10).Replace("\"", ""); //FileName ok
/****** How do I get "MyParameter"? **********/
}
var data = e.Result; //File OK
}
I'm returning a file from WebApi controller, I'm attaching the file name in the response content headers, but also I'd like to return an aditional value.
In the client I'm able to get the filename, but how do I get the aditional parameter?
If you are working with .NET 4.5 or later, consider using the System.Net.Mime.ContentDisposition class:
string cpString = wc.ResponseHeaders["Content-Disposition"];
ContentDisposition contentDisposition = new ContentDisposition(cpString);
string filename = contentDisposition.FileName;
StringDictionary parameters = contentDisposition.Parameters;
// You have got parameters now
Edit:
otherwise, you need to parse Content-Disposition header according to it's specification.
Here is a simple class that performs the parsing, close to the specification:
class ContentDisposition {
private static readonly Regex regex = new Regex(
"^([^;]+);(?:\\s*([^=]+)=((?<q>\"?)[^\"]*\\k<q>);?)*$",
RegexOptions.Compiled
);
private readonly string fileName;
private readonly StringDictionary parameters;
private readonly string type;
public ContentDisposition(string s) {
if (string.IsNullOrEmpty(s)) {
throw new ArgumentNullException("s");
}
Match match = regex.Match(s);
if (!match.Success) {
throw new FormatException("input is not a valid content-disposition string.");
}
var typeGroup = match.Groups[1];
var nameGroup = match.Groups[2];
var valueGroup = match.Groups[3];
int groupCount = match.Groups.Count;
int paramCount = nameGroup.Captures.Count;
this.type = typeGroup.Value;
this.parameters = new StringDictionary();
for (int i = 0; i < paramCount; i++ ) {
string name = nameGroup.Captures[i].Value;
string value = valueGroup.Captures[i].Value;
if (name.Equals("filename", StringComparison.InvariantCultureIgnoreCase)) {
this.fileName = value;
}
else {
this.parameters.Add(name, value);
}
}
}
public string FileName {
get {
return this.fileName;
}
}
public StringDictionary Parameters {
get {
return this.parameters;
}
}
public string Type {
get {
return this.type;
}
}
}
Then you can use it in this way:
static void Main() {
string text = "attachment; filename=\"fname.ext\"; param1=\"A\"; param2=\"A\";";
var cp = new ContentDisposition(text);
Console.WriteLine("FileName:" + cp.FileName);
foreach (DictionaryEntry param in cp.Parameters) {
Console.WriteLine("{0} = {1}", param.Key, param.Value);
}
}
// Output:
// FileName:"fname.ext"
// param1 = "A"
// param2 = "A"
The only thing that should be considered when using this class is it does not handle parameters (or filename) without a double quotation.
Edit 2:
It can now handle file names without quotations.
You can parse out the content disposition using the following framework code:
var content = "attachment; filename=myfile.csv";
var disposition = ContentDispositionHeaderValue.Parse(content);
Then just take the pieces off of the disposition instance.
disposition.FileName
disposition.DispositionType
With .NET Core 3.1 and more the most simple solution is:
using var response = await Client.SendAsync(request);
response.Content.Headers.ContentDisposition.FileName
The value is there I just needed to extract it:
The Content-Disposition header is returned like this:
Content-Disposition = attachment; filename="C:\team.jpg"; MyParameter=MyValue
So I just used some string manipulation to get the values:
void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
WebClient wc=sender as WebClient;
// Try to extract the filename from the Content-Disposition header
if (!String.IsNullOrEmpty(wc.ResponseHeaders["Content-Disposition"]))
{
string[] values = wc.ResponseHeaders["Content-Disposition"].Split(';');
string fileName = values.Single(v => v.Contains("filename"))
.Replace("filename=","")
.Replace("\"","");
/********** HERE IS THE PARAMETER ********/
string myParameter = values.Single(v => v.Contains("MyParameter"))
.Replace("MyParameter=", "")
.Replace("\"", "");
}
var data = e.Result; //File ok
}
As #Mehrzad Chehraz said you can use the new ContentDisposition class.
using System.Net.Mime;
// file1 is a HttpResponseMessage
FileName = new ContentDisposition(file1.Content.Headers.ContentDisposition.ToString()).FileName

Split and Append string at specific point

i have use an web API
https://api.nasa.gov/planetary/earth/imagery?lon=100.75&lat=1.5&date=2014-02-01&cloud_score=True&api_key=DEMO_KEY
And display the parameters above
Method input:
imagery?lon=100.75&lat=1.5&date=2014-02-01&cloud_score=True&api_key=DEMO_KEY
Expected Output:
Method name: imagery
Parameters: lon, lat, date, cloud_score, api_key
Values: 100.75, 1.5, 2014-02-01, True, api_key
Method input:
browse?lon=100.75&lat=1.5&date=2014-02-01
Expected Output:
Method name: browse
Parameters: lon, lat, date
Values: 100.75, 1.5, 2014-02-01
Method input:
?lon=100.75&lat=1.5&date=2014-02-01
Expected Output:
Error: malformed URL
Method input:
browse?lon=100.75&lat=1.5&date
Expected Output:
Error: malformed URL
Method input:
browse?
Expected Output:
Error: malformed URL
Method input:
browse
Expected Output:
Method name: browse
i need to split the API from any word before the Question Mark
Here is my code so far
if (S == null || S=="")
{
lbOutput.Text = "Please dont leave Fields Empty";
}
else
{
if (S.Contains("?") || S.Contains("&"))
{
lbOutput.Text = "Output";
string url = txtInput.Text;
string querystring = url.Substring(url.IndexOf("?"));
System.Collections.Specialized.NameValueCollection parameters =
System.Web.HttpUtility.ParseQueryString(querystring);
//lbOutput.Text = querystring;
lbLonRes.Text = System.Web.HttpUtility.ParseQueryString(querystring).Get("lon");
lbLatRes.Text = System.Web.HttpUtility.ParseQueryString(querystring).Get("lat");
lbDateRes.Text = System.Web.HttpUtility.ParseQueryString(querystring).Get("date");
lbCloudRes.Text = System.Web.HttpUtility.ParseQueryString(querystring).Get("cloud_score");
lbAPIRes.Text = System.Web.HttpUtility.ParseQueryString(querystring).Get("api_key");
}
if(S.Contains(" "))
{
lbOutput.Text = "Error: malformed URL";
lbLonRes.Text = "";
lbLatRes.Text = "";
lbDateRes.Text = "";
lbCloudRes.Text = "";
lbAPIRes.Text = "";
}
}
You can use the Segments property of the Uri class to get the method since it will be the last segment.
You need a reference to System.Net.HttpFormatting to use this code, it will remove your dependence on System.Web
using System;
using System.Net.Http;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
string url = "https://api.nasa.gov/planetary/earth/imagery?lon=100.75&lat=1.5&date=2014-02-01&cloud_score=True&api_key=DEMO_KEY";
Uri theUri = new Uri(url);
string method = theUri.Segments[theUri.Segments.Length - 1];
Console.WriteLine("Method: {method}");
var qa = theUri.ParseQueryString();
foreach (string item in qa.AllKeys)
{
Console.WriteLine($"key: {item}, value: {qa[item]}");
}
Console.ReadKey();
}
}
}

How to check valid URL address?

I have simple code , wich get url path and redirect to this url:
private void Redirect(String path)
{
Uri validatedUri = null;
var result = Uri.TryCreate(HelpURL + path, UriKind.Absolute, out validatedUri);
if (result&&validatedUri!=null)
{
var wellFormed = Uri.IsWellFormedUriString(HelpURL + path, UriKind.Absolute);
if(wellFormed)
{
Response.Write("Redirect to: " + HelpURL + path);
Response.AddHeader("REFRESH", "1;URL=" + HelpURL + path);
}
else //error
{
Response.Write(String.Format("Validation Uri error!", path));
}
}
else
{
Response.Write(String.Format("Validation Uri error!", path));
}
}
Example of Url:http://web-server/SomeSystemindex.html. It is not valid address, but:
at my code result is true, wellFormed is true too!
How to validate url address?
P.S. HelpUrl+path=http://web-server/SomeSystemindex.html for this case. Where HelpUrl is 'http://web-server/SomeSystem', and path=index.html
P.P.S. I do as Martin says- create connection and check the status code.
HttpWebRequest req = WebRequest.Create(HelpURL + path) as HttpWebRequest;
req.UseDefaultCredentials = true;
req.PreAuthenticate = true;
req.Credentials = CredentialCache.DefaultCredentials;
var statusCode= ((HttpWebResponse)req.GetResponse()).StatusCode;
if (statusCode == HttpStatusCode.NotFound)
isValid = false;
else if (statusCode == HttpStatusCode.Gone)
isValid = false;
else
{
isValid = true;
}
As far as I know, the only way to determine whether an address is valid or not, is by opening a connection. If the connection lives, the address is valid. If not, the connection is not valid. There are some tricks to filter out bad URL's, but to know whether an adress is valid, you need to open a connection.
An example has already been posted on StackOverflow here
Or here:
URL url;
URL wrongUrl;
try {
url = new URL("http://google.com");
wrongUrl = new URL( "http://notavalidurlihope.com");
HttpURLConnection con = (HttpURLConnection ) url.openConnection();
System.out.println(con.getResponseCode());
HttpURLConnection con2 = (HttpURLConnection ) wrongUrl.openConnection();
System.out.println(con2.getResponseCode());
} catch (IOException e) {
System.out.println("Error connecting");
}
Note: Do disconnect afterwards
output:
200
Error connecting
This simple helper method uses regex to ensure that a website URL is in correct format. It will also fail if there is any white space (which is important).
The following URL's pass:
google.com
www.google.com
http://google.com
http://www.google.com
https://google.com/test/test
https://www.google.com/test
It fails on:
www.google.com/a bad path with white space/
Below is the helper method I created:
public static bool ValidateUrl(string value, bool required, int minLength, int maxLength)
{
value = value.Trim();
if (required == false && value == "") return true;
if (required && value == "") return false;
Regex pattern = new Regex(#"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]#!\$&'\(\)\*\+,;=.]+$");
Match match = pattern.Match(value);
if (match.Success == false) return false;
return true;
}

Get specific field from Uri

I'm using the following url and I need to delete the ?$format=xml from the url. Is there a simple way to achieve this ?
Uri uri = new Uri("https://ldcorp:435/mtp/op/ota/ind/Customer/?$format=xml);
Maybe with simple string methods:
uriString = uri.ToString();
int indexOfQuestionMark = uriString.IndexOf("?");
if(indexOfQuestionMark >= 0)
{
uri = new Uri(uriString.Substring(0, indexOfQuestionMark));
}
or with the Uri class itself and string.Format:
string pathWithoutQuery = String.Format("{0}{1}{2}{3}", uri.Scheme,
uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.AbsolutePath);
uri = new Uri(pathWithoutQuery);

How to efficiently remove a query string by Key from a Url?

How to remove a query string by Key from a Url?
I have the below method which works fine but just wondering is there any better/shorter way? or a built-in .NET method which can do it more efficiently?
public static string RemoveQueryStringByKey(string url, string key)
{
var indexOfQuestionMark = url.IndexOf("?");
if (indexOfQuestionMark == -1)
{
return url;
}
var result = url.Substring(0, indexOfQuestionMark);
var queryStrings = url.Substring(indexOfQuestionMark + 1);
var queryStringParts = queryStrings.Split(new [] {'&'});
var isFirstAdded = false;
for (int index = 0; index <queryStringParts.Length; index++)
{
var keyValue = queryStringParts[index].Split(new char[] { '=' });
if (keyValue[0] == key)
{
continue;
}
if (!isFirstAdded)
{
result += "?";
isFirstAdded = true;
}
else
{
result += "&";
}
result += queryStringParts[index];
}
return result;
}
For example I can call it like:
Console.WriteLine(RemoveQueryStringByKey(#"http://www.domain.com/uk_pa/PostDetail.aspx?hello=hi&xpid=4578", "xpid"));
Hope the question is clear.
Thanks,
This works well:
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url);
// this gets all the query string key value pairs as a collection
var newQueryString = HttpUtility.ParseQueryString(uri.Query);
// this removes the key if exists
newQueryString.Remove(key);
// this gets the page path from root without QueryString
string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path);
return newQueryString.Count > 0
? String.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
: pagePathWithoutQueryString;
}
an example:
RemoveQueryStringByKey("https://www.google.co.uk/search?#hl=en&output=search&sclient=psy-ab&q=cookie", "q");
and returns:
https://www.google.co.uk/search?#hl=en&output=search&sclient=psy-ab
var queryString = "hello=hi&xpid=4578";
var qs = System.Web.HttpUtility.ParseQueryString(queryString);
qs.Remove("xpid");
var newQuerystring = qs.ToString();
This still works in .NET 5.
There's a useful class called UriBuilder in the System namespace. We can use it along with a couple of extension methods to do the following:
Uri u = new Uri("http://example.com?key1=value1&key2=value2");
u = u.DropQueryItem("key1");
Or like this:
Uri u = new Uri("http://example.com?key1=value1&key2=value2");
UriBuilder b = new UriBuilder(u);
b.RemoveQueryItem("key1");
u = b.Uri;
The extension methods:
using System;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
public static class UriExtensions
{
public static Uri DropQueryItem(this Uri u, string key)
{
UriBuilder b = new UriBuilder(u);
b.RemoveQueryItem(key);
return b.Uri;
}
}
public static class UriBuilderExtensions
{
private static string _ParseQueryPattern = #"(?<key>[^&=]+)={0,1}(?<value>[^&]*)";
private static Regex _ParseQueryRegex = null;
private static Regex ParseQueryRegex
{
get
{
if (_ParseQueryRegex == null)
{
_ParseQueryRegex = new Regex(_ParseQueryPattern, RegexOptions.Compiled | RegexOptions.Singleline);
}
return _ParseQueryRegex;
}
}
public static void SetQueryItem(this UriBuilder b, string key, string value)
{
NameValueCollection parms = ParseQueryString(b.Query);
parms[key] = value;
b.Query = RenderQuery(parms);
}
public static void RemoveQueryItem(this UriBuilder b, string key)
{
NameValueCollection parms = ParseQueryString(b.Query);
parms.Remove(key);
b.Query = RenderQuery(parms);
}
private static string RenderQuery(NameValueCollection parms)
{
StringBuilder sb = new StringBuilder();
for (int i=0; i<parms.Count; i++)
{
string key = parms.Keys[i];
sb.Append(key + "=" + parms[key]);
if (i < parms.Count - 1)
{
sb.Append("&");
}
}
return sb.ToString();
}
public static NameValueCollection ParseQueryString(string query, bool caseSensitive = true)
{
NameValueCollection pairs = new NameValueCollection(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
string q = query.Trim().TrimStart(new char[] {'?'});
MatchCollection matches = ParseQueryRegex.Matches(q);
foreach (Match m in matches)
{
string key = m.Groups["key"].Value;
string value = m.Groups["value"].Value;
if (pairs[key] != null)
{
pairs[key] = pairs[key] + "," + value;
}
else
{
pairs[key] = value;
}
}
return pairs;
}
}
I know this is a rather old question, but everything I read felt a bit complicated.
public Uri GetUriWithoutQueryParam( Uri originalUri, string paramKey ) {
NameValueCollection newQuery = HttpUtility.ParseQueryString( originalUri.Query );
newQuery.Remove( paramKey );
return new UriBuilder( originalUri ) { Query = newQuery.ToString() }.Uri;
}
We can also do it using regex
string queryString = "Default.aspx?Agent=10&Language=2"; //Request.QueryString.ToString();
string parameterToRemove="Language"; //parameter which we want to remove
string regex=string.Format("(&{0}=[^&\s]+|(?<=\?){0}=[^&\s]+&?)",parameterToRemove); //this will not work for javascript, for javascript you can do following
string finalQS = Regex.Replace(queryString, regex, "");
//javascript(following is not js syntex, just want to give idea how we can able do it in js)
string regex1 = string.Format("(&{0}=[^&\s]+)",parameterToRemove);
string regex2 = string.Format("(\?{0}=[^&\s]+&?)",parameterToRemove);
string finalQS = Regex.Replace(queryString, regex1, "").Replace(queryString, regex2, "");
https://regexr.com/3i9vj
How about this:
string RemoveQueryStringByKey(string url, string key)
{
string ret = string.Empty;
int index = url.IndexOf(key);
if (index > -1)
{
string post = string.Empty;
// Find end of key's value
int endIndex = url.IndexOf('&', index);
if (endIndex != -1) // Last query string value?
{
post = url.Substring(endIndex, url.Length - endIndex);
}
// Decrement for ? or & character
--index;
ret = url.Substring(0, index) + post;
}
return ret;
}
I found a way without using Regex:
private string RemoveQueryStringByKey(string sURL, string sKey) {
string sOutput = string.Empty;
int iQuestion = sURL.IndexOf('?');
if (iQuestion == -1) return (sURL);
int iKey = sURL.Substring(iQuestion).IndexOf(sKey) + iQuestion;
if (iKey == -1) return (sURL);
int iNextAnd = sURL.Substring(iKey).IndexOf('&') + iKey + 1;
if (iNextAnd == -1) {
sOutput = sURL.Substring(0, iKey - 1);
}
else {
sOutput = sURL.Remove(iKey, iNextAnd - iKey);
}
return (sOutput);
}
I did try this with adding another field at the end, and it works fine for that too.
I'm thinking the shortest way (that I believe produces a valid URL in all cases, assuming the URL was valid to begin with) would be to use this regex (where getRidOf is the variable name you are trying to remove) and the replacement is a zero-length string ""):
(?<=[?&])getRidOf=[^&]*(&|$)
or maybe even
\bgetRidOf=[^&]*(&|$)
while possibly not the absolute prettiest URLs, I think they are all valid:
INPUT OUTPUT
----------- ------------
blah.com/blah.php?getRidOf=d.co&blah=foo blah.com/blah.php?blah=foo
blah.com/blah.php?f=0&getRidOf=d.co&blah=foo blah.com/blah.php?f=0&blah=foo
blah.com/blah.php?hello=true&getRidOf=d.co blah.com/blah.php?hello=true&
blah.com/blah.php?getRidOf=d.co blah.com/blah.php?
and it's a simple regex replace:
Dim RegexObj as Regex = New Regex("(?<=[?&])getRidOf=[^&]*(&|$)")
RegexObj.Replace("source.url.com/find.htm?replace=true&getRidOf=PLEASE!!!", "")
...should result in the string:
"source.url.com/find.htm?replace=true&"
...which seems to be valid for an ASP.Net application, while replace does equal true (not true& or anything like that)
I'll try to adapt it if you have a case where it won't work :)
public static string RemoveQueryStringByKey(string sURL, string sKey)
{
string sOutput = string.Empty;
string sToReplace = string.Empty;
int iFindTheKey = sURL.IndexOf(sKey);
if (iFindTheKey == -1) return (sURL);
int iQuestion = sURL.IndexOf('?');
if (iQuestion == -1) return (sURL);
string sEverythingBehindQ = sURL.Substring(iQuestion);
List<string> everythingBehindQ = new List<string>(sEverythingBehindQ.Split('&'));
foreach (string OneParamPair in everythingBehindQ)
{
int iIsKeyInThisParamPair = OneParamPair.IndexOf(sKey);
if (iIsKeyInThisParamPair != -1)
{
sToReplace = "&" + OneParamPair;
}
}
sOutput = sURL.Replace(sToReplace, "");
return (sOutput);
}
Below code before deleting your QueryString.
PropertyInfo isreadonly =
typeof(System.Collections.Specialized.NameValueCollection).GetProperty(
"IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
// make collection editable
isreadonly.SetValue(this.Request.QueryString, false, null);
// remove
this.Request.QueryString.Remove("yourKey");
Sorry this is a bit dirty but should work in older framework
public String RemoveQueryString( String rawUrl , String keyName)
{
var currentURL_Split = rawUrl.Split('&').ToList();
currentURL_Split = currentURL_Split.Where(o => !o.ToLower().StartsWith(keyName.ToLower()+"=")).ToList();
String New_RemovedKey = String.Join("&", currentURL_Split.ToArray());
New_RemovedKey = New_RemovedKey.Replace("&&", "&");
return New_RemovedKey;
}
Here is my solution:
I'v added some extra input validation.
public static void TryRemoveQueryStringByKey(ref string url, string key)
{
if (string.IsNullOrEmpty(url) ||
string.IsNullOrEmpty(key) ||
Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
{
return false;
}
try
{
Uri uri = new Uri(url);
// This gets all the query string key value pairs as a collection
NameValueCollection queryCollection = HttpUtility.ParseQueryString(uri.Query);
string keyValue = queryCollection.Get(key);
if (url.IndexOf("&" + key + "=" + keyValue, StringComparison.OrdinalIgnoreCase) >= 0)
{
url = url.Replace("&" + key + "=" + keyValue, String.Empty);
return true;
}
else if (url.IndexOf("?" + key + "=" + keyValue, StringComparison.OrdinalIgnoreCase) >= 0)
{
url = url.Replace("?" + key + "=" + keyValue, String.Empty);
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
Some unit testing examples:
string url1 = "http://www.gmail.com?a=1&cookie=cookieValue"
Assert.IsTrue(TryRemoveQueryStringByKey(ref url1,"cookie")); //OUTPUT: "http://www.gmail.com?a=1"
string url2 = "http://www.gmail.com?cookie=cookieValue"
Assert.IsTrue(TryRemoveQueryStringByKey(ref url2,"cookie")); //OUTPUT: "http://www.gmail.com"
string url3 = "http://www.gmail.com?cookie="
Assert.IsTrue(TryRemoveQueryStringByKey(ref url2,"cookie")); //OUTPUT: "http://www.gmail.com"
Here's a full solution that works with >= 0 params specified, and any form of URL:
/// <summary>
/// Given a URL in any format, return URL with specified query string param removed if it exists
/// </summary>
public static string StripQueryStringParam(string url, string paramToRemove)
{
return StripQueryStringParams(url, new List<string> {paramToRemove});
}
/// <summary>
/// Given a URL in any format, return URL with specified query string params removed if it exists
/// </summary>
public static string StripQueryStringParams(string url, List<string> paramsToRemove)
{
if (paramsToRemove == null || !paramsToRemove.Any()) return url;
var splitUrl = url.Split('?');
if (splitUrl.Length == 1) return url;
var urlFirstPart = splitUrl[0];
var urlSecondPart = splitUrl[1];
// Even though in most cases # isn't available to context,
// we may be passing it in explicitly for helper urls
var secondPartSplit = urlSecondPart.Split('#');
var querystring = secondPartSplit[0];
var hashUrlPart = string.Empty;
if (secondPartSplit.Length > 1)
{
hashUrlPart = "#" + secondPartSplit[1];
}
var nvc = HttpUtility.ParseQueryString(querystring);
if (!nvc.HasKeys()) return url;
// Remove any matches
foreach (var key in nvc.AllKeys)
{
if (paramsToRemove.Contains(key))
{
nvc.Remove(key);
}
}
if (!nvc.HasKeys()) return urlFirstPart;
return urlFirstPart +
"?" + string.Join("&", nvc.AllKeys.Select(c => c.ToString() + "=" + nvc[c.ToString()])) +
hashUrlPart;
}
A more modern answer for this old question in case someone else stumbles across it like I did.
This is using the Uri class to parse the URL (can be skipped if your URL is already in a Uri object) and LINQ to filter the query string.
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url, UriKind.Absolute);
var queryParts = uri.Query
.TrimStart('?')
.Split('&')
.Where(item => string.CompareOrdinal(item, key) != 0);
return uri.Scheme + Uri.SchemeDelimiter
+ uri.Authority
+ uri.AbsolutePath
+ "?" + string.Join("&", queryParts);
}
With reusing the signature from the accepted answer, but preserving the fragment and using QueryHelpers from Microsoft.AspNetCore.WebUtilities.
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url);
var newQueryString = QueryHelpers.ParseQuery(uri.Query);
if (newQueryString.Remove(key))
{
var urlWithNewQuery = QueryHelpers.AddQueryString(
uri.GetLeftPart(UriPartial.Path),
newQueryString.ToDictionary(
queryParam => queryParam.Key,
queryParam => queryParam.Value.ToString()))
return $"{urlWithNewQuery}{uri.Fragment}";
}
return url;
}
string url = HttpContext.Current.Request.Url.AbsoluteUri;
string[] separateURL = url.Split('?');
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(separateURL[1]);
queryString.Remove("param_toremove");
string revisedurl = separateURL[0] + "?" + queryString.ToString();

Categories

Resources