So i have this code on my cs page that takes decodes a key from my Url string. The key is "Reauth_URL" and its a link that is decoded in base64 to UTF8.
////base 64 decoding for Reauth_URL key in URL query string
string encodedString = Convert.ToString(HttpContext.Current.Request.Params["Reauth_URL"]).Trim(')');
byte[] data = Convert.FromBase64String(encodedString);
string decodedString = Encoding.UTF8.GetString(data);
I'm trying to use decodedString but i keep on getting a null refence exception but i can see that the key and value are there.
once i can return the string value id like to ba able to send it into a hyperlink that's on my aspx page.
the encoded url is set up from IronPort which allows a user to lg in as differnt user if they've been blocked from a website. so this reauth_url key in the query string allows them to log in as different user. by the reauth_url needs to be decoded and linked to the hyperlink. I know the key and value is there but i cant get by this null exception, and when i say i know they are there obviously i don't mean in the code above, ive had to split the url query by ? and & and print it out somewhere else and they exist. The code below is used earlier and the key and value i need is there.
string currentUrl = HttpContext.Current.Request.Url.Query;
txtBlockedUrl.Visible = true;
string [] result = currentUrl.Split(new Char[]{'?','&'});
foreach (string r in result)
{
txtBlockedUrl.Text += HttpUtility.UrlDecode(r) + "\n";
}
div style="font-size: medium">
LogIn as Different User
</div>
If HttpContext.Current.Request.Params["Reauth_URL"] is null, Convert.ToString will throw a null reference exception.
Please note that the Params indexer will return null when "Reauth_URL" is not available.
So you have to check first if it exists: (what if the url does not provide it?)
string value = HttpContext.Current.Request.Params["Reauth_URL"];
if (value!=null) {
string encodedString = Convert.ToString(HttpContext.Current.Request.Params["Reauth_URL"]).Trim(')');
//...
Ended Up doing this....
//splitting url string for textbox using name value collection
NameValueCollection collection = new NameValueCollection();
string currentUrl = HttpContext.Current.Request.Url.Query;
string [] result = currentUrl.Split('&');
foreach (string r in result)
{
string[] parts = HttpUtility.UrlDecode(r).Split('=');
if (parts.Length > 0)
{
string key = parts[0].Trim(new char[] { '?', ' ' });
string val = parts[1].Trim();
collection.Add(key, val);
}
}
Related
I have string URL as follow
http://localhost:56856/s.aspx?&searchString=jacket&sortField=&pageNumber=2&pageSize=0&facetQuery=
I need to change the query string values from the above url for example if i find the pageSize=0 than i need to change its value pageNumber*12.
like in above url pagnumber is 2 and page size is 0 so page size should be 2* 12=24. i have used following code
string url=http://localhost:56856/s.aspx?&searchString=jacket&sortField=&pageNumber=2&pageSize=0&facetQuery=
var QueryValues = HttpUtility.ParseQueryString(url);
string pageno = QueryValues.Get("pageNumber");
string pagesize = QueryValues.Get("pageSize");
if (pagesize == "0")
{
QueryValues.Set("pageSize", Convert.ToString(Convert.ToInt32(pageno) * 12));
}
in QueryValues i am getting url like this =http://localhost:%%2f55%/s%aspx?&searchString=jacket&sortField=&pageNumber=2&pageSize=0&facetQuery=
can you please suggest me where i am wrong and how can i convert this QueryValues to valid url?
Thanks
One thing that I noticed is that you are not identifying what the querystring prior to parsing it. We can easily find this by locating the IndexOf('?') in the URL which delineates the URL from the QueryString. You may want to review the MSDN: HttpUtility.ParseQueryString Method article, I used their identification method when I was reviewing this method ( I generally use more primitve methods when working with URLs)
Be aware that the NameValueCollection QueryString can have and will return null values in it.
I recommend that when retrieving these values that you take appropriate countermeasures, such as setting strings to empty or numbers to 0. I further recommend that you do these upon retrieval and not using compounded `Convert.To\
string url = #"http://localhost:56856/s.aspx?&searchString=jacket&sortField=&pageNumber=2&pageSize=0&facetQuery=";
#region ===== Added: Identify and split =====
int iqs = url.IndexOf('?');
if iqs< 0) {
// Cannot process, NO query string present
// Corrective Action?
} else {
string urlQS= (iqs < url.Length - 1) ? currurl.Substring(iqs + 1) : String.Empty;
#endregion ===================================
var QueryValues = HttpUtility.ParseQueryString(urlQS); // changed from (url)
string pageno = QueryValues.Get("pageNumber"); // catch null return ""
string pagesize = QueryValues.Get("pageSize"); // int, catch null return 0
if (pagesize == "0") {
QueryValues.Set( "pageSize", Convert.ToString( Convert.ToInt32(pageno) * 12 ) );
}
}
In my c# application I am building a routine that will parse through a url replace any sections of the url with the appropriate data.
For instance, if I have a url like:
api.domain.com/users/{id}
and the user provides the id, i replace the id with the given value.
This is simple enough:
if(path.Contains("{id}") path = path.Replace("{id}", id);
However, what I want is to be able to remove the {id} from the url if no id is provided so that the final url is:
api.domain.com/users
I would also want it to intelligently be able to remove items in the middle of the path so that if the url were:
api.domain.com/users/{id}/photos
I would get:
api.domain.com/users/photos
For this, I would not know the text of the key ahead of time so {id} could be anything such as:
{name} {sometext} {anyvalue}
But I do know that each MUST be contained in curly braces.
Any help would be greatly appreciated!
You can do something like this:
public string UrlReplace(string Url, string key, string value = "")
{
var replaceString = "{" + key + "}"; //get the string to replace
//if the value is empty remove the slash
if (string.IsNullOrEmpty(value))
{
//find the index of the replace string in the url
var index = url.IndexOf(replaceString) + replaceString.Length;
if (url[index] == '/')
{
url = url.Remove(index, 1); //if the character after the string is a slash, remove it
}
}
return url.Replace(replaceString, value); //replace the string with the value
}
Then you'd use it like
string url = "api.domain.com/users/{id}/photos";
url = UrlReplace(url,"id","test");
//returns "api.domain.com/users/test/photos"
url = UrlReplace(url, "id", "");
//returns "api.domain.com/users/photos"
I am using this API to find the country of a user. I am able to find the country on a web page in XML format. Here you can see XML file example. But the problem is i can not read this XML in my c# code. Here is my code
string UserIP = Request.ServerVariables["REMOTE_ADDR"].ToString();
string ApiKey = "5d3d0cdbc95df34b9db4a7b4fb754e738bce4ac914ca8909ace8d3ece39cee3b";
string Url = "http://api.ipinfodb.com/v3/ip-country/?key=" + ApiKey + "&ip=" + UserIP;
XDocument xml = XDocument.Load(Url);
But this code returns following exception on loading the xml.
System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
Please describe the exact method to read this XML.
I'll say that it isn't an XML but simply a string subdivided by ;:
By giving an impossible IP address we can see that it's so composed:
OK;;74.125.45.100;US;UNITED STATES
ERROR;Invalid IP address.;127.0.0.1.1;;
OK/ERROR
If ERROR, complete ERROR message
IP Address
Abbreviation of country
Country name
This code should do:
string userIP = "127.0.0.1";
string apiKey = "5d3d0cdbc95df34b9db4a7b4fb754e738bce4ac914ca8909ace8d3ece39cee3b";
string url = "http://api.ipinfodb.com/v3/ip-country/?key=" + apiKey + "&ip=" + userIP;
WebRequest request = WebRequest.Create(url);
using (var response = (HttpWebResponse)request.GetResponse())
{
// We try to use the "correct" charset
Encoding encoding = response.CharacterSet != null ? Encoding.GetEncoding(response.CharacterSet) : null;
using (var sr = encoding != null ? new StreamReader(response.GetResponseStream(), encoding) :
new StreamReader(response.GetResponseStream(), true))
{
var response2 = sr.ReadToEnd();
var parts = response2.Split(';');
if (parts.Length != 5)
{
throw new Exception();
}
string okError = parts[0];
string message = parts[1];
string ip = parts[2];
string code = parts[3];
string country = parts[4];
}
}
Here is what I'd do:
Using a HTTP transfer, query the site, and buffer the results
Convert it into a String
Use a splitting algorithm on it to make into an array.
Check if the 0th element of the array equals 'OK'
If not, bail out.
If so, check the third and fourth elements for country code, and country name respectively.
from the IP Location XML API Documentation: API Parameter format, required = false, default = raw, values = raw, xml, json. so I have tested it and string Url = "http://api.ipinfodb.com/v3/ip-country/?key=" + ApiKey + "&ip=" + UserIP + "&format=xml" gives a parsable xml result.
I have a C# asp.net page that has to get username/password info from a text file.
Could someone please tell me how.
The text file looks as follows: (it is actually a lot larger, I just got a few lines)
DATASOURCEFILE=D:\folder\folder
var1= etc
var2= more
var3 = misc
var4 = stuff
USERID = user1
PASSWORD = pwd1
all I need is the UserID and password out of that file.
Thank you for your help,
Steve
This would work:
var dic = File.ReadAllLines("test.txt")
.Select(l => l.Split(new[] { '=' }))
.ToDictionary( s => s[0].Trim(), s => s[1].Trim());
dic is a dictionary, so you easily extract your values, i.e.:
string myUser = dic["USERID"];
string myPassword = dic["PASSWORD"];
Open the file, split on the newline, split again on the = for each item and then add it to a dictionary.
string contents = String.Empty;
using (FileStream fs = File.Open("path", FileMode.OpenRead))
using (StreamReader reader = new StreamReader(fs))
{
contents = reader.ReadToEnd();
}
if (contents.Length > 0)
{
string[] lines = contents.Split(new char[] { '\n' });
Dictionary<string, string> mysettings = new Dictionary<string, string>();
foreach (string line in lines)
{
string[] keyAndValue = line.Split(new char[] { '=' });
mysettings.Add(keyAndValue[0].Trim(), keyAndValue[1].Trim());
}
string test = mysettings["USERID"]; // example of getting userid
}
You can use Regular expressions to extract each variable. You can read one line at a time, or the entire file into one string. If the latter, you just look for a newline in the expression.
Regards,
Morten
Dictionary is not needed.
Old-fashioned parsing can do more, with less executable code, the same amount of compiled data, and less processing:
public string MyPath1;
public string MyPath2;
...
public void ReadConfig(string sConfigFile)
{
MyPath1 = MyPath2 = ""; // Clear the external values (in case the file does not set every parameter).
using (StreamReader sr = new StreamReader(sConfigFile)) // Open the file for reading (and auto-close).
{
while (!sr.EndOfStream)
{
string sLine = sr.ReadLine().Trim(); // Read the next line. Trim leading and trailing whitespace.
// Treat lines with NO "=" as comments (ignore; no syntax checking).
// Treat lines with "=" as the first character as comments too.
// Treat lines with "=" as the 2nd character or after as parameter lines.
// Side-benefit: Values containing "=" are processed correctly.
int i = sLine.IndexOf("="); // Find the first "=" in the line.
if (i <= 0) // IF the first "=" in the line is the first character (or not present),
continue; // the line is not a parameter line. Ignore it. (Iterate the while.)
string sParameter = sLine.Remove(i).TrimEnd(); // All before the "=" is the parameter name. Trim whitespace.
string sValue = sLine.Substring(i + 1).TrimStart(); // All after the "=" is the value. Trim whitespace.
// Extra characters before a parameter name are usually intended to comment it out. Here, we keep them (with or without whitespace between). That makes an unrecognized parameter name, which is ignored (acts as a comment, as intended).
// Extra characters after a value are usually intended as comments. Here, we trim them only if whitespace separates. (Parsing contiguous comments is too complex: need delimiter(s) and then a way to escape delimiters (when needed) within values.) Side-drawback: Values cannot contain " ".
i = sValue.IndexOfAny(new char[] {' ', '\t'}); // Find the first " " or tab in the value.
if (i > 1) // IF the first " " or tab is the second character or after,
sValue = sValue.Remove(i); // All before the " " or tab is the parameter. (Discard the rest.)
// IF a desired parameter is specified, collect it:
// (Could detect here if any parameter is set more than once.)
if (sParameter == "MyPathOne")
MyPath1 = sValue;
else if (sParameter == "MyPathTwo")
MyPath2 = sValue;
// (Could detect here if an invalid parameter name is specified.)
// (Could exit the loop here if every parameter has been set.)
} // end while
// (Could detect here if the config file set neither parameter or only one parameter.)
} // end using
}
As the title says, I am getting:
Invalid length for a Base-64 char
array.
I have read about this problem on here and it seems that the
suggestion is to store ViewState in SQL if it is large. I am
using a wizard with a good deal of data collection so chances
are my ViewState is large. But, before I turn to the "store-in-DB"
solution, maybe somebody can take a look and tell me if I have
other options?
I construct the email for delivery using the below method:
public void SendEmailAddressVerificationEmail(string userName, string to)
{
string msg = "Please click on the link below or paste it into a browser to verify your email account.<BR><BR>" +
"<a href=\"" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" +
userName.Encrypt("verify") + "\">" +
_configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" +
userName.Encrypt("verify") + "</a>";
SendEmail(to, "", "", "Account created! Email verification required.", msg);
}
The Encrypt method looks like this:
public static string Encrypt(string clearText, string Password)
{
byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
return Convert.ToBase64String(encryptedData);
}
Here is what the HTML looks like in hotmail:
Please click on the link below or
paste it into a browser to verify your
email account.
http://localhost:1563/Accounts/VerifyEmail.aspx?a=YOHY57xYRENEOu3H+FGq1Rf09AZAI56EPjfwuK8XWKg=
On the receiving end, the VerifyEmail.aspx.cs page has the line:
string username = Cryptography.Decrypt(_webContext.UserNameToVerify, "verify");
Here is the getter for UserNameToVerify:
public string UserNameToVerify
{
get
{
return GetQueryStringValue("a").ToString();
}
}
And here is the GetQueryStringValue method:
private static string GetQueryStringValue(string key)
{
return HttpContext.Current.Request.QueryString.Get(key);
}
And the decrypt method looks like:
public static string Decrypt(string cipherText, string password)
{
**// THE ERROR IS THROWN HERE!!**
byte[] cipherBytes = Convert.FromBase64String(cipherText);
Can this error be remedied with a code fix or must I store ViewState in the database?
The length of a base64 encoded string is always a multiple of 4. If it is not a multiple of 4, then = characters are appended until it is. A query string of the form ?name=value has problems when the value contains = charaters (some of them will be dropped, I don't recall the exact behavior). You may be able to get away with appending the right number of = characters before doing the base64 decode.
Edit 1
You may find that the value of UserNameToVerify has had "+"'s changed to " "'s so you may need to do something like so:
a = a.Replace(" ", "+");
This should get the length right;
int mod4 = a.Length % 4;
if (mod4 > 0 )
{
a += new string('=', 4 - mod4);
}
Of course calling UrlEncode (as in LukeH's answer) should make this all moot.
My guess is that you simply need to URL-encode your Base64 string when you include it in the querystring.
Base64 encoding uses some characters which must be encoded if they're part of a querystring (namely + and /, and maybe = too). If the string isn't correctly encoded then you won't be able to decode it successfully at the other end, hence the errors.
You can use the HttpUtility.UrlEncode method to encode your Base64 string:
string msg = "Please click on the link below or paste it into a browser "
+ "to verify your email account.<br /><br /><a href=\""
+ _configuration.RootURL + "Accounts/VerifyEmail.aspx?a="
+ HttpUtility.UrlEncode(userName.Encrypt("verify")) + "\">"
+ _configuration.RootURL + "Accounts/VerifyEmail.aspx?a="
+ HttpUtility.UrlEncode(userName.Encrypt("verify")) + "</a>";
I'm not Reputable enough to upvote or comment yet, but LukeH's answer was spot on for me.
As AES encryption is the standard to use now, it produces a base64 string (at least all the encrypt/decrypt implementations I've seen). This string has a length in multiples of 4 (string.length % 4 = 0)
The strings I was getting contained + and = on the beginning or end, and when you just concatenate that into a URL's querystring, it will look right (for instance, in an email you generate), but when the the link is followed and the .NET page recieves it and puts it into this.Page.Request.QueryString, those special characters will be gone and your string length will not be in a multiple of 4.
As the are special characters at the FRONT of the string (ex: +), as well as = at the end, you can't just add some = to make up the difference as you are altering the cypher text in a way that doesn't match what was actually in the original querystring.
So, wrapping the cypher text with HttpUtility.URLEncode (not HtmlEncode) transforms the non-alphanumeric characters in a way that ensures .NET parses them back into their original state when it is intepreted into the querystring collection.
The good thing is, we only need to do the URLEncode when generating the querystring for the URL. On the incoming side, it's automatically translated back into the original string value.
Here's some example code
string cryptostring = MyAESEncrypt(MySecretString);
string URL = WebFunctions.ToAbsoluteUrl("~/ResetPassword.aspx?RPC=" + HttpUtility.UrlEncode(cryptostring));
My initial guess without knowing the data would be that the UserNameToVerify is not a multiple of 4 in length. Check out the FromBase64String on msdn.
// Ok
byte[] b1 = Convert.FromBase64String("CoolDude");
// Exception
byte[] b2 = Convert.FromBase64String("MyMan");
The encrypted string had two special characters, + and =.
'+' sign was giving the error, so below solution worked well:
//replace + sign
encryted_string = encryted_string.Replace("+", "%2b");
//`%2b` is HTTP encoded string for **+** sign
OR
//encode special charactes
encryted_string = HttpUtility.UrlEncode(encryted_string);
//then pass it to the decryption process
...
string stringToDecrypt = CypherText.Replace(" ", "+");
int len = stringToDecrypt.Length;
byte[] inputByteArray = Convert.FromBase64String(stringToDecrypt);
While Encrypting use
HttpUtility.UrlEncode(Encryptedtext));
While Decrypting,
use
value = HttpUtility.UrlDecode(value);
value = value.Replace(" ", "+");//to remove any empty spaces
value = value.Replace('-', '+').Replace('_', '/');//replace special char
while (value.Length % 4 != 0) value += '='; //it should be divisible by 4 or append =
Then send this value for decryption