Email not being shown as HTML even with IsBodyHtml property as true - c#

I have found a lot of open questions about this issue, but none gave me a solution, so I am kind of re-opening other questions here, sorry.
I have an HTML created (from a VB6 application, though that's not very important because I checked it is correctly formatted) and then sent from a .NET Core worker application.
The IsBodyHtml property is being set to true, so it should work correctly.
The HTML I have generated has this structure:
<table>
<thead>
<tr>
<th colspan="2"> Resultado </th>
<th>Índice del vector</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiempo inicio</td>
<td class="centered">{DateTime}</td>
<td class="centered">0</td>
</tr>
<tr>
<td>Tiempo fin</td>
<td class="centered">{DateTime}</td>
<td class="centered">1</td>
</tr>
<tr>
<td>Tiempo total</td>
<td class="centered">{DateTime(Tiempo fin - Tiempo inicio)}</td>
<td class="centered">2</td>
</tr>
<tr>
<td>Tipo de bases de datos</td>
<td class="centered">{"SQL" | "Access"}</td>
<td class="centered">3</td>
</tr>
<tr>
<td>Copia de Documentos</td>
<td class="centered">{ True | False }</td>
<td class="centered">5</td>
</tr>
<tr>
<td>Carpeta no existente</td>
<td class="centered">"TextMessage"</td>
<td class="centered">11</td>
</tr>
</tbody>
</table>
<style>
* {
font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
table,
td {
border: 1px solid #333;
}
th,
td {
padding: 5px;
inline-size: 7rem;
overflow-wrap: break-word;
}
thead,
tfoot {
background-color: #333;
color: #fff;
}
.centered {
text-align: center;
}
</style>
I checked the Gmail references and it should work since the <style> tag is now supported (I think the only thing that is not very well supported is the font-family property), but it still was sent as raw HTML.
Then I tried sending a simple <h1>This is an H1 element</h1>, and it was still not shown correctly, just as raw HTML.
I also tried sending the former HTML with the <body> tag and the <style> tag in the <head> tag.
[EDIT]
Updated with the C# code for the e-mail sender:
private MailMessage SetMessageInfo(EmailService.MailMessage message)
{
MailMessage clientMessage = new Net_MailMessage();
clientMessage.From = new MailAddress(message.From.Address, message.From.DisplayName);
foreach (EmailService.MailAddress email in message.To)
{
clientMessage.To.Add(new MailAddress(email.Address, email.DisplayName));
}
foreach (EmailService.MailAddress email in message.CC)
{
clientMessage.CC.Add(new MailAddress(email.Address, email.DisplayName));
}
foreach (EmailService.MailAddress email in message.Bcc)
{
clientMessage.Bcc.Add(new MailAddress(email.Address, email.DisplayName));
}
clientMessage.Subject = message.Subject;
clientMessage.SubjectEncoding = message.SubjectEncoding;
clientMessage.Body = message.Body;
clientMessage.BodyEncoding = message.BodyEncoding;
clientMessage.IsBodyHtml = true;
if (message.CustomId != null)
{
clientMessage.Headers.Add("custom-id", message.CustomId);
}
return clientMessage;
}
The EmailService class is an intermediary class we created that has a DTO that is almost a copy of the MailMessage class. I can't show it here, sorry.

Related

AutoIncrement Column HTML doesnt show after sending Mail

I have to send a Table that have a column with autoincrement number and when I sent the mail it shows the second column values but none the auto increment numbers:
This is my html script generated by c# code:
<style>
.tableOrder {
counter-reset: rowNumber;
border-collapse: collapse;
text-align: center;
}
.tableOrder tr .counterColumn {
counter-increment: rowNumber;
}
.tableOrder tr .counterColumn:first-child::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
}
</style>
</table>
<font> This is the following order of Pickups Arrives </font> <br><br>
<table class="tableOrder" border="1">
<tr style="background-color:#6FA1D2;color:#ffffff;">
<td style="color:#555555;">Order Arrive</td>
<td style="color:#555555;">Pickup Number</td>
</tr>
<tr>
<td class="counterColumn"></td>
<td>1</td>
</tr>
<tr>
<td class="counterColumn"></td>
<td>1233</td>
</tr>
<tr>
<td class="counterColumn"></td>
<td>521346</td>
</tr>
<tr>
<td class="counterColumn"></td>
<td>1246</td>
</tr>
<tr>
<td class="counterColumn"></td>
<td>7594</td>
</tr>
</table>
and when I run my code and sent the email it didn't show the autoincrement values column
I'm using the SmtpClient in C#
MailMessage message = new MailMessage()
{
From = fromEmail,
Subject = "Subject",
IsBodyHtml = true,
Body = htmlString,
};
message.To.Add(toEmail);
message.CC.Add(ccEmail);

Adding style to table in Email Body in c#

I want to compose a mail with a table with some basic style. Here is my code:
MailMessage mail = new MailMessage();
mail.From = new MailAddress("abc#domain.com");
mail.To.Add("myname#domain.com");
mail.Body = string.Format(#"<html>
<body>
<style>
table, th, td {
border: 1px solid black;
line-height: 24px;
font-size:14px;
font-family:verdana;
text-align: center;
}
</style>
<p style=""""font-family:verdana""""> Status :</p>
<table style=""""width=50%""""><tr>
<th >No. of Students</th>
<th >No. of Pass</th>
<th >No. of Failures </th>
<tr/><tr style=""""height=120%"""">
<td>{0} </td>
<td style=""""color:green"""">{1} </td>
<td style=""""color:red"""">{2} </td>
</tr></table>
<p style=""""font-family:verdana""""> Please refer to the
Log files for more details.</p>
</body>
</html>",student.Total, student.Pass,student.Fail);
mail.Subject = "Report";
};
mail.IsBodyHtml = true;
This gives me an Exception saying 'Input string is not in correct format'. If I remove the style, paragraph, and keep only , it works but no borders are present in table. How can I style my mail?
I changed the body like this, but the style is not reflected.
mail.Body = string.Format(#"
<p style=""font-family:verdana""> Status :</p>
<table style=""border: 1px solid black"", ""text-align: center""><tr>
<th style=""border: 1px solid black"">No. of new records added</th>
<th style=""border: 1px solid black"">No. of records transferred </th>
<th style=""border: 1px solid black"">No. of records not transferred </th>
<tr/><tr style=""height=120%"">
<td style=""border: 1px solid black"" ""text-align: center"">CompanyName.Value </td>
<td style=""border: 1px solid black"" ""text-align: center"" ""color:green"">1000 </td>
<td style=""border: 1px solid black"" ""text-align: center"" ""color:red"">82 </td>
</tr></table>
<p style=""font-family:verdana""> Please refer to the Log files for more details.</p>
");
Your syntax is wrong while adding style for <table> and <p>. Do it in the following way, for example:
<table style="width: 50%">
Similarly change the syntax wherever you have used style.

how to set background color and table border in pdf file using html in c#

i have created pdf file genration using html template. but after generating pdf background color on h4 tag and and color also not set please suggest me
i have try to inline css on set background color and table proper border color in html but after generating pdf this css not apply it
Controller:-
public void abcd()
{
try
{
string abc = Request.QueryString["abc"];
string strFileName = abc;
string strFileExtension = ".pdf";
string strContentType = FileManager.FileContentType_application_msexcel;
string strExportData = string.Empty;
Document pdfDoc = new Document(PageSize.A4, 43f, 50f, 5f, 50f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
var output = new MemoryStream();
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
StringReader sr;
sr = new StringReader(Convert.ToString(ExportData.abcUserDetails(abc)));
PdfWriter.GetInstance(pdfDoc, output);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
strFileName = strFileName.Replace(" - ", "-").Replace(" ", "-").Replace("--", "-");
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment; filename={0}{1}", strFileName, strFileExtension));
Response.ContentType = strContentType;
Response.Charset = "";
Response.BinaryWrite(output.ToArray());
Response.Flush();
Response.End();
}
catch (Exception ex)
{
Settings.exceptionLog.Publish(ex);
}
}
Model:-
public static string abcUserDetails(string abc)
{
string strHtmlBody = (new WebClient()).DownloadString(HttpContext.Current.Server.MapPath("~/Templates/abcUserDetails.html"));
string DomainURL = Settings.GetSettingsKeyValue("DomainURL");
IDictionary<string, string> objData = new Dictionary<string, string>();
dynamic dtUser = User.GetuserDetails(abc);
foreach (dynamic m in dtUser)
{
objData.Add("User.Name", Convert.ToString(m["Name"]));
objData.Add("User.RegNo", Convert.ToString(m["RegNo"]));
objData.Add("User.Gender", Convert.ToString(m["Gender"]));
objData.Add("User.EmailId", Convert.ToString(m["EmailId"]));
objData.Add("User.Address", Convert.ToString(m["VLEAddress"]));
}
string strValue = string.Empty;
foreach (KeyValuePair<string, string> data in objData)
{
strValue = HttpUtility.HtmlEncode(data.Value);
strHtmlBody = strHtmlBody.Replace(string.Format("%{0}%", data.Key), strValue);
}
return strHtmlBody;
}
html template:-
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<link href="../css/custom/style.css" rel="stylesheet" />
<title></title>
</head>
<body style="font-family:Arial;font-size:7.5px;vertical-align:top!important;">
<h4 style="background-color:#d48d88;text-transform: uppercase;font-weight:bold;width:100%;">
User Details
</h4>
<table border="1" style="color:#000000;border-color:#6f6f6f;border-style: ridge;">
<tr>
<td valign="top" style="font-weight:bold;">
<b>Name</b>
</td>
<td valign="top">
%User.Name%
</td>
<td valign="top" style="font-weight:bold;">
<b>Mobile number</b>
</td>
<td valign="top">
%User.Mobile%
</td>
<td valign="top" style="font-weight:bold;">
<b>Email Id</b>
</td>
<td valign="top">
%User.Email%
</td>
</tr>
</table>
</body>
</html>
Expected Output:-
By default the HTML to PDF converter will render the HTML document for 'screen', but this can be changed when another media type is assigned to HtmlToPdf.MediaType property.
For example, when this property is set to 'print' the CSS properties defined by the '#media print' rule will be used when the HTML is rendered instead of the CSS properties defined by the '#media screen' rule.
p {
font-family: Verdana;
font-size: 14px;
font-style: italic;
color: Green;
}
#media print {
p {
border-style: dashed;
}
}
thead th{
background: #ddd;
}
table {
width: 100% !important;
max-width: 100%;
border-spacing: 0;
border-collapse: collapse;
border-bottom: none;
}
th, td {
border: 1px solid #a9a6a6;
padding: 5px 8px;
text-align: left;
}
h4 {
background-color: #d48d88;
color: white;
padding: 5px;
text-align: center;
font-size: 16px;
}
<h4>User Details</h4>
<table>
<thead>
<tr>
<th>Name </th>
<th> %User.Name%</th>
<th>Mobile number</th>
<th> %User.Mobile%</th>
<th>Email Id</th>
<th>%User.Email%</th>
</tr>
</thead>
<tbody>
<tr>
<td> your name </td>
<td> user name </td>
<td> your mobile </td>
<td> your mobile no </td>
<td> example#gmail.com </td>
<td> User email</td>
</tr>
<tr>
<td> your name </td>
<td> user name </td>
<td> your mobile </td>
<td> your mobile no </td>
<td> example#gmail.com </td>
<td> User email</td>
</tr>
</tbody>
</table>
[ hope it'll help you :::::::::::: let me know if it works.]

Export to Excel fails on some machines

We are developing a Web application and some of our query results need to be Exported to Excel. We are using the following C# code to Export :
System.Web.HttpContext ctx = System.Web.HttpContext.Current;
CurrentPackingListModel.Voyage.ShipmentDataContext = ShipmentDataContext;
ctx.Response.Clear();
string filename = "ApprovalForm.xls";
ctx.Response.AddHeader("content-disposition", "attachment;filename=" + filename);
ctx.Response.ContentType = "application/vnd.ms-excel";
ctx.Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
ctx.Response.Charset = "UTF-8";
return View("../Packing/_ExportApprovalForm", CurrentPackingListModel);
The partial View I am returning to result is as follows :
<body id="body" onload="window.print();">
<table>
<tbody>
<tr>
<td class="table-header" colspan="8">
<div style="width: 100%">
<div class="lleft">
#* <img id="imgLogo" src="~/Images/myLogo.png" />*#
</div>
<div class="baslik">Approval Packing List Form</div>
<div style="float: right;">#DateTime.Now.ToString("MM.dd.yyyy")</div>
</div>
</td>
</tr>
<tr>
<td colspan="6"></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td class="line-header">#Html.DisplayNameFor(x => x.ID)</td>
<td>: #Html.HiddenFor(x => x.ID)#Html.DisplayFor(x => x.ID)</td>
<td class="line-header" style="width: 165px;">#Html.DisplayNameFor(x => x.Voyage.StartDate)</td>
<td>: #Html.DisplayFor(x => x.Voyage.StartDate)</td>
<td class="line-header">#Html.DisplayNameFor(x => x.Voyage.VesselID)</td>
<td>: #Html.DisplayFor(x => x.Voyage.VesselText)
</td>
</tr>
<tr>
<td class="line-header">#Html.DisplayNameFor(x => x.Voyage.Id)</td>
<td>: #Html.DisplayFor(x => x.Voyage.Id)</td>
<td class="line-header" style="width: 165px;">#Html.DisplayNameFor(x => x.Voyage.EndDate)</td>
<td>: #Html.DisplayFor(x => x.Voyage.EndDate)</td>
<td></td>
<td></td>
</tr>
<tr>
<td colspan="6">
<hr />
</td>
</tr>
</tbody>
</table>
<table>
<tr>
<td class="line-header" style="width: 160px;">Approve Personel</td>
<td style="border: solid 1px; width: 180px;"></td>
<td class="line-header">Discharge Port</td>
<td style="border: solid 1px; width: 180px;"></td>
</tr>
<tr>
<td class="line-header">Approve Date</td>
<td style="border: solid 1px;"></td>
<td class="line-header">Terminal</td>
<td style="border: solid 1px;"></td>
</tr>
<tr>
<td class="line-header">Signiture</td>
<td style="border: solid 1px;"></td>
<td></td>
<td></td>
</tr>
</table>
#if (Request.QueryString["type"] == "HRC" && Model.HrcListPrint != null)
{
<table>
<tr>
<td colspan="10" style="height: 20px;">
<hr />
</td>
</tr>
<tr>
<td style="text-align: center; width: 210mm; font-weight: bold;" colspan="11">HRC LIST
</td>
</tr>
</table>
<table class="display dataTable no-footer">
<thead>
<tr>
<th>Customer Name</th>
<th>Customer PO No</th>
<th>Ord. ITem No</th>
<th>CM No</th>
<th>Product</th>
<th>Size (T x W inch)</th>
<th>Thickness Tolerance</th>
<th>Qty (tons)</th>
<th>Coil Weight (Lbs)</th>
<th>Destination Port</th>
<th>Barcode</th>
<th>Heat No</th>
<th>Status</th>
</tr>
</thead>
<tbody>
#foreach (MedTrade.Apollo.Shared.Models.Shipment.PackingListDetailModel item in Model.HrcListPrint)
{
<tr>
<td>#item.CustomerName</td>
<td>#item.CustomerPurchaseOrderNumber</td>
<td>#String.Format("'{0}'", item.OrderItemText)</td>
<td>#item.CMNO</td>
<td>#item.ProductStandartName</td>
<td>#item.ProductProperty</td>
<td>#item.ThicknessToleranceType</td>
<td>#((item.Quantity / 1000).ToString("N3"))</td>
<td>#item.CoilWeight.ToString("N0")</td>
<td>#item.DischargePortTanim</td>
<td>#item.BarcodeNo</td>
<td>#item.HeatNo</td>
<td>#item.StatusText</td>
</tr>
}
</tbody>
</table>
}
#if (Request.QueryString["type"] == "Rebar" && Model.RebarListPrint != null)
{
<table>
<tr>
<td colspan="10" style="height: 20px;">
<hr />
</td>
</tr>
<tr>
<td style="text-align: center; width: 210mm; font-weight: bold;" colspan="10">REBAR LIST
</td>
</tr>
</table>
<table class="display dataTable no-footer">
<thead>
<tr>
<th>Customer Name</th>
<th>Customer PO No</th>
<th>Ord. ITem No</th>
<th>CM No</th>
<th>Product</th>
<th>Size (D x L inch)</th>
#if (Model.SearchCriteria.ViewType == ViewType.Group)
{
<th>Qty (tons) / # of bundles</th>
}
else
{
<th>Quantity (Tons)</th>
}
<th>Bundle Weight (Lbs)</th>
<th>Destination Port</th>
#if (Model.SearchCriteria.ViewType == ViewType.Detail)
{
<th>Barcode</th>
}
<th>Heat No</th>
<th>Status</th>
</tr>
</thead>
<tbody>
#foreach (MedTrade.Apollo.Shared.Models.Shipment.PackingListDetailModel item in Model.RebarListPrint)
{
<tr>
<td>#item.CustomerName</td>
<td>#item.CustomerPurchaseOrderNumber</td>
<td>#String.Format("'{0}'", item.OrderItemText)</td>
<td>#item.CMNO</td>
<td>#item.ProductStandartName</td>
<td>#item.ProductProperty</td>
#if (Model.SearchCriteria.ViewType == ViewType.Group)
{
<td>#((item.Quantity / 1000).ToString("N3")) / #item.Count</td>
}
else
{
<td>#((item.Quantity / 1000).ToString("N3"))</td>
}
<td>#item.BundleWeight.ToString("N0")</td>
<td>#item.DischargePortTanim</td>
#if (Model.SearchCriteria.ViewType == ViewType.Detail)
{
<td>#item.BarcodeNo</td>
}
<td>#item.HeatNo</td>
<td>#item.StatusText</td>
</tr>
}
</tbody>
</table>
}
</body>
But export to Excel works on some machines, but not others. This started to happen only recently.
Is there a possible solution to fix this without re-writing the whole Exporting functionality?
Apologies this is not an answer but i am unable to comment as i have low rep.
IS excel installed on the machines it is not working on? From my memory excel must be installed for you to export. I have used Epplus to get around this in the past.
Are you able to add some exception handling and logging around this issued so you can get more details from the error? Even if you just write it to a txt file on the machine.
Sorry i dont have any actual answers.
May below code will be helpful for you:
public void ExportToExcel()
{
DataGrid dgGrid = new DataGrid();
dgGrid.DataSource = /*Give your data source here*/;
dgGrid.DataBind();
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.Buffer = true;
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", "Data Report.xls"));
System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
System.Web.HttpContext.Current.Response.Charset = "";
System.IO.StringWriter sw = new System.IO.StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
dgGrid.RenderControl(htw);
System.Web.HttpContext.Current.Response.Output.Write(sw.ToString());
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.End();
}

Grabbing a timesheet HTMLAgilityPack

I need to grab a timesheets from a website. I want to store/add this timesheet to a data table in my C# Application.
The structure of the data table looks like this:
1. | Day | Time | Status |
2. ..1.......7:00.........IN
3. ..1.......9:45.......OUT
4. ..1......10:15........IN
5. ..1......15:45......OUT
6. ..1.......8:45.....TOTAL
7. ..2 .. ..
My C# code for the DataTable:
DataTable table = new DataTable("Worksheet");
table.Columns.Add("Day");
table.Columns.Add("Time");
table.Columns.Add("Status");
I tried different variants and I always mess up with all the data.
For testing purpose I made a new Winform with a "textbox" (for the sitepath) and "button"(to start the process)
Then I want HTMLAgilityPack to get all the data. one example:
public string[] GREYsource;
public Form1()
{
InitializeComponent();
}
private void btnSubmit_Click(object sender, EventArgs e)
{
var doc = new HtmlAgilityPack.HtmlDocument();
var fileName = txtPath.Text; // I downloaded the HTML-File
doc.Load(fileName);
string strGREYInner;
foreach (HtmlNode td in doc.DocumentNode.SelectNodes("//tr[#class=\"tblDataGreyNH\"]"))
{
strGREYInner = td.InnerText.Trim();
string shorted = strGREYInner.Replace("\t", ""); string shorted2 = shorted.Replace("\n\n\n\n", "\n\n\n"); string shorted3 = shorted2.Replace("\n\n\n", "\n\n"); string shorted4 = shorted3.Replace("\n\n", "\n");
GREYsource = shorted4.Split(new Char[] { '\n', });
}
foreach (string str in GREYsource)
{
...
}
}
Problem: the result contains a lot of tabs(/t) and newlines(/n) I need to trim.
Problem: This isn't a good way to do it, IMO. And this would just grab the Totaltimes.
It can be done better.
This is just a example I tried (other codes just went a pile of junk)
I attached the HTML-structure below:
Overview(picture):
A bit more in depth:
<html>
<head>
</head>
<style type="text/css">
</style>
<body id="body" onload="handleMenuOverlapLogo();onload_column_expand();;firstElementFocus();">
<.. some (java)scripts> /* has to be ignoered. not necessary */
<.. some other divs> /* has to be ignoered. not necessary */
<div id="rowContent"> /* This <div> contains the content i need */
<div id="titleTab"> /* Title is not necessary */
</div>
<div id="rowContentInner"> /* Here the content starts */
<table class="tblList">
<tbody>
<tr> /* not necessary */
<tr class="tblHeader"> /* not necessary */
<tr class="tblHeader"> /* not necessary */
<tr class="tblDataWhiteNH"> /* IN : */
<td class="tblHeader" style="font-weight: bold; text-align: right"> In </td>
<td nowrap=""> /* "tblDataWhiteNH" always contains 7 "td nowrap"
<td nowrap="">
<td nowrap=""> /* Example: if it contains a value */
<table width="100%" border="0" align="center">
<tbody>
<tr>
<td width="25%" align="left"> </td>
<td nowrap="" width="50%" align="center"> 7:53 </td> /* value = 7:53 (THIS!) */
<td width="25%" align="right"> </td>
</tr>
</tbody>
</table>
</td>
<td nowrap="">
<td nowrap=""> /* Example: if it contains no value */
<table width="100%" border="0" align="center">
<tbody>
<tr>
<td width="25%" align="left"> </td>
<td nowrap="" width="50%" align="center"> /* no value = 0:00 (THIS!) */
<td width="25%" align="right"> </td>
</tr>
</tbody>
</table>
</td>
<td nowrap="">
<td nowrap="">
<tr class="tblDataWhiteNH"> /* OUT : */
<td class="tblHeader" style="font-weight: bold; text-align: right"> Out </td>
<td nowrap=""> /* "tblDataWhiteNH" always contains 7 "td nowrap".
<td nowrap="">
<td nowrap=""> /* Example: if it contains a value */
<table width="100%" border="0" align="center">
<tbody>
<tr>
<td width="25%" align="left"> </td>
<td nowrap="" width="50%" align="center"> 7:53 </td> /* value = 7:53 (THIS!) */
<td width="25%" align="right"> </td>
</tr>
</tbody>
</table>
</td>
<td nowrap="">
<td nowrap=""> /* Example: if it contains no value */
<table width="100%" border="0" align="center">
<tbody>
<tr>
<td width="25%" align="left"> </td>
<td nowrap="" width="50%" align="center"> /* no value = 0:00 (THIS!) */
<td width="25%" align="right"> </td>
</tr>
</tbody>
</table>
</td>
<td nowrap="">
<td nowrap="">
<tr class="tblDataGreyNH"> /* IN : */
<tr class="tblDataGreyNH"> /* OUT : */
... /* "tblDataGreyNH" is built up the same way like "tblDataWhiteNH".
... /* sometimes there could be more "tblDataWhiteNH" and "tblDataGreyNH". */
... /* Usally there are just the "tblDataWhiteNH"(IN/OUT) */
<tr class="tblHeader"> /* not necessary */
/* It continues f.egs. with "tblDataWhite" if the last above header was a "tblDatagrey" */
/* and versa vice ("grey" if there was a "white" before.) */
<tr class="tblDataWhiteNH"> /* Worked : */
<td class="tblHeader" style="font-weight: bold; text-align: right"> Total Time </td>
<td> 07:47 </td> /* value = 7:47 (THIS!) */
<td> 04:48 </td>
<td> 00:00 </td> /* no value = 0:00 (THIS!) */
<td> 00:00 </td>
<td> 07:42 </td>
<td> 00:00 </td>
<td> 00:00 </td>
</tr>
<tr class="tblDataGreyNH"> /* Total : */
<td class="tblHeader" style="font-weight: bold; text-align: right"> Regular Time </td>
<td> 07:47 </td> /* value = 7:47 (THIS!) */
<td> 04:48 </td>
<td> </td> /* no value = 0:00 (THIS!) */
<td> </td>
<td> 07:42 </td>
<td> </td>
<td> </td>
</tr>
<tr class="tblHeader"> /* not necessary */
<tr valign="top"> /* not necessary */
</tbody>
</table>
</div>
</div>
</body>
</html>
a copy of the original HTML: http://time.wnb.dk/123/
I Hope anyone could help me get this to work.
Okay let me explain it with a picture. https://www.abload.de/img/eeeqnuwu.png
On the Picture you see the website + a table below, how the result should look like.
Declaring the Datatable isnt the problem.
The main problem is I can't get htmlagility to spit out right results and if it did, its almost buggy.
Some of the selectnodes I tried got the output messed up after a while. As yet I wasn't able to get "all" data from the table on the website, just some values, but often buggy.
So I'm actually searching for someone who could take a look on this and maybe help me to find the right selectnodes.
Not sure I fully understand what you want to do but here is a sample code that should help you get started. I strongly suggest you have a look at XPATH to understand it.
HtmlDocument doc = new HtmlDocument();
doc.Load(yourFile);
// get all TR with a specific class name, starting from root (/), and recursively (//)
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//tr[#class='tblDataGreyNH' or #class='tblDataWhiteNH']"))
{
// get all TD below the current node with a specific class name
HtmlNode inOrOut = node.SelectSingleNode("td[#class='tblHeader']");
if (inOrOut != null)
{
string io = inOrOut.InnerText.Trim();
Console.WriteLine(io.ToUpper());
if (io.Contains("Time"))
{
// normalize-space gets rid or whitespaces (\r,\n, etc.)
// text() gets the node's inner text
foreach (HtmlNode td in node.SelectNodes("td[normalize-space(#class)='' and normalize-space(text())!='' and normalize-space(text())!='00:00']"))
{
Console.WriteLine("value:" + td.InnerText.Trim());
}
}
}
// gets all TD below the current node that define the NOWRAP attribute
HtmlNodeCollection tdNoWraps = node.SelectNodes("td[#nowrap]");
if (tdNoWraps != null)
{
foreach (HtmlNode tdNoWrap in tdNoWraps)
{
string value = tdNoWrap.InnerText.Trim();
if (value == string.Empty)
continue;
Console.WriteLine("value:" + value);
}
}
}
It will output this from your sample page:
IN
value:7:47
value:7:46
value:7:45
value:7:51
OUT
value:15:35
value:15:33
value:12:38
value:8:59
IN
value:12:38
value:8:59
OUT
value:15:35
TOTAL TIME
value:07:48
value:07:47
value:07:50
value:01:08
REGULAR TIME
value:07:48
value:07:47
value:07:50
value:01:08

Categories