Programmatically reading emails from Exchange Server 2010 mailbox - c#

we have a c# application that reads an email Inbox currently hosted on Exchange 2003 using the http service.
Now the mailbox is to be migrated to an Exchange 2010 server, so we are testing our code to confirm it will still work.
We are getting an error 'Bad request' with the below code (which tries to get all the mail):
public static XmlDocument GetUnreadMailAll()
{
HttpWebRequest loRequest = default(HttpWebRequest);
HttpWebResponse loResponse = default(HttpWebResponse);
string lsRootUri = null;
string lsQuery = null;
byte[] laBytes = null;
Stream loRequestStream = default(Stream);
Stream loResponseStream = default(Stream);
XmlDocument loXmlDoc = default(XmlDocument);
loXmlDoc = new XmlDocument();
try
{
lsRootUri = strServer + "/Exchange/" + strAlias + "/" + strInboxURL;
lsQuery = "<?xml version=\"1.0\"?>"
+ "<D:searchrequest xmlns:D = \"DAV:\" xmlns:m=\"urn:schemas:httpmail:\">"
+ "<D:sql>SELECT "
+ "\"urn:schemas:httpmail:to\", "
+ "\"urn:schemas:httpmail:displayto\", "
+ "\"urn:schemas:httpmail:from\", "
+ "\"urn:schemas:httpmail:fromemail\", "
+ "\"urn:schemas:httpmail:subject\", "
+ "\"urn:schemas:httpmail:textdescription\", "
//+ "\"urn:schemas:httpmail:htmldescription\", "
+ "\"urn:schemas:httpmail:hasattachment\", "
+ "\"urn:schemas:httpmail:attachmentfilename\", "
+ "\"urn:schemas:httpmail:senderemail\", "
+ "\"urn:schemas:httpmail:sendername\", "
+ "\"DAV:displayname\", "
+ "\"urn:schemas:httpmail:datereceived\", "
+ "\"urn:schemas:httpmail:read\", "
+ "\"DAV:id\" "
+ "FROM \"" + lsRootUri
+ "\" WHERE \"DAV:ishidden\" = false "
+ "AND \"DAV:isfolder\" = false "
+ "AND \"urn:schemas:httpmail:read\" = false "
+ "AND \"urn:schemas:httpmail:fromemail\" != 'emailAddy#domainName.co.uk' "
+ "</D:sql></D:searchrequest>";
loRequest = (HttpWebRequest)WebRequest.Create(lsRootUri);
loRequest.Credentials = new NetworkCredential(strUserName, strPassword);
loRequest.Method = "SEARCH";
laBytes = System.Text.Encoding.UTF8.GetBytes(lsQuery);
loRequest.ContentLength = laBytes.Length;
loRequestStream = loRequest.GetRequestStream();
loRequestStream.Write(laBytes, 0, laBytes.Length);
loRequestStream.Close();
loRequest.ContentType = "text/xml";
loRequest.Headers.Add("Translate", "F");
loResponse = (HttpWebResponse)loRequest.GetResponse();
loResponseStream = loResponse.GetResponseStream();
loXmlDoc.Load(loResponseStream);
loResponseStream.Close();
}
the exception is thrown on the line loResponseStream = loResponse.GetResponseStream();
here is the xml that we are sending:
<?xml version="1.0" ?>
- <D:searchrequest xmlns:D="DAV:" xmlns:m="urn:schemas:httpmail:">
<D:sql>SELECT "urn:schemas:httpmail:to", "urn:schemas:httpmail:displayto", "urn:schemas:httpmail:from", "urn:schemas:httpmail:fromemail", "urn:schemas:httpmail:subject", "urn:schemas:httpmail:textdescription", "urn:schemas:httpmail:hasattachment", "urn:schemas:httpmail:attachmentfilename", "urn:schemas:httpmail:senderemail", "urn:schemas:httpmail:sendername", "DAV:displayname", "urn:schemas:httpmail:datereceived", "urn:schemas:httpmail:read", "DAV:id" FROM "https://domain/Exchange/bbtest/Inbox" WHERE "DAV:ishidden" = false AND "DAV:isfolder" = false AND "urn:schemas:httpmail:read" = false AND "urn:schemas:httpmail:fromemail" != 'emailAddy#domainName.co.uk'</D:sql>
</D:searchrequest>

and from MSDN the answer is that WebDAV is deprecated after Exchange 2007, and replaced by Exchange Web Services
here are a couple of links:
MSDN Library: Get started with Exchange Web Services
OMEGACODER: Getting all emails from Exchange using Exchange Web Services
MSDN Code Downloads: Exchange - 101 samples

Related

Using apostrophe in email subject while sent email via gmail api creating an issue

While sent email using below subject which apostrophe replacing with another characters
Actual Subject : We’ll make 100,800 cold calls for you
Mail Shows Subject : We’ll make 100,800 cold calls for you
Issue happens when I'm sent email via api , when sent email from SMTP it's working fine
Please check my api code below
string msg = "From: " + FromName + "<" + From + ">" + " \r\n" +
"To: " + ToName + "<" + To + ">" + " \r\n" +
"BCC: " + BCCEmail + " \r\n" +
"Subject: " + Subject + " \r\n" +
"Message-ID: mID_" + messageID + "\r\n" +
"References: "+encryptMessageID + "\r\n" +
"In-Reply-To: " + encryptMessageID + "\r\n" +
"Content-Type: " + contentType + "; charset=us-ascii\r\n\r\n" + Body;
dynamic objSendMsg = new { raw = commonFunction.Base64UrlEncode(msg) };
if (!string.IsNullOrEmpty(messageThreadID))
objSendMsg = new { raw = commonFunction.Base64UrlEncode(msg), threadId = messageThreadID };
var _objSendMsg = JsonConvert.SerializeObject(objSendMsg);
var strSendMsg = new StringContent(_objSendMsg, UnicodeEncoding.UTF8, "application/json");
When same content i'm applying in body with apostrophe working fine for body
Please check attached screenshot
Email copy
You need to base64_encode of the subject header your sending it as plain text. the API is getting confused.
Subject: " + Convert.ToBase64String(Subject) + " \r\n" +

Add pause to Alexa without using SSML

Is there a way to add a pause (preferably 1 second) in Amazon Alexa without using SSML? Perhaps there is a trick I can do with the Outputspeech.Text and I just don't know it.
Below, I am saying "Here are works of art by {artist name}" but the name and the start of the works of art become mixed together - in spite of the period - so I end up with things like "Here are the works of art by Pablo Picasso Harlequin..."
I am using C# and my own https endpoint, not AWS Lambda.
Any suggestions? Otherwise I will add it as SSML. Thanks.
var output = new StringBuilder();
var outputCard = new StringBuilder();
string m_location;
string m_current_location;
string m_artist = dt_artist.Rows[0]["DisplayName"].ToString();
output.Append("here are works of art for " + m_artist + ". ");
outputCard.Append("Here are works of art for " + m_artist + ".\n\n");
foreach (DataRow dr in dt_artist_objs.Rows)
{
m_current_location = dr["CurrentLocation"].ToString();
if (m_current_location == " ")
{
m_location = "The location is not available.";
}
else
{
m_location = "It is located on the " + m_current_location;
}
output.Append(dr["Title"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + m_location);
outputCard.Append(dr["Title"].ToString() + ", " + dr["Dated"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + dr["Creditline"].ToString() + ". " + m_location + ".\n"); // It is located on the " + dr["CurrentLocation"].ToString());
}
sql_conn_data.Close();
response.Response.OutputSpeech.Text = output.ToString();
response.Response.Card.Title = "Art";
response.Response.Card.Type = "Standard";
response.Response.Card.Text = outputCard.ToString();
response.Response.ShouldEndSession = true;
return response;
UPDATE
OK. Ended up going the SSML route which looks like this:
var output = new StringBuilder();
var outputCard = new StringBuilder();
string m_location;
string m_current_location;
string m_location_card;
string m_artist = dt_artist.Rows[0]["DisplayName"].ToString();
output.Append("<speak>");
output.Append("here are works of art for " + m_artist + ". <break time='1s'/> ");
outputCard.Append("Here are works of art for " + m_artist + ".\n\n");
foreach (DataRow dr in dt_artist_objs.Rows)
{
m_current_location = dr["CurrentLocation"].ToString();
if (m_current_location == " ")
{
m_location = "The location is not available. <break time='1s' />";
m_location_card = "The location is not available. ";
}
else
{
m_location = "It is located on the " + m_current_location + "<break time = '1s' />";
m_location_card = "It is located on the " + m_current_location;
}
output.Append(dr["Title"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + m_location);
outputCard.Append(dr["Title"].ToString() + ", " + dr["Dated"].ToString() + " is a " + dr["Classification"].ToString() + ". The medium is " + dr["Medium"].ToString() + ". " + dr["Creditline"].ToString() + ". " + m_location_card + ". \n");
}
output.Append("</speak>");
sql_conn_data.Close();
response.Response.OutputSpeech.Ssml = output.ToString();
response.Response.OutputSpeech.Type = "SSML";
response.Response.Card.Title = "Art";
response.Response.Card.Type = "Standard";
response.Response.Card.Text = outputCard.ToString();
response.Response.ShouldEndSession = true;
return response;
}
There is not a way to introduce a pause in Alexa without SSML. You will need to build the ssml string and return it back to Alexa using the pause, or the cadence strings.

how to know whether compatibility is on or off using asp.net(c#)

I have to do if user's browser compatibility is on then need to show message to user that your browser's compatibility is on.
I have searched this a lot on google but yet not found a proper answer.
I have tried below code but HttpContext.Current.Request.UserAgent always contains MSIE 7.0
string isOn = string.Empty;
if (HttpContext.Current.Request.UserAgent.IndexOf("MSIE 7.0") > -1)
{
isOn = "IE8 Compatibility View";`
}
else
{
isOn = "IE8";
}
}
You may try like this
if (Request.Browser.Type.ToUpper().Contains("IE"))
{
if (Request.Browser.MajorVersion < 7)
{
//Show the message here
}
...
}
else if (Request.Browser.Type.Contains("Firefox"))
{
//code to show message
}
else if (Request.Browser.Type.Contains("Chrome"))
{
//code to show message
}
Also check this MSDN which has its own way of detecting the browser
Query the Browser property, which contains an HttpBrowserCapabilities
object. This object gets information from the browser or client device
during an HTTP request, telling your application the type and level of
support the browser or client device offers. The object in turn
exposes information about browser capabilities using strongly typed
properties and a generic name-value dictionary.
private void Button1_Click(object sender, System.EventArgs e)
{
System.Web.HttpBrowserCapabilities browser = Request.Browser;
string s = "Browser Capabilities\n"
+ "Type = " + browser.Type + "\n"
+ "Name = " + browser.Browser + "\n"
+ "Version = " + browser.Version + "\n"
+ "Major Version = " + browser.MajorVersion + "\n"
+ "Minor Version = " + browser.MinorVersion + "\n"
+ "Platform = " + browser.Platform + "\n"
+ "Is Beta = " + browser.Beta + "\n"
+ "Is Crawler = " + browser.Crawler + "\n"
+ "Is AOL = " + browser.AOL + "\n"
+ "Is Win16 = " + browser.Win16 + "\n"
+ "Is Win32 = " + browser.Win32 + "\n"
+ "Supports Frames = " + browser.Frames + "\n"
+ "Supports Tables = " + browser.Tables + "\n"
+ "Supports Cookies = " + browser.Cookies + "\n"
+ "Supports VBScript = " + browser.VBScript + "\n"
+ "Supports JavaScript = " +
browser.EcmaScriptVersion.ToString() + "\n"
+ "Supports Java Applets = " + browser.JavaApplets + "\n"
+ "Supports ActiveX Controls = " + browser.ActiveXControls
+ "\n"
+ "Supports JavaScript Version = " +
browser["JavaScriptVersion"] + "\n";
TextBox1.Text = s;
}

C# issue with a json string if value is null

I'm using the following code:
if (e.Data.MessageArray[0] == "!streams")
{
try
{
WebClient webclient = new WebClient();
var data = webclient.DownloadString("http://api.justin.tv/api/stream/list.json?channel=dotademon");
JArray ja = JArray.Parse(data);
WebClient webclient2 = new WebClient();
var data2 = webclient2.DownloadString("http://api.justin.tv/api/stream/list.json?channel=trixilulz");
JArray ja2 = JArray.Parse(data2);
WebClient webclient3 = new WebClient();
var data3 = webclient3.DownloadString("http://api.justin.tv/api/stream/list.json?channel=thepremierleague");
JArray ja3 = JArray.Parse(data3);
string streamingString = "Live right now: ";
streamingString += (char)3 + "03EG.Demon" + (char)15 + " - " + "Viewers: " + ja[0]["channel_count"] + " - " + "http://www.justin.tv/dotademon" + (char)3 + "03 Mouz.Trixi" + (char)15 + " - " + "Viewers: " + ja2[0]["channel_count"] + " - " + "http://www.justin.tv/trixilulz" + (char)3 + "03 The Premier League" + (char)15 + " - " + "Viewers: " + ja3[0]["channel_count"] + " - " + "http://www.justin.tv/thepremierleague";
irc.SendMessage(SendType.Message, e.Data.Channel, streamingString);
Console.WriteLine("EG.Demon is " + ja[0]["format"]);
Console.WriteLine("Mouz.Trixi is " + ja[2]["format"]);
Console.WriteLine("The Premier League is " + ja[3]["format"]);
}
catch (ArgumentOutOfRangeException)
{
//catch something
}
}
However, if one of the streams aren't online, then it doesn't output that string at all. Even if 2 are online and 1 is offline and vice versa. However, if they're all online, then it outputs it correctly like:
Live right now: EG.Demon - Viewers: 164 - http://www.justin.tv/dotademon Mouz.Trixi - Viewers: 49 - http://www.justin.tv/trixilulz The Premier League - Viewers: 2992 - http://www.justin.tv/thepremierleague
To demonstrate it with outputting to console, here is that code, it essentially does the same thing as the above code, but sends it to the console, same issue though obviously:
using System;
using System.Net;
using Newtonsoft.Json.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
try
{
WebClient webclient = new WebClient();
var data = webclient.DownloadString("http://api.justin.tv/api/stream/list.json?channel=dotademon");
JArray ja = JArray.Parse(data);
WebClient webclient2 = new WebClient();
var data2 = webclient2.DownloadString("http://api.justin.tv/api/stream/list.json?channel=trixilulz");
JArray ja2 = JArray.Parse(data2);
WebClient webclient3 = new WebClient();
var data3 = webclient3.DownloadString("http://api.justin.tv/api/stream/list.json?channel=thepremierleague");
JArray ja3 = JArray.Parse(data3);
string streamingString = "Live right now: ";
streamingString += (char)3 + "03EG.Demon" + (char)15 + " - " + "Viewers: " + ja[0]["channel_count"] + " - " + "http://www.justin.tv/dotademon" + (char)3 + "03 Mouz.Trixi" + (char)15 + " - " + "Viewers: " + ja2[0]["channel_count"] + " - " + "http://www.justin.tv/trixilulz" + (char)3 + "03 The Premier League" + (char)15 + " - " + "Viewers: " + ja3[0]["channel_count"] + " - " + "http://www.justin.tv/thepremierleague";
Console.WriteLine(streamingString);
}
catch (ArgumentOutOfRangeException)
{
//do something
}
}
}
}
Live right now: EG.Demon - Viewers: 164 - http://www.justin.tv/dotademon Mouz.Trixi - Viewers: 49 - http://www.justin.tv/trixilulz The Premier League - Viewers: 2992 - http://www.justin.tv/thepremierleague
My question is, how can I use this as a string but output it still if it's online and not output the rest if it's offline. When at least one of them are offline, then it doesn't output it at all. It checks if it's online if it finds channel_count in the json, because if it's offline, the json file contains nothing, just []. It's the only approach I know of to check if it's online/offline. I'm using JSON.Net by the way.
You can check ja.Count to see if you got a response.
var sb = new StringBuilder("Live right now: ");
if (ja.Count > 0)
sb.Append(string.Format("EG.Demon - Viewers: {0} - http://www.justin.tv/dotademon", ja[0]["channel_count"]));
if (ja2.Count > 0)
//...
if (ja3.Count > 0)
//...
irc.SendMessage(SendType.Message, e.Data.Channel, sb.ToString());

How to get a list of sites and SSL certificates from IIS 6.0 using C#, WMI, and/or System.Management?

I am trying to export all the SSL certificates on IIS 6.0 sites from a specificed remote server to a centralized backup server so we can migrate and/or backup our SSL certificates, however I cannot figure out how to do this with IIS 6.0 (all our servers in staging and production still run IIS 6.0). Is there a way to do with C# and System.Management for targeting IIS 6.0 web sites. I have tried everything I could think of.
Pseduo Logic:
Get a list of all IIS Web Sites on Server X
If the site has an SSL certificate binding associated with it, export the SSL certificate with the name of the IIS Web Site.
Here’s the code that is closer to what I need for for IIS 7.0:
using (ServerManager serverManager = ServerManager.OpenRemote(this.ServerName))
{
string collectionDisplay = null;
if (serverManager.Sites != null)
collectionDisplay = "There are " + serverManager.Sites.Count.ToString() + " sites:\n\n";
string siteDisplay = null;
foreach (Site site in serverManager.Sites)
{
siteDisplay = siteDisplay + site.Name + ": ID = " + site.Id + "\n";
// Display each property of each bindings.
string bindingDisplay = null;
foreach (Binding binding in site.Bindings)
{
if (binding.Protocol == "https")
{
bindingDisplay = bindingDisplay + " Binding:\n BindingInformation: " + binding.BindingInformation;
// There is a CertificateHash and CertificateStoreName for the https protocol only.
bindingDisplay = bindingDisplay + "\n CertificateHash: " +
binding.CertificateHash + ": ";
//Add the certificate hash to the collection
if (!IisCertificateHashCollection.ContainsKey(binding.CertificateHash))
{
IisCertificateHashCollection.Add(binding.CertificateHash, site.Name);
//IisCertificateHashCollection.Add(new KeyValuePair<string, byte[]>(site.Name, binding.CertificateHash));
}
// Display the hash.
foreach (System.Byte certhashbyte in binding.CertificateHash)
{
bindingDisplay = bindingDisplay + certhashbyte.ToString() + " ";
}
bindingDisplay = bindingDisplay + "\n CertificateStoreName: " +
binding.CertificateStoreName;
}
bindingDisplay = bindingDisplay + "\n EndPoint: " + binding.EndPoint;
bindingDisplay = bindingDisplay + "\n Host: " + binding.Host;
bindingDisplay = bindingDisplay + "\n IsIPPortHostBinding: " + binding.IsIPPortHostBinding;
bindingDisplay = bindingDisplay + "\n Protocol: " + binding.Protocol;
bindingDisplay = bindingDisplay + "\n ToString: " + binding.ToString();
bindingDisplay = bindingDisplay + "\n UseDsMapper: " + binding.UseDsMapper + "\n\n";
}
siteDisplay = siteDisplay + bindingDisplay;
}
collectionDisplay = collectionDisplay + siteDisplay + "\n";
}
Here’s the code I can’t quite get/don't know how to obtain the needed info from IIS 6.0, I cannot get the query correct:
// Connection succeeds, so there is no issue with that (left out code for that in sample)
ManagementScope scope = new ManagementScope(string.Format(#"\\{0}\root\cimv2", serverName, options));
//ManagementScope scope = new ManagementScope(string.Format(#"\\{0}\root\MicrosoftIISV2", serverName, options));
scope.Connect();
ObjectQuery oq = new ObjectQuery(#"SELECT * FROM Win32_NTDomain");
ManagementObjectSearcher query = new ManagementObjectSearcher(scope, oq);
ManagementObjectCollection queryCollection = query.Get();
foreach (ManagementObject mo in queryCollection)
{
foreach (PropertyData pd in mo.Properties)
{
}
}
You can use System.DirectoryServices to get the certificate hash on IIS6:
DirectoryEntry dir = new DirectoryEntry(#"IIS://Localhost/W3SVC/1"); //this is the metabase path
PropertyValueCollection vals = dir.Properties[SSLCertHash]; //this is the propertyName
The rest is the same as in IIS7.
Hope this helps,
Rotem Varon

Categories