C# Base-64 error when logging into server - c#

I was testing my own method of logging into a database last night for a program I am working on and everything was fine. When I tried logging into the database this morning I get a Base-64 error. Here is the error in its entirety.
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
Before I put the program into production I need to fix this error but I cannot figure out what is causing it. Here is the login code (I am excluding the real server address and real encryption keys for security but it shouldn't make a difference).
private void login_Click(object sender, EventArgs e)
{
try
{
WebRequest request_user = WebRequest.Create("server address here");
WebResponse response_user = request_user.GetResponse();
StreamReader sr_user = new StreamReader(response_user.GetResponseStream());
string user = RC4.Decrypt("encryption key here", sr_user.ReadToEnd());
//show("Client: " + username.Text + "\nServer: " + user);
WebRequest request_pass = WebRequest.Create("server address here");
WebResponse response_pass = request_pass.GetResponse();
StreamReader sr_pass = new StreamReader(response_pass.GetResponseStream());
string pass = RC4.Decrypt("encryption key here", sr_pass.ReadToEnd());
//show("Client: " + password.Text + "\nServer: " + pass);
WebRequest request_key1 = WebRequest.Create("server address here");
WebResponse response_key1 = request_key1.GetResponse();
StreamReader sr_key1 = new StreamReader(response_key1.GetResponseStream());
string key1 = RC4.Decrypt("encryption key here", sr_key1.ReadToEnd());
//show("Client: " + RC4.Decrypt("encryption key here", AuthKey1) + "\nServer: " + key1);
WebRequest request_key2 = WebRequest.Create("server address here");
WebResponse response_key2 = request_key2.GetResponse();
StreamReader sr_key2 = new StreamReader(response_key2.GetResponseStream());
string key2 = RC4.Decrypt("encryption key here", sr_key2.ReadToEnd());
//show("Client: " + RC4.Decrypt("encryption key here", AuthKey2) + "\nServer: " + key2);
WebRequest request_ipv4 = WebRequest.Create("server address here");
WebResponse response_ipv4 = request_ipv4.GetResponse();
StreamReader sr_ipv4 = new StreamReader(response_ipv4.GetResponseStream());
string ipv4 = sr_ipv4.ReadToEnd();
//show("Client: " + IPAddress + "\nServer: " + ipv4);
if (user.Contains(username.Text) && pass.Contains(password.Text) && key1.Contains(RC4.Decrypt("encryption key here", AuthKey1)) && key2.Contains(RC4.Decrypt("encryption key here", AuthKey2)) && ipv4.Contains(IPAddress))
{
WebRequest request_tu = WebRequest.Create("server address here");
WebResponse response_tu = request_tu.GetResponse();
StreamReader sr_tu = new StreamReader(response_tu.GetResponseStream());
string tu = sr_tu.ReadToEnd();
show("Successfully logged into the Grand Theft Rape Server!\nCurrent TU: " + tu);
}
else
{
show("Username and/or Password incorrect!");
}
}
catch (Exception ex)
{
show(ex.Message);
}
}

Related

Insert Data using Json in C#

I have some problem in inserting data to my free webhost mysql using JSON in C#. This is what I have done :
Php
<?php
/*
* Following code will create a new product row
* All product details are read from HTTP REQUEST Request
*/
require_once __DIR__ . '/db_connect.php';
//require_once __DIR__ . '/generateIDrandom.php';
require_once __DIR__ . '/Configuration.php';
$db = new DB_CONNECT();
$connstring = mysqli_connect(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);
// array for JSON response
$response = array();
// check for required fields
if (isset($_REQUEST['WSID'])) {
$wsid = $_REQUEST['WSID'];
$jenismesin = $_REQUEST['JenisMesin'];
$merk = $_REQUEST['MerkMesin'];
$lokasi = $_REQUEST['Lokasi'];
$inlok = $_REQUEST['InisialLokasi'];
$limit = $_REQUEST['LimitMesin'];
$denom = $_REQUEST['Denom'];
$tim4 = $_REQUEST['Tim4'];
$tim5 = $_REQUEST['Tim5'];
$status = "1";
// connecting to db
$result = mysqli_query($connstring, "insert into MasterATM (WSID, JenisMesin, MerkMesin, Lokasi, InisialLokasi, LimitMesin, Denom, Tim4, Tim5, Status) values ('$wsid','$jenismesin','$merk','$lokasi', '$inlok', '$limit', '$denom','$tim4','$tim5','$status')");
// check if row inserted or not
if ($result) {
// successfully inserted into database
$response["success"] = 1;
$response["message"] = "Upload Successfully";
// echoing JSON response
echo json_encode($response);
} else {
// failed to insert row
$response["success"] = 0;
$response["message"] = "Oops! An error occurred.";
// echoing JSON response
echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";
// echoing JSON response
echo json_encode($response);
}
?>
C#
private void InputBtn_Click(object sender, EventArgs e)
{
try
{
WebRequest request = WebRequest.Create("https://xxx.000webhostapp.com/php/InsertDataMesin.php?WSID =" + WSIDBox.Text + "& JenisMesin = " + TipeMesinBox.SelectedItem + "& MerkMesin = " + MerkMesinCB.SelectedItem + "& Lokasi= " + LokasiBox.Text + "& InisialLokasi = " + InisialLokasiBox.Text + "& LimitMesin= " + LimitBox.Text + "& Denom= " + DenomBox.Text + "& Tim4= '" + Tim4CB.SelectedItem + "& Tim5= '" + Tim5CB.SelectedItem + "& Status = 1");
WebResponse response = request.GetResponse();
StreamReader stream = new StreamReader(response.GetResponseStream());
string json = stream.ReadToEnd();
stream.Close();
var result = JsonConvert.DeserializeObject(json);
MessageBox.Show("Data berhasil ditambahkan !");
TampilDataEdit();
}
catch
{
MessageBox.Show("Data gagal ditambahkan. Silakan coba lagi");
}
}
When I run my program, there is no some error. But when I see to my database, there is no data inserted. So, How can I insert data using json c# ?

How to add a contact to Yahoo using Oauth-2 in Asp.Net C#

I've been wrestling with this for a while now and can't seem to find a solution. The closest I've come is PHP code for Oauth-1 by Joe Chung (https://github.com/joechung/oauth_yahoo), but I can't get my head wrapped around it.
I'm using Asp.Net, and this code is in the ContactController. I have no trouble Getting contacts from Yahoo. The problem is Adding a contact to a user's Yahoo address book. The program proceeds through the Yahoo login process, and there are no errors. But the contact is not saved. I hope someone can take a look at this and tell me what I'm missing.
Thanks.
private string AddYahooContact(string responseFromServer, string contactIdForYahoo)
{
// Some of this from http://www.yogihosting.com/implementing-yahoo-contact-reader-in-asp-net-and-csharp/
responseFromServer = responseFromServer.Substring(1, responseFromServer.Length - 2);
string accessToken = "", xoauthYahooGuid = "", refreshToken = "";
string[] splitByComma = responseFromServer.Split(',');
foreach (string value in splitByComma)
{
if (value.Contains("access_token"))
{
string[] accessTokenSplitByColon = value.Split(':');
accessToken = accessTokenSplitByColon[1].Replace('"'.ToString(), "");
}
else if (value.Contains("xoauth_yahoo_guid"))
{
string[] xoauthYahooGuidSplitByColon = value.Split(':');
xoauthYahooGuid = xoauthYahooGuidSplitByColon[1].Replace('"'.ToString(), "");
}
else if (value.Contains("refresh_token"))
{
string[] refreshTokenSplitByColon = value.Split(':');
refreshToken = refreshTokenSplitByColon[1].Replace('"'.ToString(), "");
}
}
// How to build contactUrl from https://developer.yahoo.com/social/rest_api_guide/contacts-resource.html#contacts-xml_request_put
// This is Yahoo's address to add a contact
string contactUrl = "https://social.yahooapis.com/v1/user/" + xoauthYahooGuid + "/contacts";
// Much of this from https://developer.yahoo.com/dotnet/howto-rest_cs.html
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(contactUrl);
webRequest.Method = "POST";
webRequest.Headers["Authorization"] = "Bearer " + accessToken;
webRequest.ContentType = "application/x-www-form-urlencoded"; // Tried "application/x-www-form-urlencoded & application/xml" & "text/xml".
// Create the data we want to send
string yahooContact = BuildYahooContact(contactIdForYahoo);
byte[] byteData = UTF8Encoding.UTF8.GetBytes(yahooContact);
webRequest.ContentLength = byteData.Length;
using (Stream postStream = webRequest.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
responseFromServer = "";
try
{
using (HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
responseFromServer = reader.ReadToEnd();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return yahooContact;
}
private string BuildYahooContact(string contactIdForYahoo)
{
Guid contactId = Guid.Parse(contactIdForYahoo);
Models.Contact contact = GetContactForId(contactId); // And find the contact
string firstName = "";
string lastName = "";
if (contact.FullName != null)
{
int index = contact.FullName.IndexOf(" ");
if (index > 0)
{
firstName = contact.FullName.Substring(0, index);
lastName = (contact.FullName.Substring(index + 1));
}
else
{
lastName = contact.FullName;
}
}
StringBuilder data = new StringBuilder();
data.Append("<contact>");
data.Append("<fields><type>name</type><value>");
data.Append("<givenName>" + firstName + "</givenName><middleName/>");
data.Append("<familyName>" + lastName + "</familyName>");
data.Append("<prefix/><suffix/><givenNameSound/><familyNameSound/>");
data.Append("</value></fields>");
data.Append("<fields><type>address</type>");
data.Append("<value><street>" + contact.Address + "</street>");
data.Append("<city>" + contact.City + "</city>");
data.Append("<stateOrProvince>" + contact.State + "</stateOrProvince>");
data.Append("<postalCode>" + contact.Zip + "</postalCode>");
data.Append("<country>United States</country>");
data.Append("<countryCode>US</countryCode>");
data.Append("</value></fields>");
data.Append("<fields><type>notes</type><value>" + contact.Note + "</value></fields>");
data.Append("<fields><type>link</type><value>" + contact.Website + "</value></fields>");
data.Append("<fields><type>email</type><value>" + contact.Email + "</value></fields>");
data.Append("<fields><type>phone</type><value>" + contact.BusinessPhone + "</value><flags>WORK</flags></fields>");
data.Append("<fields><type>phone</type><value>" + contact.BestPhone + "</value><flags>MOBILE</flags></fields>");
data.Append("<fields><type>phone</type><value>" + contact.SecondPhone + "</value><flags>PERSONAL</flags></fields>");
data.Append("<categories><category><name>GoGoContract</name></category></categories>");
data.Append("</contact>");
return data.ToString();
}

Screen Scraping - By pass Captcha Validation by code [ traffic issue ]

I am doing one screen scraping project in asp.net using c#, And I can scrap the screen successfully.
But I have to make one by one multiple requests to the targeted server, but after some time server redirects to Captcha validation page, at that time I stuck.
Here is my code :
public static string SearchPage(Uri url, int timeOutSeconds)
{
StringBuilder sb = new StringBuilder();
try
{
string place = HttpUtility.ParseQueryString(url.Query).Get("destination").Split(':')[1];
string resultID = HttpUtility.ParseQueryString(url.Query).Get("resultID");
string checkin = HttpUtility.ParseQueryString(url.Query).Get("checkin").Replace("-", "");
string checkout = HttpUtility.ParseQueryString(url.Query).Get("checkout").Replace("-", "");
string Rooms = HttpUtility.ParseQueryString(url.Query).Get("Rooms");
string adults_1 = HttpUtility.ParseQueryString(url.Query).Get("adults_1");
string languageCode = "EN";
string currencyCode = "INR";
string ck = "languageCode=" + languageCode + "; a_aid=400; GcRan=1; __RequestVerificationToken=IHZjc7KM_LbUXRypz02LoK4wmeLNcmRpIr-6vmPl5eNepILScAc15vn0TgQJtmABgedDy8xz4bnkqC30_zUGE1A1SaA1; Analytics=LandingID=place:77469:0m&LanguageCode=" + languageCode + "&WebPageID=9; Tests=165F000901000A1100F81000FE110100000102100103100104000105100052; dcid=dal05; currencyCode=" + currencyCode + "; countryCode=" + languageCode + "; search=place:" + place + "#" + checkin + "#" + checkout + "#" + adults_1 + "; SearchHistory=" + place + "%" + checkin + "%" + checkout + "%" + adults_1 + "%" + currencyCode + "%%11#" + place + "%" + checkin + "%" + checkout + "%" + adults_1 + "%" + currencyCode + "%%" + resultID + "#; visit=date=2015-11-23T18:26:05.4922127+11:00&id=45111733-acef-47d1-aed3-63cef1a60591; visitor=id=efff4190-a4a0-41b5-b807-5d18e4ee6177&tracked=true";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = timeOutSeconds * 1000;
request.ReadWriteTimeout = timeOutSeconds * 1000;
request.KeepAlive = true;
request.Method = "GET";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36 OPR/33.0.1990.115";
request.Headers.Add("Accept-Language", "en-US,en;q=0.8");
request.Headers.Add("Cookie", ck);
request.Headers.Add("Upgrade-Insecure-Requests", "1");
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream());
string line = reader.ReadToEnd();
sb.Append(line);
sb.Replace("<br/>", Environment.NewLine);
sb.Replace("\n", Environment.NewLine);
sb.Replace("\t", " ");
reader.Close();
reader.Dispose();
request.Abort();
}
catch (Exception ex)
{
//throw ex;
}
return sb.ToString();
}
This code works successfully but after some requests it stuck because may be server allows some limited requests.

Twitter POST problems using api 1.1

We've just changed to Twitter api 1.1, and now Tweeting doesn't work & returns an error "The remote server returned an error: (400) Bad Request." Researching on SO about this suggests that it's something to do with authentication, but we are sending the accessToken & secret which we've just got from the login page. It all worked fine with api 1.0. The code is -
public void Tweet(Action<string> response, string message)
{
StringBuilder sb = new StringBuilder();
sb.Append("POST&");
sb.Append(Uri.EscapeDataString(_postUrl));
sb.Append("&");
string oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
string timeStamp = MakeTimestamp();
var dict = new SortedDictionary<string, string>
{
{ "oauth_consumer_key", _oAuthConfig.ConsumerKey },
{ "oauth_nonce", oauthNonce },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", timeStamp },
{ "oauth_token", _accessToken },
{ "oauth_version", "1.0" },
};
foreach (var keyValuePair in dict)
{
sb.Append(Uri.EscapeDataString(string.Format("{0}={1}&", keyValuePair.Key, keyValuePair.Value)));
}
string encodedMessage = EscapeAdditionalChars(Uri.EscapeDataString(message));
sb.Append(Uri.EscapeDataString("status=" + encodedMessage));
string signatureBaseString = sb.ToString();
// create the signature
string signatureKey = Uri.EscapeDataString(_oAuthConfig.ConsumerSecret) + "&" + Uri.EscapeDataString(_accessTokenSecret);
var hmacsha1 = new HMACSHA1(new ASCIIEncoding().GetBytes(signatureKey));
string signatureString = Convert.ToBase64String(hmacsha1.ComputeHash(new ASCIIEncoding().GetBytes(signatureBaseString)));
// create the headers
string authorizationHeaderParams = String.Empty;
authorizationHeaderParams += "OAuth ";
authorizationHeaderParams += "oauth_consumer_key=\"" + _oAuthConfig.ConsumerKey + "\", ";
authorizationHeaderParams += "oauth_nonce=\"" + oauthNonce + "\", ";
authorizationHeaderParams += "oauth_signature=\"" + Uri.EscapeDataString(signatureString) + "\", ";
authorizationHeaderParams += "oauth_signature_method=\"" + "HMAC-SHA1" + "\", ";
authorizationHeaderParams += "oauth_timestamp=\"" + timeStamp + "\", ";
authorizationHeaderParams += "oauth_token=\"" + _accessToken + "\", ";
authorizationHeaderParams += "oauth_version=\"" + "1.0" + "\"";
string messageToPost = EscapeAdditionalChars(SpacesToPlusSigns(message));
// initialise the WebClient
WebClient client = new WebClient();
client.Headers [HttpRequestHeader.Authorization] = authorizationHeaderParams;
client.UploadDataCompleted += (s, eArgs) =>
{
if (eArgs.Error == null)
response(DefaultSuccessMessage());
else
response(eArgs.Error.Message);
};
try
{
Uri uri = new Uri(_postUrl);
try
{
client.UploadDataAsync(uri, "POST", Encoding.UTF8.GetBytes("status=" + messageToPost));
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
// Can happen if we had already favorited this status
Log.Info("TwitterService->Tweet error: " + e.Message);
response(DefaultErrorMessage());
}
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error 2: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
Log.Info("TwitterService->Tweet error 2: " + e.Message);
response(DefaultErrorMessage());
}
}
Basically, I'd like to be able to Tweet without using any 3rd party libraries such as Twitterizer (even TweetStation seems to be broken with api 1.1) - surely it can't be that difficult!
Any help much appreciated, as it feels a bit like a brick wall at the moment - I'm also fairly new to c#, which doesn't help...
Edited to show code which wasn't clear previously.
Finally found the solution, as usual with most of these things, it was pretty simple. Code below -
public void Tweet(Action<string> response, string message)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat ("status={0}", PercentEncode(message));
string content = sb.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_postUrl);
request.Headers.Add("Authorization", AuthorizeRequest(_accessToken, _accessTokenSecret, "POST", new Uri(_postUrl), content));
request.ContentType = "application/x-www-form-urlencoded";
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
try
{
try
{
using (Stream stream = request.GetRequestStream())
{
Byte[] streamContent = Encoding.UTF8.GetBytes("status=" + PercentEncode(message));
stream.Write(streamContent, 0, streamContent.Length);
}
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
string contents = "";
using (Stream stream = webResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
contents = reader.ReadToEnd();
}
Console.WriteLine("Twitter response: " + contents);
response(DefaultSuccessMessage());
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
// Can happen if we had already favorited this status
Log.Info("TwitterService->Tweet error: " + e.Message);
response(DefaultErrorMessage());
}
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error 2: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
Log.Info("TwitterService->Tweet error 2: " + e.Message);
response(DefaultErrorMessage());
}
}
private string AuthorizeRequest(string oauthToken, string oauthTokenSecret, string method, Uri uri, string data)
{
string oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var headers = new Dictionary<string, string>()
{
{ "oauth_consumer_key", _oAuthConfig.ConsumerKey },
{ "oauth_nonce", oauthNonce },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", MakeTimestamp() },
{ "oauth_token", oauthToken },
{ "oauth_verifier", PercentEncode(_authorizationVerifier) },
{ "oauth_version", "1.0A" }
};
var signatureHeaders = new Dictionary<string,string>(headers);
// Add the data and URL query string to the copy of the headers for computing the signature
if (data != null && data != "")
{
var parsed = HttpUtility.ParseQueryString(data);
foreach (string k in parsed.Keys)
{
signatureHeaders.Add(k, PercentEncode(parsed [k]));
}
}
var nvc = HttpUtility.ParseQueryString(uri.Query);
foreach (string key in nvc)
{
if (key != null)
signatureHeaders.Add(key, PercentEncode(nvc [key]));
}
string signature = MakeSignature (method, uri.GetLeftPart(UriPartial.Path), signatureHeaders);
string compositeSigningKey = MakeSigningKey(_oAuthConfig.ConsumerSecret, oauthTokenSecret);
string oauth_signature = MakeOAuthSignature(compositeSigningKey, signature);
headers.Add ("oauth_signature", PercentEncode(oauth_signature));
return HeadersToOAuth(headers);
}
private static string PercentEncode (string s)
{
var sb = new StringBuilder ();
foreach (byte c in Encoding.UTF8.GetBytes (s))
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~')
sb.Append ((char) c);
else
{
sb.AppendFormat ("%{0:X2}", c);
}
}
return sb.ToString ();
}
private static string MakeTimestamp ()
{
return ((long) (DateTime.UtcNow - _unixBaseTime).TotalSeconds).ToString ();
}
private static string MakeSignature (string method, string base_uri, Dictionary<string,string> headers)
{
var items = from k in headers.Keys orderby k
select k + "%3D" + PercentEncode (headers [k]);
return method + "&" + PercentEncode (base_uri) + "&" +
string.Join ("%26", items.ToArray ());
}
private static string MakeSigningKey (string consumerSecret, string oauthTokenSecret)
{
return PercentEncode (consumerSecret) + "&" + (oauthTokenSecret != null ? PercentEncode (oauthTokenSecret) : "");
}
private static string MakeOAuthSignature (string compositeSigningKey, string signatureBase)
{
var sha1 = new HMACSHA1 (Encoding.UTF8.GetBytes (compositeSigningKey));
return Convert.ToBase64String (sha1.ComputeHash (Encoding.UTF8.GetBytes (signatureBase)));
}
private static string HeadersToOAuth (Dictionary<string,string> headers)
{
return "OAuth " + String.Join (",", (from x in headers.Keys select String.Format ("{0}=\"{1}\"", x, headers [x])).ToArray ());
}
With Twitter api 1.0, I used a WebClient to post, that doesn't work with api 1.1, and it seems that the reason for this is that you can't set the ContentType or the ServicePoint.Expect100Continue properties - without these set as I've set them, the request is sent back as (401) unauthorized. Nothing to do with encoding problems in the end.
Thanks to others for the various helper methods.
I had exactly the same problem:
This is exactly what you need to do here:
Authenticate and request a user's timeline with Twitter API 1.1 oAuth
I have created a project for this at : https://github.com/andyhutch77/oAuthTwitterTimeline
It also includes an MVC, Web app and console demo.
I ran into this problem, or at least one striking similiar (from my noob perspective), recently for an app I am building. What seemed to solve it for me (after looking at the tool at dev.twitter.com) was simply to get rid of the quotes around the parameter names, so that (in your case):
I notice that you do in fact not have quotes around your parameter names. However, it confuses me that you send authentication details twice (hence my wrongheaded post.) It works for me without doing this, and I googled it briefly and found: https://dev.twitter.com/discussions/12322#comment-27120, which confirms this can be a problem generating an Authetication Error.
400 means you are not authenticated. I recommend getting user context.
https://dev.twitter.com/docs/auth/oauth#user-context

Sending/Fowarding Emails with duplicate subject line using WebDav in C#

I have some code that uses the WEBDAV 'SEARCH' method to retrieve emails from an an Exchange Mailboxs 'Inbox' folder - my code takes the the innerXML of the HTTPWebRquests WEBresponse.
Using 'selectingSingleNode' on these namsspaces:
'urn:schemas:httpmail' & urn:schemas:mailheader
Alows me to extract the elements:
f:textdescription
d:fromd:subject
f:datareceived...and so on
I then create a collection of these details in a list and using the 'Subject' along with the URI use the 'PUT' method to recreate these messages in the 'draft's folder before using the 'MOVE' to send the mails (puts them in the sent items using '/##DavMailSubmissionURI##/"' statement.
The problem i have is the nature of the emails i am dealing with tend to come in with the same subject line so it gets confused with which emails have been sent/or not.
Does anyone know of a way around this, I dont know why the 'PUT' relies on the Subject line for the URI to the mail resource rather than say the HREF tag which is unique. Any ideas:
Code is below:
public class EmailReaderWebDav
{
public enum enmHTTPType
{
HTTP,
HTTPS,
}
private String strServer { get; set; } //"mail1" ------ Exchange server name
public String strPassword { get; set; } //"password" ------ Account Domain Password
public String strDomain { get; set; } //"mydocmian" ------ Domain
public String strMailBox { get; set; } //"mymailbox" ------ UserName
public String mailFolder { get; set; } //"inbox" ------ Mail Folder
private String httpProtocol { get; set; } //http:// ? or https://
private String mailboxURI { get; set; } //httpprotocol// + strserver + "/exhange/" + strmailbox
public List<MailStruct > ListOfEmailDetails { get; private set; }
private String strQuerySearch { get; set; }
public EmailReaderWebDav(String serverName, String domain, String mailBox, String password, String mailmailFolder,enmHTTPType HTTPType)
{
strServer = serverName;
strDomain = domain;
strMailBox = mailBox;
strPassword = password;
mailFolder = mailmailFolder;
httpProtocol = (HTTPType == enmHTTPType.HTTPS) ? "https://" : "http://";
mailboxURI = httpProtocol + strServer + "/exchange/" + strMailBox + "/inbox/";
}
public void forwardEmails(List<MailStruct> emailsToSend)
{
emailsToSend.ForEach(x => SendEmail(x,enmHTTPType.HTTP ));
}
public void MakeListofEmailsToForward()
{
String tmpQuery =
"<?xml version=\"1.0\"?>"
+ "<D:searchrequest xmlns:D = \"DAV:\" >"
+ "<D:sql>"
+ " SELECT "
+ "\"urn:schemas:mailheader:to\","
+ "\"urn:schemas:mailheader:from\","
+ "\"urn:schemas:mailheader:subject\","
+ "\"urn:schemas:httpmail:datereceived\","
+ "\"urn:schemas:httpmail:textdescription\""
+ " FROM \"" + mailboxURI + "\""
+ " WHERE \"DAV:ishidden\" = false AND \"DAV:isfolder\" = false"
+ "</D:sql>"
+ "</D:searchrequest>";
// Search Request to get emails from target folder.
HttpWebRequest SearchRequest = MakeWebRequest("SEARCH", "text/xml", mailboxURI);
Byte[] bytes = Encoding.UTF8.GetBytes((String)tmpQuery);
SearchRequest.ContentLength = bytes.Length;
Stream SearchRequestStream = SearchRequest.GetRequestStream();
SearchRequestStream.Write(bytes, 0, bytes.Length);
SearchRequestStream.Close();
// get the webresponse from the searchrequest.
WebResponse SearchResponse = MakeWebResponse(SearchRequest);
String EmailsInXML = extractXMLFromWebResponse(SearchResponse);
ListOfEmailDetails = extractMailPropertiesFromXMLString(EmailsInXML);
}
public void SendEmail(MailStruct mailToForward, enmHTTPType HTTPType)
{
String submissionUri = httpProtocol + strServer + "/" + "exchange" + "/" + strMailBox + "/##DavMailSubmissionURI##/";
String draftsUri = httpProtocol + strServer + "/" +"exchange" + "/" + strMailBox + "/Drafts/" + mailToForward.Subject + ".eml";
String message = "To: " + mailToForward.To + "\n"
+ "Subject: " + mailToForward.Subject + "\n"
+ "Date: " + mailToForward.Received
+ "X-Mailer: mailer" + "\n"
+ "MIME-Version: 1.0" + "\n"
+ "Content-Type: text/plain;" + "\n"
+ "Charset = \"iso-8859-1\"" + "\n"
+ "Content-Transfer-Encoding: 7bit" + "\n"
+ "\n" + mailToForward.MailBody;
// Request to put an email the drafts folder.
HttpWebRequest putRequest = MakeWebRequest("PUT", "message/rfc822",draftsUri );
Byte[] bytes = Encoding.UTF8.GetBytes((String)message);
putRequest.Headers.Add("Translate", "f");
putRequest.Timeout = 300000;
putRequest.ContentLength = bytes.Length;
Stream putRequestStream = putRequest.GetRequestStream();
putRequestStream.Write(bytes, 0, bytes.Length);
putRequestStream.Close();
// Put the message in the Drafts folder of the sender's mailbox.
HttpWebResponse putResponse = MakeWebResponse(putRequest);
putResponse.Close();
// Request to move the email from the drafts to the mail submission Uri.
HttpWebRequest moveRequest = MakeWebRequest("MOVE", "text/xml", draftsUri);
moveRequest.Headers.Add("Destination", submissionUri);
// Put the message in the mail submission folder.
HttpWebResponse moveResponse = MakeWebResponse(moveRequest);
moveResponse.Close();
}
private CredentialCache getCredentials(String URI)
{
CredentialCache tmpCreds = new CredentialCache();
tmpCreds.Add(new Uri(URI), "NTLM", new NetworkCredential(strMailBox, strPassword,strDomain ));
ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate pCertificate, System.Security.Cryptography.X509Certificates.X509Chain pChain, System.Net.Security.SslPolicyErrors pSSLPolicyErrors)
{
return true;
};
return tmpCreds;
}
private HttpWebRequest MakeWebRequest(String method,String contentType,String URI)
{
HttpWebRequest tmpWebRequest;
tmpWebRequest = (HttpWebRequest)HttpWebRequest.Create(URI);
tmpWebRequest.Credentials = getCredentials (URI);
tmpWebRequest.Method = method;
tmpWebRequest.ContentType = contentType ;
return tmpWebRequest ;
}
private HttpWebResponse MakeWebResponse(HttpWebRequest webRequest)
{
HttpWebResponse tmpWebresponse = (HttpWebResponse)webRequest.GetResponse();
return tmpWebresponse;
}
WebResponse getMailsFromWebRequest(String strRootURI, String strQuerySearch)
{
HttpWebRequest SEARCHRequest;
WebResponse SEARCHResponse;
CredentialCache MyCredentialCache;
Byte[] bytes = null;
Stream SEARCHRequestStream = null;
try
{
MyCredentialCache = new CredentialCache();
MyCredentialCache.Add(new Uri(strRootURI ), "NTLM", new NetworkCredential(strMailBox.ToLower(), strPassword, strDomain));
SEARCHRequest = (HttpWebRequest)HttpWebRequest.Create(strRootURI );
ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate pCertificate, System.Security.Cryptography.X509Certificates.X509Chain pChain, System.Net.Security.SslPolicyErrors pSSLPolicyErrors)
{
return true;
};
SEARCHRequest.Credentials = MyCredentialCache;
SEARCHRequest.Method = "SEARCH";
SEARCHRequest.ContentType = "text/xml";
bytes = Encoding.UTF8.GetBytes((string)strQuerySearch);
SEARCHRequest.ContentLength = bytes.Length;
SEARCHRequestStream = SEARCHRequest.GetRequestStream();
SEARCHRequestStream.Write(bytes, 0, bytes.Length);
SEARCHResponse =(HttpWebResponse ) SEARCHRequest.GetResponse();
SEARCHRequestStream.Close();
SEARCHRequest.Timeout = 300000;
System.Text.Encoding enc = System.Text.Encoding.Default;
if (SEARCHResponse == null)
{
Console.WriteLine("Response returned NULL!");
}
else
{
Console.WriteLine(SEARCHResponse.ContentLength);
}
return SEARCHResponse;
}
catch (Exception ex)
{
Console.WriteLine("Problem: {0}", ex.Message);
return null;
}
}
private String extractXMLFromWebResponse(WebResponse SearchResponse)
{
String tmpStream;
using(StreamReader strmReader = new StreamReader(SearchResponse.GetResponseStream(), System.Text.Encoding.ASCII))
{
tmpStream = strmReader.ReadToEnd();
strmReader.Close();
}
return tmpStream;
}
private List<MailStruct > extractMailPropertiesFromXMLString(String strXmlStream)
{
List<MailStruct> tmpListOfMailProperties = new List<MailStruct>();
XmlDocument doc = new XmlDocument();
doc.InnerXml = strXmlStream ;
XmlNamespaceManager xmlNameSpaces = new XmlNamespaceManager(doc.NameTable);
xmlNameSpaces.AddNamespace("a", "DAV:");
xmlNameSpaces.AddNamespace("f", "urn:schemas:httpmail:");
xmlNameSpaces.AddNamespace("d", "urn:schemas:mailheader:");
XmlNodeList mailNodes = doc.SelectNodes("//a:propstat[a:status='HTTP/1.1 200 OK']/a:prop", xmlNameSpaces);
foreach (XmlElement node in mailNodes)
{
tmpListOfMailProperties.Add(new MailStruct()
{
MailBody = node.SelectSingleNode("//f:textdescription",xmlNameSpaces ).InnerText ,
from = node.SelectSingleNode ("//d:from",xmlNameSpaces ).InnerText ,
To = "dfoster#liquidcapital.com",
Subject = node.SelectSingleNode("//d:subject",xmlNameSpaces ).InnerText.ToString () ,
Received = node.SelectSingleNode ("//f:datereceived",xmlNameSpaces ).InnerText.ToString ()
}
);
}
return tmpListOfMailProperties;
}
public struct MailStruct
{
public String To { get; set; }
public String from { get; set; }
public String Subject { get; set; }
public String Received { get; set; }
public String MailBody { get; set; }
}
}
}
Using just the subject to identify email is, indeed, not a good way. If I remember it's correct, there are no automatic / obvious email id for exchange / webdav?
If you parse the subject to pick message, I would also pick more information of the email envelope - Like it size, length to create my own id. The best step should be that you create some sort of hash (check Cryptography) out of the whole message body OR i.e. first character of first xx word in the email body (heavier processing though). That will end up in same hash value everytime you call it on same email envelope. Of until the email content is leaved unchanged.
Looks like you're working with Exchange 2003. Be aware that WebDAV is no longer supported in Exchange Version 2010... and with 2007 and newer you can use a WSDL to do everything you need. All you need is an Exchange 2007 CAS to do this.
What I mentioned is a better longer term approach and has less headaches than parsing unsupported WEBDAV XML
To answer your question, there is a property that is unique per message. Use MFCMapi (on codeplex) to look for it. The property will be named "MessageURL" or something like that. Use that property in the URL for your webdav calls.

Categories