NavigationContext returning incomplete data - c#

I have a code in which i'm passing email data to another page. The email body may contain HTML.
On the second page, I have observed that when '&' or '#' etc comes into body content (while getting data from NavigationContext.QueryString.TryGetValue()), the string breaks & further data is not obtained.
Code on first page to send data:
string strParameters = string.Empty;
strParameters += "subject=" + objEmail.Subject;
strParameters += "&from=" + objEmail.FromAddress;
strParameters += "&to=";
for (int i = 0; i < objEmail.NumTo; i++)
{
strParameters += objEmail.GetToAddr(i) + "; ";
}
strParameters += "&cc=";
for (int i = 0; i < objEmail.NumCC; i++)
{
strParameters += objEmail.GetCcAddr(i) + "; ";
}
strParameters += "&body=" + objEmail.Body;
NavigationService.Navigate(new Uri("/PageReadMail.xaml?" + strParameters, UriKind.Relative));
Code on second page to receive data:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string strOriginalString = e.Uri.OriginalString;
//get data received from navigation service
string strBody = "";
string strSubject = "";
string strTo = "";
string strCc = "";
string strFrom = "";
NavigationContext.QueryString.TryGetValue("body", out strBody);
NavigationContext.QueryString.TryGetValue("subject", out strSubject);
NavigationContext.QueryString.TryGetValue("from", out strFrom);
NavigationContext.QueryString.TryGetValue("to", out strTo);
NavigationContext.QueryString.TryGetValue("cc", out strCc);
}
Here, strBody is having incomplete data.

The parameters should be Url-encoded
You should use HttpUtility.UrlEncode() or Uri.EscapeDataString() on each parameter of the Uri. Alternatively, you can use Uri.EscapeUriString() on the whole Uri.
There's a limit on the lenght of a Uri
Perhaps your string is longer and is getting trimmed? Although, I think if it was longer, it will just throw an exception, rather than trimming it, but you should check it out.
Better pass the whole email object to PageReadMail
I think it will be easier and safer to just pass the whole email object to the page, rather than converting it to a string and passing it in the Uri.
Just add a static property of type YourEmailObjectType to the PageReadMail class and set that property before you navigate to the page. Once you've navigated, get the data that for the email from that property, rather than from the navigation Uri.

You can just replace characters ('&' and '#') :
strParameters += "&body=" + objEmail.Body.Replace("&", "%26").Replace("#", "%23");

Related

C# - Unable to remove the back slashes in JSON

I am trying to construct a string which I want to use it to update a JSON.
The code is below
public string ConstructCylicLoop(string fieldName, int LoopCount, string BadDataLabel,string ImmediateParent)
{
string start = "";
string fullbody = "";
string end = "";
string body = "";
for (int i = 0; i < LoopCount; i++)
{
LoopTestData = (new ExcelUtilities().getAPITestData(ApplicationConfiguration.LoopSheetName));
body = "";
foreach (Dictionary<string, string> loopData in LoopTestData)
{
string ParentNode = "";
string Key = "";
string Data = "";
loopData.TryGetValue("ParentNode", out ParentNode);
loopData.TryGetValue("Key", out Key);
loopData.TryGetValue("Data", out Data);
if(ImmediateParent.Equals(ParentNode)) //&& Key.Equals(fieldName)
{
body = body + '"' + Key + '"' + ":" + '"' + Data + '"'+',';
}
}
body = body.Remove(body.Length - 1);
body = "{" + body + "},";
fullbody = fullbody + body;
}
fullbody = fullbody.Remove(fullbody.Length - 1);
return start + fullbody + end;
}
The issue with this code is it always returns a text like this
"{\"my_address_type\":\"primarypropertyaddress\",\"my_address-street\":\"52 Street\",\"my_address-suburb\":\"vinvent\",\"my_address-postcode\":\"2121\"}"
When I update this string to an JSON node, the server is not able to parse it and the issue is with the back slash. Is there a way to remove the back slash. so I get something like this..
"{"my_address_type":"primarypropertyaddress","my_address-street":"52 Street","my_address-suburb":"vinvent","my_address-postcode":"2121"}"
I tried all possibilities but not able to clear/remove the backslash. Any code snippet on removing the backslashes. Thanks in advance.

C# Encode connection string from win1251 to utf8 and back

I'm trying to work around the problem with connection string encoding in Firebird .net provider ver >= 5.6.0.0 (current is 5.8.0.0). The full description of the problem (if you are interested in) is here, but I think I could explain it briefly. So let's start! I have a system default encoding win1251 and a connection string that contains a param calls "DbPath" with value
"F:\\Рабочая\\БД\\2.14.1\\January_2017\\MYDB.IB"
When I pass this connection string to firebird .net provider it takes "DbPath" param from connection string and get bytes from its value using Encoding.UTF-8. That's how it looks in their code:
protected virtual void SendAttachToBuffer(DatabaseParameterBuffer dpb, string database)
{
XdrStream.Write(IscCodes.op_attach);
XdrStream.Write(0);
if (!string.IsNullOrEmpty(Password))
{
dpb.Append(IscCodes.isc_dpb_password, Password);
}
//database is DbPath
XdrStream.WriteBuffer(Encoding.UTF8.GetBytes(database));
XdrStream.WriteBuffer(dpb.ToArray());
}
As you see they don't convert encoding from win1251 to utf-8, they just get bytes using Encoding.UTF8.GetBytes();
And later in their code I see that they just get a string using current Encoding (Encoding.Default):
public string GetString(byte[] buffer, int index, int count)
{
//_encoding is Encoding.Default == win1251
return _encoding.GetString(buffer, index, count);
}
And the result of this lines of code is that I get an I/O Exception cause my DbPath becomes to
"F:\\Рабочая\\БД\\2.14.1\\January_2017\\MYDB.IB"
So the first thing that I've tried is to convert my connection string to utf-8
using this lines of code:
private static string Win1251ToUTF8(string source)
{
Encoding utf8 = Encoding.GetEncoding("utf-8");
Encoding win1251 = Encoding.GetEncoding("windows-1251");
byte[] win1251Bytes = win1251.GetBytes(source);
byte[] utf8bytes = Encoding.Convert(win1251, utf8, win1251Bytes);
source = utf8.GetString(utf8bytes);
return source;
//Actually I'm not sure that I'm converting Encoding correctly
}
But it didn't affect. I've tried many variants with Encoding.Convert but I've not a solution yet. Can someone tell me please what I'm doing wrong and how I can solve the problem. Regards.
I recommend you to try the following code, maybe it helps you. Create a new C# WindowsFormApplication, put a BIG multiline texBox "textBox1" and a button "button1" on it. In the button click handler put this code:
// ----- The work -------------------------------------------------
string source = "F:\\\\Рабочая\\\\БД\\\\2.14.1\\\\January_2017\\\\MYDB.IB";
Encoding utf8 = Encoding.UTF8;
Encoding unicode = Encoding.Unicode;
Encoding win1251 = Encoding.GetEncoding("windows-1251");
byte[] utf8Bytes = utf8.GetBytes(source);
byte[] win1251Bytes = win1251.GetBytes(source);
byte[] utf8ofwinBytes = Encoding.Convert(win1251, utf8, win1251Bytes);
string unicodefromutf8 = utf8.GetString(utf8Bytes);
string unicodefromwin1251 = win1251.GetString(win1251Bytes);
// ----- The show -------------------------------------------------
textBox1.Text = "";
textBox1.Text += "Literal Unicode soource" + Environment.NewLine;
textBox1.Text += source + Environment.NewLine + Environment.NewLine;
string s1 = "";
textBox1.Text += "UTF8" + Environment.NewLine;
for (int i = 0; i < utf8Bytes.Length; i++)
{
s1 += utf8Bytes[i].ToString() + ", ";
}
textBox1.Text += s1 + Environment.NewLine + Environment.NewLine;
s1 = "";
textBox1.Text += "WIN 1251" + Environment.NewLine;
for (int i = 0; i < win1251Bytes.Length; i++)
{
s1 += win1251Bytes[i].ToString() + ", ";
}
textBox1.Text += s1 + Environment.NewLine + Environment.NewLine;
s1 = "";
textBox1.Text += "UTF8 of WIN 1251" + Environment.NewLine;
for (int i = 0; i < utf8ofwinBytes.Length; i++)
{
s1 += utf8ofwinBytes[i].ToString() + ", ";
}
textBox1.Text += s1 + Environment.NewLine + Environment.NewLine;
textBox1.Text += "Unicode string of UTF8 bytes" + Environment.NewLine;
textBox1.Text += unicodefromutf8 + Environment.NewLine + Environment.NewLine;
textBox1.Text += "Unicode string of WIN 1251 bytes" + Environment.NewLine;
textBox1.Text += unicodefromwin1251 + Environment.NewLine + Environment.NewLine;
Run it, click the button and you will see, all converting, encoding is done as it should.
You asked for a way to convert Unicode to UTF8 to WIN1251 to UTF8 to UNICODE - here it is.
Your misunderstanding may be:
source = utf8.GetString(utf8bytes);
return source;
This will convert the created UTF8 byte sequence array to an Unicode string. So you return an Unicode string, not a UTF8-byte-sequence of your win-1251 string. Exactly, you return the same string you get.
You have to push the (proper zero terminated) UTF8-byte-sequence to the .Net provider.
Use Encoding.Convert to convert charsets:
Encoding utf8 = Encoding.UTF8;
Encoding win = Encoding.GetEncoding("windows-1251");
byte[] winBytes = win.GetBytes(source);
byte[] utfBytes = Encoding.Convert(win, utf8, winBytes);
string result = utf8.GetString(utfBytes);

Encoding of POST Data

I am programatically trying to POST to a web-service. The issue I face is with my data that I post.
Despite
string post_data = "man=HE&game=01&&address=123 Main St.&cap=1,2,3,4";
new ASCIIEncoding().GetBytes( post_data )
it is not getting converted to
man=HE&game=01&&address=123+Main+St.&cap=1%2C2%2C3%2C4
What is the best way to resolve this?
You are only getting a byte stream that way. In order to URL encode the string you could use the URLEncode method of the HttpUtility helper class:
string post_data = "man=HE&game=01&&address=123 Main St.&cap=1,2,3,4";
string[] postTokens = post_data.Split(new Char [] {'&'});
for(int i = 0; i < postTokens.Length; i++)
{
int pos = postTokens[i].IntexOf("=");
string name = postTokens[i].Substring(0, pos);
string value = postTokens[i].Substring(pos + 1);
postTokens[i] = String.Format("{0}={1}", name, HttpUtility.UrlEncode(value));
}
string encodedPostData = String.Join("=", postTokens);
var encodedPostDataBytes = ASCIIEncoding.GetBytes(encodedPostData);
I think you're confusing ascii encoding with url encoding.
You'll want to use System.Web.HttpServerUtility.UrlEncode method and encode each element of the query string separately.
string post_data =
"man=" + HttpUtility.UrlEncode("HE") +
"&game=" + HttpUtility.UrlEncode("01") // and so forth

Payment succeeds, and our data matches querystring data, but falls thru to INVALID anyway!

Why does my ipn script I wrote always fail? It always goes to INVALID even though it matches everything in the query string that paypal sends to me?
notification.cshtml?tx=b78v54b5b55rby92S&st=Completed&amt=3.04&cc=USD&cm=&item_number=&merchant_return_link=Return+to+web+site+name&form_charset=UTF-8
And the part that checks it is:
string LiveURL = "https://www.paypal.com/cgi-bin/webscr";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(LiveURL);
// Set request back values.
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] parameters = Request.BinaryRead(HttpContext.Current.Request.ContentLength);
string RequestString = System.Text.Encoding.ASCII.GetString(parameters);
RequestString += "&cmd=_notify-validate";
request.ContentLength = RequestString.Length;
// Send request to PP and get response.
StreamWriter Sout = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
Sout.Write(RequestString);
Sout.Close();
StreamReader Sin = new StreamReader(request.GetResponse().GetResponseStream());
string response = Sin.ReadToEnd();
Sin.Close();
if(result != null && result.OrderStatus == "Confirmed")
{
switch(response)
{
case "VERIFIED":
if(Request["st"] == "Completed")
{
var PPQuery = "SELECT TransactionId, OrderTotal FROM Orders WHERE OrderId = '" + Session["OSFOID"] + "' AND UserId = '" + WebSecurity.CurrentUserId + "'";
var ppQueryResult = database.Query(PPQuery);
foreach(var item in ppQueryResult)
{
decimal fff = 3.04M;
if(item["TransactionId"] != Request["tx"])
{
if(item["OrderTotal"] == TotalPrice)
{
// Payment was a success. Convey that to the user.
output = "Thanks. Order complete.";
}
else
{
// Possible fraud. Log it.
}
}
else
{
// This is a duplicate transaction. Log it and Redirect to homepage.
}
}
}
break;
case "INVALID":
output = "Invalid was returned. Investigate further.";
break;
default:
output = "Other exception has occured. Investigate further and log.";
break;
}
}
The code looks fine. The problem must be with response not matching "VERIFIED".
You're not in Turkey by chance, and changing response to uppercase prior to the comparison? *
*) If the locale is Turkey, uppercasing a string turns i into İ, not I (just one of the many traps with string manipulation)
Within the "VERIFIED" block, check:
if (Request.Params["payment_status"] == "Completed")
{
...
}
Request["st"] is incorrect.
Be sure to set IPN URL in one place in PayPal admin and do not use the other form of return URL checking (can't remember the name of it offhand) and IPN at the same time.
There is no "merchant_return_link" parameter; I think it should be "notify_url"... the URL string and the list of params doesn't look right to me; for example: &cm=&item_number
I know your list of params will be unique for your situation, but here's some sample code where I construct the URL to be passed to PayPal:
protected string GetPayPalURL(string SERVER_URL, string business, string[] itemNames,
int[] quantities, decimal[] amounts, double[] weight, string invoiceID, string transID, string NOTIFY_URL)
{
// Customer will be required to specify delivery address to PayPal - VERY IMPORTANT
const string NO_SHIPPING = "2";
StringBuilder url = new StringBuilder();
url.Append(SERVER_URL + "?cmd=_cart&upload=1");
url.Append("&business=" + HttpUtility.UrlEncode(business));
for (int i = 0; i < itemNames.Length; i++)
{
url.Append("&item_name" + "_" + (i + 1).ToString() + "=" + HttpUtility.UrlEncode(itemNames[i]));
url.Append("&quantity" + "_" + (i + 1).ToString() + "=" + quantities[i].ToString().Replace(",", "."));
url.Append("&amount" + "_" + (i + 1).ToString() + "=" + amounts[i].ToString().Replace(",", "."));
url.Append("&weight" + "_" + (i + 1).ToString() + "=" + weight[i].ToString().Replace(",", "."));
}
url.Append("&no_shipping=" + HttpUtility.UrlEncode(NO_SHIPPING));
url.Append("&custom=" + HttpUtility.UrlEncode(invoiceID));
url.Append("&txn_id=" + HttpUtility.UrlEncode(transID));
url.Append("&notify_url=" + HttpUtility.UrlEncode(NOTIFY_URL));
return url.ToString();
}
I think the Paypal method you are trying to do is as follows on code project
and if you get payment_status = INVALID, then check the reason in payment_reason
i dont see in the code where you are defining result which is checked in the if, also in the switch you are checking against request, surely this should be against response?

How to call a JavaScript function multiple times in a loop on page reload with ASP.NET

I'm using the local database functionality in Chrome and Safari and what I do when I want to save this to a remote database is to create a hidden textfield and then using JSON to stringify each row. In the code behind I then parse each JSON object and insert it into the list. What I want to do now is to delete these rows from the local database. I have a JavaScript function called deletePatient:
function deletePatient(patientID) {
MaRDB.transaction(
function (transaction) {
transaction.executeSql("DELETE FROM Patients WHERE id = " + patientID + ";");
}
);
}
I then call this function from the code behind if the insert was successfull
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Delete", "<script language='javascript'>$(document).ready(function() {deletePatient(" + id + ");});</script>");
However, it only deletes the patient with the lowest ID (the first JSON object). When I step through the code it goes back to that code for each ID but only deletes one. If I try with an alert it also only shows one ID even though it iterates through the code N number of times. I guess it's some kind of conflict with postback and executing a JavaScript function here but is it possible to solve?
protected void btnSave_Click(object sender, EventArgs e)
{
bool successfullySent = false;
SharePointConnection();
int count = Convert.ToInt32(txtRows.Text);
for (int i = 0; i <= count; i++)
{
string p = String.Format("{0}", Request.Form["hiddenField" + i]).ToString();
JObject o = JObject.Parse(p);
id = (int)o["id"];
string name = (string)o["name"];
string address = (string)o["address"];
string city = (string)o["city"];
string state = (string)o["state"];
string zip = (string)o["zip"];
string country = (string)o["country"];
string phone = (string)o["phone"];
StringBuilder sb_method = new StringBuilder();
sb_method.Append("<Method ID='1' Cmd='New'>");
sb_method.Append("<Field Name='Title'>" + name + "</Field>");
sb_method.Append("<Field Name='Address'>" + address + "</Field>");
sb_method.Append("<Field Name='City'>" + city + "</Field>");
sb_method.Append("<Field Name='State'>" + state + "</Field>");
sb_method.Append("<Field Name='ZIP'>" + zip + "</Field>");
sb_method.Append("<Field Name='Country'>" + country + "</Field>");
sb_method.Append("<Field Name='Phone'>" + phone + "</Field>");
sb_method.Append("</Method>");
XmlDocument x_doc = new XmlDocument();
XmlElement xe_batch = x_doc.CreateElement("Batch");
xe_batch.SetAttribute("OnError", "Continue");
xe_batch.InnerXml = sb_method.ToString();
try
{
//updating the list
XmlNode xn_return = listsObj.UpdateListItems(ConfigurationManager.AppSettings["SaveToSPList"].ToString(), xe_batch);
if (xn_return.InnerText == "0x00000000")
{
successfullySent = true;
}
else
{
successfullySent = false;
}
}
catch
{
successfullySent = false;
}
if (successfullySent)
{
divSuccessfulMessage.Visible = true;
lblSuccessfulMessage.Text = "Report Successfully Saved";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Delete", "<script language='javascript'>$(document).ready(function() {deletePatient(" + id + ");});</script>");
}
else
{
divErrorMessage.Visible = true;
lblErrorMessage.Text = "Failed to Save, Please Try Again";
}
}
}
Thanks in advance.
I'm assuming you're calling the RegisterClientScriptBlock multiple times? In that case, the second parameter of your RegisterClientScriptBlock is the unique key of the script you're trying to inject. Since its always the same, in effect you're basically 'overwriting' each previous script with the latest one.
Try it again, and make sure your key is unique every time you call the RegisterClientScriptBlock (for example, append a counter to it?).
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Delete" + counter.ToString(), "<script language='javascript'>$(document).ready(function() {deletePatient(" + id + ");});</script>");

Categories

Resources