I have a url that is hold the complete path of my SSRS Report . In C# i want to break the url in multiple string
http://Mydatabase-live/ReportServer?%2fADMIN%2fSTATS+-+SCHEDULE&TEAMNM=2015 TERRIER JV&rs:Command=Render&rs:Format=PDF
Here i want to break this url into part-1 http://Mydatabase-live/ReportServer part-2 ADMIN/STATS-SCHEDULE and part-3 TEAMNM
I thought about this and one way to do it is to define some delimiters for the program to know where to break the URL.
Before we do this, we need to replace the special characters first.
So let's start:
string searchFor;
string replaceWith;
static void Main(string[] args)
{
// First we need to replace the special characters:
ReplaceSubstrings replace = new ReplaceSubstrings();
string s = "http://Mydatabase-live/ReportServer?%2fADMIN%2fSTATS+-+SCHEDULE&TEAMNM=2015 TERRIER JV&rs:Command=Render&rs:Format=PDF";
// We need to replace:
// "%2f" with "/"
// "+-+" with "-"
// using System.Text.RegularExpressions
replace.searchFor = "%2f";
replace.replaceWith = "/";
s = Regex.Replace(s, replace.searchFor);
replace.searchFor = "+-+";
replace.replaceWith = "-";
s = Regex.Replace(s, replace.searchFor);
// Your URL will now look like this:
Console.WriteLine(s);
// Output: http://Mydatabase-live/ReportServer?/ADMIN/STATS-SCHEDULE&TEAMNM=2015 TERRIER JV&rs:Command=Render&rs:Format=PDF
// Add the delimiters
char[] delimiters = {'?', '&', '='};
string[] words = s.Split(delimiters);
foreach (string s in words)
{
System.Console.WriteLine(s);
}
// Output:
// http://Mydatabase-live/ReportServer
// /ADMIN/STATS-SCHEDULE
// TEAMNM
// 2015 TERRIER JV
// rs:Command
// Render
// rs:Format
// PDF
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Your URL will be separated in much more places than you specified, but this is how you should do it. You could delete the last part from the string where the first = sign is located, and then execute the string separation.
I hope this helped you.
This is dynamic way of splitting the URL using Uri Class.
Uri class has the feature to get absolute path,query and etc. You can use them and construct your requirement.
string path = "http://Mydatabase-live/ReportServer?%2fADMIN%2fSTATS+-+SCHEDULE&TEAMNM=2015 TERRIER JV&rs:Command=Render&rs:Format=PDF";
Uri uri = new Uri(path);
Console.WriteLine(uri.AbsolutePath); //Absolute path
Console.WriteLine(uri.Query); //Query
Related
I have a query string that looks something like this:
"somename1=123&QueryString=PlaceHolder%3dNothing%26anotherid%3dsomevalue&somename=somevalue"
but I want the query string to be something like the query string below and replace the whole query string with the updated one is there any way to do that without redirection?
"somename1=somevalue1&PlaceHolder=Nothing&somename2=somevalue2&somename3=somevalue3"
basically need to remove:
"QueryString=" with empty string
"%3d" with "&"
"%26" with "="
So far I've done is:
string strQueryString = Request.QueryString.ToString();
if (strQueryString.Contains("QueryString="))
{
strQueryString = strQueryString.Replace("QueryString=", "");
if (strQueryString.Contains("%26")) strQueryString = strQueryString.Replace("%26", "&");
if (strQueryString.Contains("%3d")) strQueryString = strQueryString.Replace("%3d", "=");
string x = strQueryString;
}
and:
// reflect to readonly property
PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
// make collection editable
isreadonly.SetValue(this.Request.QueryString, false, null);
if (this.Request.QueryString.ToString().Contains("QueryString="))
{
this.Request.QueryString.ToString().Replace("QueryString=", "");
if (this.Request.QueryString.ToString().Contains("%26")) this.Request.QueryString.ToString().Replace("%26", "&");
if (this.Request.QueryString.ToString().Contains("%3d")) this.Request.QueryString.ToString().Replace("%3d", "=");
string x = this.Request.QueryString.ToString();
}
// make collection readonly again
isreadonly.SetValue(this.Request.QueryString, true, null);
The second part of the code is not replacing the characters and I don't know how after removing all character or replacing them change the query string to new query string.
Any help is greatly appreciated.
Changing the query string of the current request is not supported. Using private Reflection to edit some in-memory state will most likely break ASP.NET because it assumes that the query string is immutable. The only way to change the query string is to issue a new request, either by doing a redirect, or by doing a sort of sub-request, such as by making a new HTTP request to the same page but with a different query string.
May I suggest a not very well known built in key/value dictionary, Context.Items.
With this you very like get a better performance than toggle the readonly QueryString object, and it also last throughout a request so you can share it between module, handlers, etc.
Create
string strQueryString = Request.QueryString.ToString();
if (strQueryString.Contains("QueryString="))
{
HttpContext.Current.Items("qs") = strQueryString.Replace("QueryString=", "").Replace("%26", "&").Replace("%3d", "=");
}
Use
string x = HttpContext.Current.Items("qs_d").ToString();
Side note: I shortened you code some, as there is no need to first check if anything contains and if so, replace, just run replace, it will be faster
I need to extract uploads from http-trafic. How could do that? First of all, the request-method will be POST. Secondly, there will be a Content-Type header-field. I do not want to extract formular-data, but uploads like mail-attachements.
The content type is per specification multipart/form-data.
This is a special content type which can be visualized as multiple sub-requests in one big request. Each of those sub-requests (one form-data element) has their own set of headers. The content type of the actual data is in there.
Here's an example how it look like with 1 normal field and 1 file field (in HTML terms, when using <input name="textfield"><input type="file" name="filefield">):
Content-Type: multipart/form-data;boundary=SOME_BOUNDARY
--SOME_BOUNDARY
content-disposition: form-data;name="textfield"
content-type: text/plain;charset=UTF-8
value of textfield here
--SOME_BOUNDARY
content-disposition: form-data;name="filefield";filename="some.ext"
content-type: application/octet-stream
binary file content here
--SOME_BOUNDARY--
As to parsing and extracting this data, practically every programming language has builtin/3rd party APIs for this. As you didn't tell anything about which one you're using, it's impossible to give a targeted answer. In case of for example Java, that would be either the 3rd party library Apache Commons FileUpload or when you're using Servlet 3.0, the API-provided request.getPart() method.
If (and I by no means am saying this is the correct way) you just want to save data from a byte array, you should look at how to read the POST body at:
Reading POST body with bottle.py
Reading the data and then creating a new file should do the trick.
Based on #BalusC s solution I made a little extension method for .NET's build in WebClient class which does not support Multipart upload out of the box.
Usage
Just mix string values and files (enclosed in #)
public void UploadMultipart()
{
var fileName = "/some/existing/file.ext";
using (var client = new WebClient())
{
var values = new NameValueCollection();
values.Add("id", Guid.NewGuid().ToString());
values.Add("name", Path.GetFileNameWithoutExtension(fileName));
values.Add("file", $"#{fileName}#");
var result = client.UploadMultipart(address, method, values);
var content = client.Encoding.GetString(result);
}
}
Extension method
public static byte[] UploadMultipart(this WebClient client,
string address, string method, NameValueCollection values)
{
string boundary = DateTime.Now.Ticks.ToString("x");
client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
var sb = new StringBuilder()
.AppendLine();
foreach (var key in values.AllKeys)
{
var contentDispositon = $"form-data;name=\"{key}\"";
var contentType = $"text/plain;charset={client.Encoding.WebName}";
var value = values[key];
if (value.StartsWith("#") && value.EndsWith("#"))
{
// if a value is enclosed in hashes we expect this to be a path to a file
// file=#/path/to/file.ext#
var fileName = value.Trim('#');
var file = File.ReadAllBytes(fileName);
value = client.Encoding.GetString(file);
contentType = "application/octet-stream";
contentDispositon = $"form-data;name=\"{key}\"filename=\"{Path.GetFileName(fileName)}\"";
}
sb.AppendLine($"--{boundary}")
.AppendLine($"Content-Disposition: {contentDispositon}")
.AppendLine($"Content-Type: {contentType}")
.AppendLine()
.AppendLine(value);
}
sb.AppendLine($"--{boundary}--");
var data = client.Encoding.GetBytes(sb.ToString());
return client.UploadData(address, method, data);
}
I think regular expressions might be able to accomplish this, if not then string manipulation is also a viable solution.
I need to turn the following inputs:
"http://open.thumbshots.org/image.pxf?url=www.party.com"
"http://www.xclicks.net/sc/ct.php?s=9971&l=http%3A//www.google.com/imgres%3F"
"http://whos.amung.us/pingjs/?k=yvybju40twbs&t=Mudswimmer%3A%20Spam%20%26%20Crap%3A%20Http%3AUniversity.com%3A%20No%20Animals%20Allowed..&c=c&y=htt"
into the following outputs:
"party.com"
"google.com"
"University.com"
I am not trying to get the host name of the URL, I want the the second domain, the one in the query string.
With everything that involves regular expressions there is a degree of uncertainty, for me at least, but giving your three inputs the following code works:
string[] urls = new string[]
{
"http://open.thumbshots.org/image.pxf?url=www.party.com",
"http://www.xclicks.net/sc/ct.php?s=9971&l=http%3A//www.google.com/imgres%3F",
"http://whos.amung.us/pingjs/?k=yvybju40twbs&t=Mudswimmer%3A%20Spam%20%26%20Crap%3A%20Http%3AUniversity.com%3A%20No%20Animals%20Allowed..&c=c&y=htt"
};
foreach (var url in urls)
{
var result = HttpUtility.ParseQueryString(new Uri(url, UriKind.Absolute).Query);
foreach (string item in result)
{
string value = result.GetValues(item).Single();
const string DomainNamePattern = "(?:www\\.|\\b)(?<domain>([a-z0-9]([-a-z0-9]*[a-z0-9])?\\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(cat|com|coop|c[acdfghiklmnorsuvxyz])|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))";
var match = Regex.Match(
value,
DomainNamePattern,
RegexOptions.IgnoreCase);
if (match.Success)
{
string domain = match.Groups["domain"].Value;
Console.WriteLine(domain);
}
}
}
The regular expression used was adapted from here.
If you run this you get the following output:
// party.com
// google.com
// University.com
If your link always contain the url querystring key then you can simple get this by
String url = Request.QueryString["url"].ToString();
This will retrun the value of url.
Writing
#Url.Content("~/Something/Something.html")
in razor renders
/AppFolder/Something/Something.html
Is there a way to render the full URL like http://www.something.com/AppFolder/Something/Something.html without atrocious hacks? (like storing the protocol and domain in the AppConfig, and concatenate the string to it)
Is there a helper like #Url.FullPath("~/asdf/asdf") or similar?
See this blog post for the answer.
Basically, all you need to do it include the protocol parameter e.g.
Url.Action("About", "Home", null, "http")
The #Url.RouteURL() does not quiet answer this question. It does work for named routes but falls short for arbitrary virtual paths.
Here is quick helper method that generates full outbound url. You can create overloads for various schemes (http[s]) depending on the degree of control desired.
public static class UrlHelperExtension
{
public static string ContentFullPath(this UrlHelper url,string virtualPath)
{
var result = string.Empty;
Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
result = string.Format("{0}://{1}{2}",
requestUrl.Scheme,
requestUrl.Authority,
VirtualPathUtility.ToAbsolute(virtualPath));
return result;
}
}
For anyone needing to build URLs in WebAPI 2.2 and/or MVC5, this worked for me:
// works in a controller
var requestUri = this.Request.RequestUri;
// just the http/s and the hostname; ymmv
string baseUrl = requestUri.Scheme + "://" + requestUri.Authority + "/";
// build your url for whatever purpose you need it for
string url = baseUrl + "SomeOtherController?id=" + <some_magic_value>;
You can use a helper to produce a full url, including protocol. Note the first lowercase in url.Action.
var url = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext);
var fullUrl = url.Action("YourAction", "YourController", new { id = something }, protocol: System.Web.HttpContext.Current.Request.Url.Scheme);
Output
https://www.yourdomain.com/YourController/YourAction?id=something
how can i modified the querystring?
I have capture the query string like this
qs = Request.QueryString["flag"].ToString();
and then rebuilt the query string with modified values
and response.redirect(url & qs) to it
While I'm not sure I'd suggest using this approach liberally, if you wanted to reconstruct the path and query string with a few changes... you could convert the query string to an editable collection, modify it, then rebuild it from your new collection.
Goofy example...
// create dictionary (editable collection) of querystring
var qs = Request.QueryString.AllKeys
.ToDictionary(k => k, k => Request.QueryString[k]);
// modify querystring
qs["flag"] = "2";
// rebuild querystring
var redir = string.Format("{0}{1}", Request.Path,
qs.Aggregate(new StringBuilder(),
(sb, arg) => sb.AppendFormat("{0}{1}={2}",
sb.Length > 0 ? "&" : "?", arg.Key, arg.Value)));
// do something with it
Response.Redirect(redir);
While I definitely wouldn't recommend the below for production code, for testing purposes you can use reflection to make the querystring collection editable.
// Get the protected "IsReadOnly" property of the collection
System.Reflection.PropertyInfo prop = Request.QueryString.GetType()
.GetProperty("IsReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
// Set the property false (writable)
prop.SetValue(Request.QueryString, false, null);
// Have your way with it.
Request.QueryString.Add("flag", "2");
To combine the required destination URL based on the Request’s properties, use something like this:
string destUrl = string.Format("{0}://{1}{2}/", Request.Url.Scheme, Request.Url.Authority, Request.Url.AbsolutePath);
if (destUrl.EndsWith("/"))
destUrl = destUrl.TrimEnd(new char[] { '/' });
if (!string.IsNullOrEmpty(Request.QueryString["paramName"])) {
destUrl = string.Format("{0}?paramName={1}", destUrl, "paramValueHere");
Response.Redirect(destUrl);
}
i am not sure if I understand your question. You can just alter the string qs and use.
qs = qs + "modification"
Response.Redirect("this.aspx?flag=" + qs )
The stuff in the Request class deals with the request that got you to the page. You can't edit it because the client constructed it, not the server.