Using SSDT for Visual Studio 2013 am sending e-mail notifications via ssis script using SmtpClient class.
public void Main()
{
SmtpClient v_EmailClient;
string v_From = Dts.Variables["User::vFrom"].Value.ToString();
string v_To = Dts.Variables["User::vTo"].Value.ToString();
string v_EnvNameToSubject = Dts.Variables["User::vEnvNameToSubject"].Value.ToString();
MailMessage v_EmailMessage = new MailMessage(v_From, v_To);
v_EmailMessage.IsBodyHtml = true;
v_EmailMessage.Subject = v_EnvNameToSubject + "SSIS email notification";
//Concatenation of variable with the standard message does not work
v_EmailMessage.Body = "Message text";
v_EmailClient = new SmtpClient("SmtpServer");
v_EmailClient.UseDefaultCredentials = true;
v_EmailClient.Send(v_EmailMessage);
Dts.TaskResult = (int)ScriptResults.Success;
}
When I try to concatenate the variable v_EnvNameToSubject with the standard subject text does not work. I tried to use try catch block to find out the actual error message and that did not help either.
First, check your variables names (and cases) vFrom , vTo , vEnvNameToSubject because they are case sensitive.
Second, Try concatenating these strings another way (Using String.Concat() Function or using a stringbuilder):
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine(v_EnvNameToSubject);
sb.AppendLine("SSIS email notification");
v_EmailMessage.Subject = sb.ToString();
Or
v_EmailMessage.Subject = String.Concat(v_EnvNameToSubject,"SSIS email notification")
Third, Check your variables scope and that they are added to the script task ReadOnly Variables
Related
I am making an windows form application in c#, it has to be able to send an email to all the recipient ids that are in a table in an Access Database.
I already understand how to send the mails and even successfully made tests, but I don't understand how to convert column the has all de email ids to a comma separated string.
I am also kinda confused if this code goes inside the forms code or somewhere else.
I already tried using foreach loops and for some reason they have errors saying that i cannot use them.
I have also read a bit of linq but i could not understand where to even implement such code in my program.
Here is the code for the email sending button:
private void button1_Click(object sender, EventArgs e)
{
try
{
MailMessage mail = new MailMessage();
SmtpClient smtpserver = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("latinaultimatesite#gmail.com");
mail.To.Add("diomidiov#gmail.com,ninjaboy.abel#gmail.com");
mail.Subject = "Que xopa";
mail.Body = "probando 1 2 3";
smtpserver.Port = 587;
smtpserver.Credentials = new
System.Net.NetworkCredential("latinaultimatesite#gmail.com","proyectofinal69lus");
smtpserver.EnableSsl = true;
smtpserver.Send(mail);
MessageBox.Show("mail Send");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
For now I have achieved sending mail to the accounts seen in the code, so that works, what I need is the accounts in the database to be in a separated comma string format so I can use them in this button.
It is unclear why you would not simply query the database for this info. However, if you already have the DataTable then, as others have pointed out, you will need to loop through the DataTable.Rows collection and grab the email address cell from that row, add a comma, then continue this for all the rows in the table. A StringBuilder may be helpful for building this comma delimited email string. It may look something like below…
private string GetEmailAddress(DataTable dt) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dt.Rows.Count; i++) {
sb.Append(dt.Rows[i]["Email"].ToString());
if (i < dt.Rows.Count - 1)
sb.Append(",");
}
sb.AppendLine();
return sb.ToString();
}
As per my understanding, you should try to split that string and then add every email I'd to 'To' clause.
One example is illustrated here:-
https://www.c-sharpcorner.com/UploadFile/0c1bb2/sending-email-to-multiple-recipeint-using-Asp-Net/
I am trying to convert some data I get from my database in my ASP.NET application. So far I came across a very straight forward framework to do that called DocX.
https://www.nuget.org/packages/DocX/
So according to its API I decided that the best way to implement my task would be to first make a documents and save it to server. Then import it from server as stream and attach it to email. But I a doubtfull.
So I go:
var doc = DocX.Create("test.doc");
string f = "sdcdscdsc";
doc.InsertParagraph(f);
doc.Save();
Two things happen here:
1) First I get an exception FileNotFoundException: Could not load file or assembly 'System.IO.Packaging
2) Somehow... when I tried another framework for doing this DocumentCore (https://www.nuget.org/packages/sautinsoft.document/), I guess that installed a missing file and the Save() method started working and saving the file but the files where blank.
Honestly I would really appreciate on best practices to do this task. If anyone has come across similar task please share the methodology used.
The second part is a bit easier. I got the email part sorted but still got no idea how to attach the file. So far the code looks like this:
private static void SendMail()
{
var mailMessage = new MailMessage("xxxxxx#gmail.com", "xxxxxx#gmail.com");
mailMessage.Subject = "Tester ";
mailMessage.Body = "This is the message";
SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
client.Credentials = new System.Net.NetworkCredential()
{
UserName = "xxxxxxxx#gmail.com",
Password = "xxxxxxxxx"
};
client.EnableSsl = true;
client.Send(mailMessage);
}
Overall it in bits and pieces and I would really appreciate some sharing of experience. Thank you very much.
Part 1 - create doc with content
Had to use DocXCore for ASP.NET Core app.
private void CreateDocument()
{
try
{
var doc = DocX.Create("mytest.docx");
doc.InsertParagraph("Hello my new message");
doc.Save();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Part 2 - sending email
private void SendMail()
{
var mailMessage = new MailMessage("xxxxx#gmail.com", "yzolxxxxxotarev#gmail.com");
mailMessage.Subject = "Tester ASP.NET Boat Inspector";
mailMessage.Body = "This is the message";
var contentPath = _env.ContentRootPath+#"\mytest.docx";
Attachment data = new Attachment(contentPath, MediaTypeNames.Application.Octet);
mailMessage.Attachments.Add(data);
SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
client.Credentials = new System.Net.NetworkCredential()
{
UserName = "xxxxx#gmail.com",
Password = "xxxxx"
};
client.EnableSsl = true;
client.Send(mailMessage);
}
Works well.
I have a class that uses the razor engine to generate html templates and there seems to be an issue where some links (anchors or images) have an additional period inserted into the address, usually at the www. part making the link unusable.
There doesn't appear to be any rhyme or reason as to when or where it does this, sometimes it works fine, other times several of the links have this issue.
So when I return the template as string to then send as an email I call replace like below:
var fixedTemplate = template.Replace("www..", "www.");
But this isn't working. I've never ran into this issue before. The strings are quite large, could this cause problems with the replace function?
How can I
a) Fix the razor engine so that these random periods are no longer added in links
Or
b) Find out why the replace function isn't replacing all of the occurrences.
A sample of the code called in my class below for completeness.
// nt = class associated with template
using (TemplateService templateService = new TemplateService())
{
string html = templateService.Parse(File.ReadAllText(nt.TemplateFilePath), nt, null, null);
var pm = new PreMailer.Net.PreMailer(html);
//inline css styles with premailer
Emailer.SendTestEmail(pm.MoveCssInline().Html, emailAddress, "Test Email: " + campaign.Title);
pm = null;
}
And the emailer code where replace is called
public static void SendTestEmail(string template, string emailAddress, string subject)
{
var updatedTemplate = template.Replace("www..", "www.");
var email = new MailMessage
{
Body = updatedTemplate,
Subject = subject,
IsBodyHtml = true,
From = new MailAddress("noreply#mydomain.com")
};
email.To.Add(emailAddress);
using (var smtpClient = new SmtpClient())
{
smtpClient.PickupDirectoryLocation = "M:\\Pickup";
smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
smtpClient.Send(email);
}
}
every night i have a trigger that executes asp.net page with method that first retrieves from DB users with needed details and then emails them with information they need like ie. users that does not have an image in their profile. Once i get data from DB i build large string with encoded HTML and assign it to MailMessage.Body tag. There are about 20000 users per action/night who get the mail. Stored procedures just get users based on criteria i need nothing to optimize there (after proper indexes been made).
How do i optimize it? Can i create sort of queue in ASP.NET that it will be executed all day long without one time action? Maybe i can use async actions to send few emails per time.
Need advice, if you have question about how i perform each action in order to help me don't be afraid to ask, i will answer i just don't know what place in code may interest you.
protected void Page_Load(object sender, EventArgs e)
{
string type = Request.QueryString["type"];
string spName = "";
string message = "";
switch (type)
{
//getUsersWithoutPictures
case "uwp":
spName = "getUsersWithoutPictures";
message = getUsersWithoutPicturesTemplate();
break;
//getUsersWithoutText
case "uwt":
spName = "getUsersWithoutText";
message = getUsersWithoutTextTemplate();
break;
//getUsersWithoutEnteringWebsiteForTwoWeeks
case "uwewftw":
spName = "getUsersWithoutEnteringWebsiteForTwoWeeks";
message = getUsersWithoutEnteringWebsiteForTwoWeeksTemplate();
break;
//getUsersWithoutHobbies
case "uwh":
spName = "getUsersWithoutHobbies";
message = getUsersWithoutHobbiesTemplate();
break;
//getUsersWithoutCharateristics
case "uwc":
spName = "getUsersWithoutCharateristics";
message = getUsersWithoutCharateristicsTemplate();
break;
//getUsersWithoutActivation
case "uwa":
spName = "getUsersWithoutActivation";
message = getUsersWithoutActivationTemplate();
break;
default:
Response.Write("failure");
Response.End();
break;
}
DataTable recipientsList = new DataTable();
using (SqlConnection cn = cms.connect("someconnectionstring"))
{
SqlDataAdapter adp = new SqlDataAdapter(spName, cn);
adp.SelectCommand.CommandType = CommandType.StoredProcedure;
adp.Fill(recipientsList);
}
foreach (DataRow row in recipientsList.Rows)
{
try
{
IPHostEntry emailHost = Dns.GetHostEntry(row["email"].ToString().Remove(0, row["email"].ToString().LastIndexOf("#") + 1));
MailMessage myMessage = new MailMessage(new MailAddress("support#" + row["registratioSite"].ToString()), new MailAddress(row["email"].ToString()));
myMessage.Subject = "";
myMessage.Body = getGenericEmailTemplate(AffDomains.getFullDomain(row["registratioSite"].ToString()), message, row["email"].ToString(), row["usernumber"].ToString(), row["nick"].ToString());
myMessage.IsBodyHtml = true;
SmtpClient mySmtp = new SmtpClient("mysmtp.server.com");
mySmtp.Send(myMessage);
}
catch (Exception)
{
}
}
Response.Write("success");
Response.End();
}
private string getGenericEmailTemplate(string domain, string message, string email, string usernumber, string nick)
{
return "some html";
}
private string getUsersWithoutPicturesTemplate()
{
return "some message";
}
private string getUsersWithoutTextTemplate()
{
return "some message 2";
}
private string getUsersWithoutEnteringWebsiteForTwoWeeksTemplate()
{
return "some message 3";
}
private string getUsersWithoutHobbiesTemplate()
{
return "some message 4";
}
private string getUsersWithoutCharateristicsTemplate()
{
return "some message 5";
}
private string getUsersWithoutActivationTemplate()
{
return "some message 6";
}
Some pointers based on your current implementation:
Do this once per week. Is your site really so important that the users must be tortured every single night?
It looks like you're going to email each user several times, eg if they don't have a picture and haven't entered for two weeks they will get two emails. Combine all the events into one email.
Batch your emails into small groups based on which notifications they ought to receive, eg BCC 5 users at a time who don't have images in their profile.
Return only the data you need from the stored procs.
Move everything you can outside of the main loop eg creation of the EmailHost, MailMessage object and set the relevant properties inside the loop.
If you want this solution to scale way beyond its current limits however, you might want to think about some sort of multithreaded (or distrubuted) producer/consumer queue. I won't elaborate further here - there are plenty of examples on the web.
I have a ready generated MHTML as a byte array (from Aspose.Words) and would like to send it as an email. I'm trying to do this through CDOSYS, though am open to other suggestions. For now though I have the following:
CDO.Message oMsg = new CDO.Message();
CDO.IConfiguration iConfg = oMsg.Configuration;
Fields oFields = iConfg.Fields;
// Set configuration.
Field oField = oFields["http://schemas.microsoft.com/cdo/configuration/sendusing"];
oField.Value = CDO.CdoSendUsing.cdoSendUsingPort;
oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpserver"];
oField.Value = SmtpClient.Host;
oField = oFields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"];
oField.Value = SmtpClient.Port;
oFields.Update();
//oMsg.CreateMHTMLBody("http://www.microsoft.com", CDO.CdoMHTMLFlags.cdoSuppressNone, "", "");
// NEED MAGIC HERE :)
oMsg.Subject = warning.Subject; // string
oMsg.From = "system#example.com";
oMsg.To = warning.EmailAddress;
oMsg.Send();
In this snippet, the warning variable has a Body property which is a byte[]. Where it says "NEED MAGIC HERE" in the code above I want to use this byte[] to set the body of the CDO Message.
I have tried the following, which unsurprisingly doesn't work:
oMsg.HTMLBody = System.Text.Encoding.ASCII.GetString(warning.Body);
Anybody have any ideas how I can achieve what I want with CDOSYS or something else?
Please don't use CDO, it dates from an era when computers still used smoke signals to exchange emails. System.Net.Mail contains everything you need, MailMessage is your friend. Note its IsBodyHtml property.
It is possible via CDO.Message (it is necessary add to project references COM library "Microsoft CDO for Windows 2000 Library"):
protected bool SendEmail(string emailFrom, string emailTo, string subject, string MHTmessage)
{
string smtpAddress = "smtp.email.com";
try
{
CDO.Message oMessage = new CDO.Message();
// set message
ADODB.Stream oStream = new ADODB.Stream();
oStream.Charset = "ascii";
oStream.Open();
oStream.WriteText(MHTmessage);
oMessage.DataSource.OpenObject(oStream, "_Stream");
// set configuration
ADODB.Fields oFields = oMessage.Configuration.Fields;
oFields("http://schemas.microsoft.com/cdo/configuration/sendusing").Value = CDO.CdoSendUsing.cdoSendUsingPort;
oFields("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value = smtpAddress;
oFields.Update();
// set other values
oMessage.MimeFormatted = true;
oMessage.Subject = subject;
oMessage.Sender = emailFrom;
oMessage.To = emailTo;
oMessage.Send();
}
catch (Exception ex)
{
// something wrong
}
}