how to send the gridview in email with formatting - c#

I am developing an online ordering web application in which I have to email with perches product details to customer. I have maintain all the data in a data table and then generated the grid view pragmatically as follows
public GridView makeGridview(DataTable Dt)
{
GridView GV = new GridView();
GV.DataSource = Dt;
GV.DataBind();
return GV;
}
then adding this grid view to email
body = body.Replace("{Product_Details}", GridViewToHtml(makeGridview(Dt)));
private string GridViewToHtml(GridView gv)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(sw);
gv.RenderControl(hw);
return sb.ToString();
}
This is working fine but the problem is then am unable to design it in our predefine format. This mail will be received by the customer of my website, so I need to convert in to our them.
Please guide me how to format in our them.
If there is an another way to do this then I'm open to that as well.

I would suggest you to not trust the GridView as your rendered html, but instead to use your current data-source for that (DataTable):
public GridView CreateHtmlTable(DataTable dt)
{
//Do your HTML work here, like the following:
string tab = "\t";
StringBuilder sb = new StringBuilder();
sb.AppendLine("<html>");
sb.AppendLine(tab + "<body>");
sb.AppendLine(tab + tab + "<table>");
// headers.
sb.Append(tab + tab + tab + "<tr>");
foreach (DataColumn dc in dt.Columns)
{
sb.AppendFormat("<td>{0}</td>", dc.ColumnName);
}
sb.AppendLine("</tr>");
// data rows
foreach (DataRow dr in dt.Rows)
{
sb.Append(tab + tab + tab + "<tr>");
foreach (DataColumn dc in dt.Columns)
{
string cellValue = dr[dc] != null ? dr[dc].ToString() : "";
sb.AppendFormat("<td>{0}</td>", cellValue);
}
sb.AppendLine("</tr>");
}
sb.AppendLine(tab + tab + "</table>");
sb.AppendLine(tab + "</body>");
sb.AppendLine("</html>");
}

Follow follwing code:
public void SendHTMLMail()
{
MailMessage Msg = new MailMessage();
MailAddress fromMail = new MailAddress("administrator#aspdotnet-suresh.com");
// Sender e-mail address.
Msg.From = fromMail;
// Recipient e-mail address.
Msg.To.Add(new MailAddress("suresh#gmail.com"));
// Subject of e-mail
Msg.Subject = "Send Gridivew in EMail";
Msg.Body += "Please check below data <br/><br/>";
Msg.Body += GetGridviewData(gvUserInfo);
Msg.IsBodyHtml = true;
string sSmtpServer = "";
sSmtpServer = "10.2.160.101";
SmtpClient a = new SmtpClient();
a.Host = sSmtpServer;
a.EnableSsl = true;
a.Send(Msg);
}
// This Method is used to render gridview control
public string GetGridviewData(GridView gv)
{
StringBuilder strBuilder = new StringBuilder();
StringWriter strWriter = new StringWriter(strBuilder);
HtmlTextWriter htw = new HtmlTextWriter(strWriter);
gv.RenderControl(htw);
return strBuilder.ToString();
}
Refer below doccument:
http://www.aspdotnet-suresh.com/2012/09/how-to-send-gridview-in-email-body-in.html

Honestly what you have done here (rendering a Web Forms control to an email string) seems like a bit of an unintended trick. Honestly it's not that hard to iterate through a collection and build an HTML table using a StringBuilder.
I believe that for email HTML the convention is often to use inline styles to guarantee the best compatibility with email clients. So you'd want to style your elements like so:
<table>
<tbody>
<tr style="background-color: #EE0000">
<td style="text-transform: uppercase"></td>
...
</tr>
</tbody>
</table>
In the past I've done this by creating an HTML file with everything how I want it and using placeholders like {VariableName} and then doing a string replace on the variables with their values. This way you separate your HTML view from the C# code. It'd be a little tricky with a list of items, in that case you'd have at least two HTML templates: one for the entire document and one for the item rows.

I ran into a similar issue like yours, and I got it done like this:
encapsulated the functionality in a separate HelperClass for ease of use. Used static variables and methods to keep it simple
write the HTML code to format the content of the GridView to a nice table (with zebra stripes and stuffs)
public static StringBuilder gridViewToHTML(GridView gv)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("<html>");
sb.AppendLine("<body>");
sb.AppendLine(#"<table style='padding: 10px; font-family: Verdana; font-size:11px;
border-style:solid;border-width:1px;border-color:grey;'> ");
sb.AppendLine("<tr>");
/* *** Build header of the HTML table *** */
for (int i = 0; i < gv.Columns.Count; i++)
{
sb.AppendLine("<td style='font-weight:bold;background-color:black;color:white;'>" + gv.Columns[i].HeaderText + "</td>");
}
sb.AppendLine("</tr>");
/* *** Build body of the HTML table *** */
for (int i = 0; i < gv.Rows.Count; i++)
{
sb.AppendLine("<tr>");
foreach (DataControlFieldCell gvcell in gv.Rows[i].Cells)
{
sb.AppendLine("<td style='text-align;left;'>" + gvcell.ToString() + "</td>");
}
sb.AppendLine("</tr");
}
sb.AppendLine("</table>");
sb.AppendLine("</body>");
sb.AppendLine("</html>");
return sb;
}
send the email message using the StringBuilder object as html formatting of the content, and the casual parameters (to Whom, and Subject)
public static void sendEmailMessage(StringBuilder stringBuilder, string email_ToAddress, string email_Subject)
{
DateTime now = DateTime.Now;
DateTime yesterday = DateTime.Now.AddDays(-1);
MailMessage mail = new MailMessage();
//SomeEmailAccount#yourOrganization.com must be set by your Sysadmin before using it.
mail.From = new MailAddress("SomeEmailAccount#yourOrganization.com");
mail.To.Add(email_ToAddress);
mail.Subject = $"{email_Subject} . Date #{now.ToShortDateString()}";
mail.Body = stringBuilder.ToString();
mail.IsBodyHtml = true;
NetworkCredential autentificare = new NetworkCredential();
autentificare.UserName = "SomeEmailAccount#yourOrganization.com"";
autentificare.Password = "yourPassw0rd";
SmtpClient smtp = new SmtpClient();
smtp.Host = "mail.yourOrganization.com";
smtp.UseDefaultCredentials = true;
smtp.Credentials = autentificare;
smtp.Port = 25;
smtp.EnableSsl = false;
smtp.Send(mail);
}

Related

Inserting many records while reloading the page

I have a form. I am inserting data to my database and sending those inserted details to mail.
After clicking the submit button I'm clearing all the variables but my problem is when I reload the page once again data inserting as a new record and anther mail is sending. I don't want to insert new record and send another mail.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Data.SqlClient;
namespace SupportPortal
{
public partial class Support : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void clearallfields()
{
ProblemName.Value = "";
ImpactDropDown.SelectedIndex = 0;
SeverityDropDown.SelectedIndex = 0;
ProblemDescription.Value = "";
}
protected void Submitsupportform_Click(object sender, EventArgs e)
{
//string ticketNumber = string.Empty;
string Problem = ProblemName.Value;
string impact = ImpactDropDown.Value;
string Priority = SeverityDropDown.Value;
string problemdescription = ProblemDescription.Value;
Byte[] bytImage = new byte[] { 1 };
Byte[] bytImage1 = new byte[] { 1 };
Byte[] bytImage2 = new byte[] { 1 };
string FileName = "";
try
{
// Get the HttpFileCollection
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
FileName = System.IO.Path.GetFullPath(hpf.FileName);
HttpPostedFile objHttpPostedFile = Request.Files[Request.Files.AllKeys[i]];
int intContentlength = objHttpPostedFile.ContentLength;
if (i == 0)
{
bytImage = new Byte[intContentlength];
objHttpPostedFile.InputStream.Read(bytImage, 0, intContentlength);
}
if (i == 1)
{
bytImage = new Byte[intContentlength];
objHttpPostedFile.InputStream.Read(bytImage1, 0, intContentlength);
}
if (i == 2)
{
bytImage = new Byte[intContentlength];
objHttpPostedFile.InputStream.Read(bytImage2, 0, intContentlength);
}
}
}
catch (Exception ex)
{
throw ex;
}
// inserting into database
SqlConnection con = new SqlConnection("Server=localhost;Database=ViveSupport;Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand("CreateTicket", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Product", ProductName.Value);
cmd.Parameters.AddWithValue("#Version", ProductVersionDropDown.Value);
cmd.Parameters.AddWithValue("#Module", ModuleDropDown.Value);
cmd.Parameters.AddWithValue("#OperatingSystem", OSDropDown.Value);
cmd.Parameters.AddWithValue("#DataSource", Datasource.Value);
cmd.Parameters.AddWithValue("#Browser", BrowserDropDown.Value);
cmd.Parameters.AddWithValue("#Attachment1", bytImage);
cmd.Parameters.AddWithValue("#Attachment2", bytImage1);
cmd.Parameters.AddWithValue("#Attachment3", bytImage2);
con.Open();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
String ticketNumber = ds.Tables[0].Rows[0]["ticketNumber"].ToString();
con.Close();
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[6] {
new DataColumn("Product", typeof(string)),
new DataColumn("Module",typeof(string)),
new DataColumn("Product version", typeof(string)),
new DataColumn("OS",typeof(string)),
new DataColumn("Datasource", typeof(string)),
new DataColumn("Browser",typeof(string))});
dt.Rows.Add(ProductName, ModuleDropDown, ProductVersionDropDown, OSDropDown, Datasource, BrowserDropDown);
StringBuilder sb = new StringBuilder();
// Table start
sb.Append("<table cellpadding='5' cellspacing='0' style='border: 1px solid #ccc;font-size: 9pt;font-family:Arial'>");
// Adding HeaderRow
sb.Append("<tr>");
foreach (DataColumn column in dt.Columns)
{
sb.Append("<th style='background-color: #f5f5f5;border: 1px solid #ccc;text-align: left;'>" + column.ColumnName + "</th>");
}
sb.Append("</tr>");
// Adding DataRow
foreach (DataRow row in dt.Rows)
{
sb.Append("<tr>");
foreach (DataColumn column in dt.Columns)
{
sb.Append("<td style='width:100px;border: 1px solid #ccc'>" + row[column.ColumnName].ToString() + "</td>");
}
sb.Append("</tr>");
}
// Table end
sb.Append("</table>");
StringBuilder problemtable = new StringBuilder();
problemtable.Append("<div><div><table style='font-size: 9pt;font-family:Arial'><tr><td>Problem: </td><td>" + Problem + "</td></tr><tr><td>Impact: </td><td>" + impact + "</td></tr><tr><td>Priority: </td><td>" + Priority + "</td></tr><tr><td>ProblemDescription: </td><td>" + problemdescription + "</td></tr></table></div></div>");
StringBuilder footersignature = new StringBuilder();
string to = ""; //To address
string from = ""; //From address
MailMessage message = new MailMessage(from, to);
string mailbody = sb.ToString() + problemtable.ToString();
message.Subject = "Generated ticket Number is" + ticketNumber;
message.Body = mailbody;
message.BodyEncoding = Encoding.UTF8;
message.IsBodyHtml = true;
for (var x = 0; x < Request.Files.AllKeys.Length; x++)
{
string file = System.IO.Path.GetFullPath(upload_file1.PostedFile.FileName);
// HttpPostedFile file = Request.Files[Request.Files.AllKeys[x]];
if (file != null && file.Length > 0)
{
try
{
message.Attachments.Add(new Attachment(Path.GetFileName(System.IO.Path.GetFileName(file))));
}
catch (Exception ex)
{
throw ex;
}
}
}
SmtpClient client = new SmtpClient("smtp.gmail.com", 587); //Gmail smtp
System.Net.NetworkCredential basicCredential1 = new System.Net.NetworkCredential("", "");
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = basicCredential1;
try
{
client.Send(message);
}
catch (Exception ex)
{
throw ex;
}
// method to clear all the fields
clearallfields();
}
}
}
Generally doing bulk changes or comits like this is not a good design. You want to have the user only Add, Edit or Delete one specific entry. And comit the moment the user is finished with that one. Gathering changes like this is not generally a good idea. It raises the danger of data loss and update race conditions exponentially. It barely works for IMAP, and IIRC that one is designed more like a proper, multi-insert Distributed Database.
If you want to still use this design, you have to memorize if one specific row has been comited already. You want to know wich row has "unsaved changes". A simple boolean value for each row would do this. With WebApplications persisting the data is a problem. In this specific case - as the data has very low security impact - you can have it send to the client and retreive it back from them as part of the Formular data.
Very important rule: No mater how much they look like a Desktop applications, Web Applications are still a 1980 HTML Webformular. All the old design decisions still apply. But luckily that old design did include a hidden formular field. Something send to and send back from the user, that is not displayed. How to use such a field from ASP.Net is a bit outside my knowledge however.

How to apped in table format using String builder

I am trying to make a table format in the body of email.
This is how I do the appending
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<table border='1' cellpadding='0' cellspacing='0'>");
sb.Append("<tr>");
sb.Append("<td>ID</td>");
sb.Append("<td>STATUS</td>");
sb.Append("</tr>");
//sb.Append("</table>");
//sb.Append(" < table border = '1' cellpadding = '0' cellspacing = '0' width = '100%' >");
foreach (var item in mylist)
{
sb.Append("<tr>");
sb.Append("<td>" + item.message + "</td>");
sb.Append("<td>" + item.transactionid + "</td>");
sb.Append("</tr>");
}
sb.Append("</table>");
var sendmail = new MailAddress("", "Akhil");
var receiver = new MailAddress("", "Buddy");
var subject = "Request for Asset!!";
var body = sb.ToString();
If you using System.Web.Mail then put messageg.BodyFormat = MailFormat.Html;
If you using System.Net.Mail then put message.IsBodyHtml = true; .
IsBodyHtml & MailFormat.Html states that your message is HTML formatted.
> This is not a true way, first you should add the HTML file, then after create a table inside the file.
Now attach a file with StringBuilder.
## Here is my send email with attachment code ##
StringBuilder sbMailBody = new StringBuilder();
sbMailBody.Append(Server.MapPath("~/Content/fielname.html"));
var sendmail = new MailAddress("", "Akhil");
var receiver = new MailAddress("", "Buddy");
var subject = "Request for Asset!!";
var body = sbMailBody.ToString();

Sending datagridview as mail with header

This is my code to send datagridview as email. This code works for me by just sending the data in the datagridview.
Please guide me how to add the table header in it. I want the email to be sent as whole table including the table header.
var client = new SmtpClient("smtp.gmail.com", 587);
client.EnableSsl = true;
client.Credentials = new NetworkCredential("from_mail", "password");
var mail = new MailMessage();
mail.From = new MailAddress("from_mail");
mail.To.Add("to_mail");
mail.IsBodyHtml = true;
mail.Subject = "test";
string mailBody = "<table width='100%' style='border:Solid 1px Black;'>";
foreach (DataGridViewRow row in dataGridView2.Rows)
{
mailBody += "<tr>";
foreach (DataGridViewCell cell in row.Cells)
{
mailBody += "<td>" + cell.Value + "</td>";
}
mailBody += "</tr>";
}
mailBody += "</table>";
//your rest of the original code
mail.Body = mailBody;
client.Send(mail);
MessageBox.Show("mail send");
this.Close();
For converting your DataGridView to HTML for sending it in an email, use the function below:
private StringBuilder DataGridtoHTML(DataGridView dg)
{
StringBuilder strB = new StringBuilder();
//create html & table
strB.AppendLine("<html><body><center><" +
"table border='1' cellpadding='0' cellspacing='0'>");
strB.AppendLine("<tr>");
//create table header
for (int i = 0; i < dg.Columns.Count; i++)
{
strB.AppendLine("<td align='center' valign='middle'>" +
dg.Columns[i].HeaderText + "</td>");
}
//Close the header row
strB.AppendLine("</tr>");
//create table body
for (int i = 0; i < dg.Rows.Count; i++)
{
strB.AppendLine("<tr>");
foreach (DataGridViewCell dgvc in dg.Rows[i].Cells)
{
strB.AppendLine("<td align='center' valign='middle'>" +
dgvc.Value.ToString() + "</td>");
}
strB.AppendLine("</tr>");
}
//table footer & end of html file
strB.AppendLine("</table></center></body></html>");
return strB;
}

email containing with SQL

I have a button called "lnkupdate_click" basically all it does when you click is access a table called "tbl_security" and from there it will update the field "pass" with a random 4 digit number where the field "patrol" = 1 or true.
an example is shown below;
Code Pass Patrol
TES 1234 1
ASD 4321 1
MOR 6789 1
SAI 0959 1
The bit I am stuck on is this: All I want it to do from here is send the updated info from the database in an email. So basically to generate me an email containing all of the information in the table above. However I keep getting a red line underneath my "foreach" loop with this error message.
"foreach statement cannot operate on variables of type 'int' because 'int' does not contain a public definition for 'GetEnumerator'"
My code is below:
protected void lnkUpdate_Click(object sender, EventArgs e)
{
{
string queryUpdateAllFields;
string queryGetAllUpdatedField;
StringBuilder sb = new StringBuilder();
queryGetAllUpdatedField = #"update tbl_Security set
Pass = round(rand(CAST(CAST(NEWID() AS VARBINARY(4)) AS SMALLINT))* 9000,0) + 1000
WHERE Patrol = 1";
queryGetAllUpdatedField = #"SELECT Code, Pass, Patrol
FROM tbl_Security
WHERE Patrol = 1";
var random = new Random();
//queries to update and retrieve
SqlHelper.ExecuteSqlNonQuery(queryUpdateAllFields);
var results = SqlHelper.ExecuteSqlNonQuery(queryGetAllUpdatedField);
//loop over the results and append to StringBuilder instance.
sb.Append("Below are all the fields that have been updated: <br /><br />");
foreach(var r in results)
{
sb.AppendLine("<hr />");
sb.AppendLine("Code: " + r.Code + " Pass: " + r.Pass + " Patrol: " + r.Patrol); //for Patrol
}
//Email showing all updated pass's with codes
MailAddress to = new MailAddress("");
MailAddress from = new MailAddress("");
MailMessage message = new MailMessage(from, to);
message.Subject = "Subject Line Here";
message.Body = sb.ToString(); //attach StringBuilder - This will be built up of all the rows updated in the DataBase
SmtpClient mailClient = new SmtpClient();
mailClient.Port = 25;
//finally send message here
mailClient.Send(msg);
}
}
ExecuteSqlNonQuery returns an int not a collection which I think you are assuming.
try:
change the loop like so: for(int i= 0; i < results; i++)

Writing HTML code in C#

What I want to do is;
for (int i = 0; i < thexfiles.Length; i++)
{
tosend = tosend + "<tr><td>"+thexfiles[i]+"</td><td>"+thexdates[i]+"</td></tr><tr>";
}
mail.Body = tosend;
I want to insert the data into a table in a C# code (using html perhaps?), so when it's mailed it looks clean.
if you are using the class: System.Net.Mail.MailMessage make sure after assigning the content to the Body property you also set the property IsBodyHtml to true .
that should work.
You simply have to do this:
for (int i = 0; i < thexfiles.Length; i++)
{
tosend = tosend + "<tr><td>"+thexfiles[i]+"</td><td>"+thexdates[i]+"</td></tr>";
}
tosend = "<html><table>" + tosend + "</table></html>";
mail.IsBodyHtml = true;
mail.Body = tosend;
And that's it, the mail body will be shown in HTML table.
Try this
StringBuilder sb = new StringBuilder();
sb.Append("<table>");
sb.Append("<tr><td>Column 1</td><td>Column 2</td></tr>");
for (int i = 0; i < thexfiles.Length; i++)
sb.AppendFormat("<tr><td>{0}</td><td>{1}</td></tr>", thexfiles[i], thexdates[i]);
sb.Append("</table>");
mail.IsBodyHtml = true;
mail.Body = sb.ToString();

Categories

Resources