I'm trying to get Plain Text or HTML Text of email using AE.Net.Mail.
I cannot find any documentation.
using (Pop3Client pop3 = new AE.Net.Mail.Pop3Client("pop3Server", "login", "pwd", 995, true))
{
for (var i = pop3.GetMessageCount() - 1; i >= 0; i--)
{
MailMessage Msg = pop3.GetMessage(i);
string HtmlText = Msg.??????
string PlainText = Msg.??????
}
}
Edit : I found this solution
IList<Attachment> iList;
string HtmlText = "", PlainText = "";
for (var i = pop3.GetMessageCount() - 1; i >= 0; i--)
{
MailMessage msg = pop3.GetMessage(i);
TextBody = msg.Body;
iList = msg.AlternateViews as IList<Attachment>;
if (iList.Count == 0) iList = msg.Attachments as IList<Attachment>;
if (iList.Count > 0)
{
TextBody = iList[0].Body;
HtmlBody = iList[1].Body;
}
}
I solved this problem with this method:
Firt create a class:
class BodyContent
{
public string ContentType { get; set; }
public string Body { get; set; }
}
Than:
List<BodyContent> bodies = new List<BodyContent>();
foreach (AE.Net.Mail.Attachment item in mail.AlternateViews)
{
bodies.Add(new BodyContent
{
ContentType = item.ContentType,
Body = item.Body
});
}
And check has "text/html":
string body="";
BodyContent bodyTemp= bodies.Find(x => x.ContentType == "text/html");
if (bodyTemp== null)
body = mail.Body;
else
body = bodyTemp.Body;
And if has "text/html", body's format html else body's format plain
Body = e.Value.AlternateViews.GetHtmlView().Body,
If your MailMessage is the System.Net.Mail one, you can get the message body from the Body property. It may be either HTML or plain-text depending on the IsBodyHtml property. The AlternateViews property may also contain alternate forms of the message body.
you must set headers only to false
foreach (var item in mm)
{
Email myM = new Email();
myM.Date = item.Date;
myM.Body = item.Body;
Related
I am using MailKit to receive emails.
Here is my code:
using (var emailClient = new Pop3Client())
{
emailClient.Connect(settings.HostMail, 110);
emailClient.Authenticate(settings.UsernameEmail, settings.PasswordEmail);
List<EmailMessageDTO> emails = new List<EmailMessageDTO>();
for (int i = 0; i < emailClient.Count; i++)
{
var message = emailClient.GetMessage(i);
var emailMessage = new EmailMessageDTO();
emailMessage.MessageHtml = !string.IsNullOrEmpty(message.HtmlBody) ? message.HtmlBody : message.TextBody;
emailMessage.Subject = message.Subject;
emailMessage.To = new List<DTO.Address>();
emailMessage.To.AddRange(message.To.Select(x => (MailboxAddress)x).Select(x => new DTO.Address { Email = x.Address, Name = x.Name }));
var sender = message.From.Select(x => (MailboxAddress)x).Select(x => new DTO.Address { Email = x.Address, Name = x.Name }).FirstOrDefault();
emailMessage.From = new DTO.Address { Email = sender.Email, Name = sender.Name };
if(emailMessage.From.Name == "Ali")
{
emails.Add(emailMessage);
}
}
}
The problem is that the above code gets all emails in a loop and then searches for the email messages received from an special account. Is there any way to list the email messages received from the account without getting all email messages in the for loop?
The POP3 protocol is very basic and does not support any way of searching. The IMAP protocol would be a better protocol for what you want to do, but if you don't have that option, you could (potentially) improve network performance of your app by downloading only the headers in order to do your filtering and then, if it matches, download the full message.
For example:
for (int i = 0; i < emailClient.Count; i++)
{
var headers = emailClient.GetMessageHeaders(i);
if (!headers.TryGetValue (HeaderId.From, out var header))
continue;
if (!InternetAddressList.TryParse (header.RawValue, out var addrList))
continue;
var sender = addrList.Mailboxes.FirstOrDefault ();
if (sender == null || sender.Name != "Ali")
continue;
var message = emailClient.GetMessage(i);
var emailMessage = new EmailMessageDTO();
emailMessage.MessageHtml = !string.IsNullOrEmpty(message.HtmlBody) ? message.HtmlBody : message.TextBody;
emailMessage.Subject = message.Subject;
emailMessage.To = new List<DTO.Address>();
emailMessage.To.AddRange(message.To.Select(x => (MailboxAddress)x).Select(x => new DTO.Address { Email = x.Address, Name = x.Name }));
emailMessage.From = new DTO.Address { Email = sender.Address, Name = sender.Name };
emails.Add(emailMessage);
}
I'm trying to send emails with embedded images using MailKit. It works well on MS Outlook. However, images do not display as embedded images in Gmail. I tried to attach with "data:image/png;base64," format to it also worked on Outlook but not Gmail.
Any help would be much appreciated!
public string SendEmail (MyModel myModel)
{
var message = new MimeMessage();
var bodyBuilder = new BodyBuilder
{
HtmlBody = myModel.Body
};
GetAllImgTags(bodyBuilder);
message.Body = bodyBuilder.ToMessageBody();
// Send Email Here...
return "OK"
}
public string GetAllImgTags(BodyBuilder bodyBuilder)
{
HtmlDocument document = new HtmlDocument();
document.LoadHtml(bodyBuilder.HtmlBody);
var imgList = document.DocumentNode.Descendants("img").Where(x =>
{
string src = x.GetAttributeValue("src", null) ?? "";
return !string.IsNullOrEmpty(src);
}).ToList();
foreach(var item in imgList)
{
string currentSrcValue = item.GetAttributeValue("src", null);
var file = Path.Combine(_env.WebRootPath,"images", currentSrcValue);
if (File.Exists(file))
{
byte[] imageData = System.IO.File.ReadAllBytes(file);
string contentId = string.Format("{0}#{1}", Path.GetFileName(file), Guid.NewGuid().ToString());
LinkedResource inline = new LinkedResource(new MemoryStream(imageData), Image.Jpeg)
{
ContentId = contentId,
TransferEncoding = TransferEncoding.Base64,
ContentLink = new Uri("cid:" + contentId),
};
inline.ContentType.Name = contentId;
inline.ContentType.MediaType = Image.Jpeg;
bodyBuilder.LinkedResources.Add(contentId, new MemoryStream(imageData));
item.SetAttributeValue("src", "cid:" + contentId);
inline.Dispose();
}
}
bodyBuilder.HtmlBody = document.DocumentNode.OuterHtml;
string result = document.DocumentNode.OuterHtml;
return result;
}
Well, first of all, why are you creating System.Net.Mail objects and then simply disposing them without using them in any way?
See this code for what I mean:
LinkedResource inline = new LinkedResource(new MemoryStream(imageData), Image.Jpeg)
{
ContentId = contentId,
TransferEncoding = TransferEncoding.Base64,
ContentLink = new Uri("cid:" + contentId),
};
inline.ContentType.Name = contentId;
inline.ContentType.MediaType = Image.Jpeg;
Let's try this instead:
var contentType = new ContentType ("image", "jpeg");
var contentId = MimeKit.Utils.MimeUtils.GenerateMessageId ();
var image = (MimePart) bodyBuilder.LinkedResources.Add (file, contentType);
image.ContentTransferEncoding = ContentEncoding.Base64;
image.ContentId = contentId;
item.SetAttributeValue ("src", "cid:" + contentId);
I have a problem. I have 2 Android.Support.V4.App.Fragments
In the first Framgent I use this code:
AgentSpinnerAdapter = new ArrayAdapter<string>(Context, Android.Resource.Layout.SimpleSpinnerDropDownItem);
AgentSpinner.Adapter = AgentSpinnerAdapter;
foreach (string[] str in NamesArray)
{
string AgentId = str[0];
string Owner = str[1];
string Exchange = str[2];
string Remark = str[3];
AgentSpinnerAdapter.Add("Agent " + AgentId + " - " + Owner + " - " + Remark);
}
In the second Fragment I call this line:
dbValue = Fragment1.AgentSpinnerAdapter.GetItem(0);
But it says that AgentSpinnerAdapter is a nullreference, which is weird, because it get's filled. I have set the AgentSpinnerAdapter to Public static. Also in my MainActivity I first create Fragment1 and then Fragment2 like this:
Fragment1 = Fragment1.NewInstance();
Fragment2 = Fragment2.NewInstance();
What am I doing wrong?
UPDATE
Here is the full Fragment1.cs method
public void LoadAgentSpinner()
{
string json = "";
try
{
string html = string.Empty;
string url = "https://www.efy.nl/app/getagents.php";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
IgnoreBadCertificates();
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
json = reader.ReadToEnd();
}
}
catch (Exception ex1)
{
try
{
WebClient client = new WebClient();
NameValueCollection fields = new NameValueCollection();
fields.Add("error", ex1.GetBaseException().ToString());
string url = "https://www.mywebsite.com";
IgnoreBadCertificates();
byte[] respBytes = client.UploadValues(url, fields);
string resp = client.Encoding.GetString(respBytes);
SelectedQuantity.Text = "";
SelectedLimit.Text = "";
}
catch (Exception ex2)
{
string exFullName = (ex2.GetType().FullName);
string ExceptionString = (ex2.GetBaseException().ToString());
}
}
//Parse json content
var jObject = JObject.Parse(json);
//Create Array from everything inside Node:"Coins"
var agentPropery = jObject["Agents"] as JArray;
//Create List to save Coin Data
agentList = new List<agent>();
//Find every value in Array: coinPropery
foreach (var property in agentPropery)
{
//Convert every value in Array to string
var propertyList = JsonConvert.DeserializeObject<List<agent>>(property.ToString());
//Add all strings to List
agentList.AddRange(propertyList);
}
//Get all the values from Name, and convert it to an Array
string[][] NamesArray = agentList.OrderBy(i => i.AgentId)
.Select(i => new string[] { i.AgentId.ToString(), i.Owner, i.Exchange, i.Remark })
.Distinct()
.ToArray();
AgentSpinnerAdapter = new ArrayAdapter<string>(Context, Android.Resource.Layout.SimpleSpinnerDropDownItem);
AgentSpinner.Adapter = AgentSpinnerAdapter;
foreach (string[] str in NamesArray)
{
string AgentId = str[0];
string Owner = str[1];
string Exchange = str[2];
string Remark = str[3];
AgentSpinnerAdapter.Add("Agent " + AgentId + " - " + Owner + " - " + Remark); // format your string here
}
if(MainActivity.db.CheckExistTableSettings("Default Agent") == true)
{
string Value = MainActivity.db.SelectValueFromTableSettings("Default Agent");
int spinnerPosition = AgentSpinnerAdapter.GetPosition(Value);
AgentSpinner.SetSelection(spinnerPosition);
}
else
{
AgentSpinner.SetSelection(0);
}
}
In a few of my applications it's necessary to access the other fragments from my main Activity, so we do the following:
public class MainActivity : AppCompatActivity, BottomNavigationView.IOnNavigationItemSelectedListener
{
public static Dictionary<string, Fragment> FragmentList { get; set; }
private Fragment currentFragment = null;
private BottomNavigationView navigation;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.layout_mainactivity);
// create our fragments and initialise them early.
if (FragmentList == null)
{
FragmentList = new Dictionary<string, Fragment>
{
{ "main", MainFragment.NewInstance() },
{ "bugreport", BugReportFragment.NewInstance() },
{ "settings", SettingsFragment.NewInstance() }
};
}
navigation = FindViewById<BottomNavigationView>(Resource.Id.bottom_nav);
navigation.SetOnNavigationItemSelectedListener(this);
navigation.SelectedItemId = Resource.Id.navigation_main;
}
public bool OnNavigationItemSelected(IMenuItem item)
{
if (!popAction)
{
navigationResourceStack.Push(item.ItemId);
}
switch (item.ItemId)
{
case Resource.Id.navigation_main:
currentFragment = FragmentList["main"];
break;
case Resource.Id.navigation_settings:
currentFragment = FragmentList["settings"];
break;
case Resource.Id.navigation_bugreport:
currentFragment = FragmentList["bugreport"];
break;
}
if (currentFragment == null)
{
return false;
}
else
{
FragmentManager.BeginTransaction().Replace(Resource.Id.frame_content, currentFragment).Commit();
return true;
}
}
}
What this means is you could do something like MainActivity.FragmentList["main"] and then call any public method on the actual initialized class because a pointer to it is stored within the dictionary.
I receive the JSON response from Twitter Search but how can I loop through them?
protected void BtnSearchClick(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://search.twitter.com/search.json?&q=felipe&rpp=40");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
count = resStream.Read(buf, 0, buf.Length);// fill the buffer with data
if (count != 0)// make sure we read some data
{
tempString = Encoding.ASCII.GetString(buf, 0, count);// translate from bytes to ASCII text
sb.Append(tempString);// continue building the string
}
}
while (count > 0); // any more data to read?
//HttpContext.Current.Response.Write(sb.ToString()); //I can see my JSON response here
//object deserializeObject = Newtonsoft.Json.JsonConvert.SerializeObject(sb.ToString());
}
I would make use of dynamic keyword
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString("http://search.twitter.com/search.json?&q=felipe&rpp=40");
dynamic obj = JsonConvert.DeserializeObject(json);
foreach (var result in obj.results)
{
Console.WriteLine("{0} - {1}:\n{2}\n\n", result.from_user_name,
(DateTime)result.created_at,
result.text);
}
}
A strongly typed way..
public class MyTwitterClass
{
public List<CustomObject> data {get; set;}
}
public class CustomObject
{
public string id {get; set;}
public string name {get; set;}
}
Then you should be able to do:
string someJson=
#"{""data"":[{""id"":""1"",""name"":""name1""}, {""id"":""2"",""name"":""name2""}]}";
MyTwitterClass someTwitterData = new JavaScriptSerializer().Deserialize<MyTwitterClass>(someJson);
foreach(var item in someTwitterData.data)
{
Console.Write(item.id + " " + item.name);
}
Having said all that you may want to check this out
http://linqtotwitter.codeplex.com/
Thanks,
The below example should help you, where "result" is the returned JSON
dynamic stuff = JsonConvert.DeserializeObject(result);
foreach (JObject item in stuff)
{
foreach (JProperty trend in item["user"])
{
if (trend.Name == "name")
{
MessageBox.Show(trend.Value.ToString());
}
else if (trend.Name == "followers_count")
{
// GET COUNT
}
else if (trend.Name == "profile_image_url")
{
// GET PROFILE URL
}
}
}
I'm trying to send a mail chimp campaign using asp.net, actually i created successfully the campaign and i can see it through my profile but also i want to send it through my code here is my code so if any one can help!!
private static void CreateCampaignAndSend(string apiKey, string listID)
{
Int32 TemplateID = 0;
string campaignID = string.Empty;
// compaign Create Options
var campaignCreateOpt = new campaignCreateOptions
{
list_id = listID,
subject = "subject",
from_email = "cbx#abc.com",
from_name = "abc",
template_id = TemplateID
};
// Content
var content = new Dictionary<string, string>
{
{"html", "Lots of cool stuff here."}
};
// Conditions
var csCondition = new List<campaignSegmentCondition>();
var csC = new campaignSegmentCondition {field = "interests-" + 123, op = "all", value = ""};
csCondition.Add(csC);
// Options
var csOptions = new campaignSegmentOptions {match = "all"};
// Type Options
var typeOptions = new Dictionary<string, string>
{
{"offset-units", "days"},
{"offset-time", "0"},
{"offset-dir", "after"}
};
// Create Campaigns
var campaignCreate = new campaignCreate(new campaignCreateInput(apiKey, EnumValues.campaign_type.plaintext, campaignCreateOpt, content, csOptions, typeOptions));
campaignCreateOutput ccOutput = campaignCreate.Execute();
campaignSendNow c=new campaignSendNow();
List<Api_Error> error = ccOutput.api_ErrorMessages; // Catching API Errors
if (error.Count <= 0)
{
campaignID = ccOutput.result;
}
else
{
foreach (Api_Error ae in error)
{
Console.WriteLine("\n ERROR Creating Campaign : ERRORCODE\t:" + ae.code + "\t ERROR\t:" + ae.error);
}
}
}