【问题标题】:How to control styling of a dynamic html table of a static html page through App.config file in a c# console application?如何通过 c# 控制台应用程序中的 App.config 文件控制静态 html 页面的动态 html 表的样式?
【发布时间】:2020-08-11 21:09:31
【问题描述】:

我一直在尝试做某事。我有一个控制台应用程序,它查找一些文件,如果它们存在与否。因此,此应用程序会向我的电子邮件 ID 发送一封电子邮件。为电子邮件格式创建了一个普通的 SuccessBody.html。

现在,我正在尝试在 message.html 中动态添加一个 html 表,如下所示。

HTML

<body>
    Hi All,
    <br />
    <br />
    Please be informed that below files for this month <b>are available</b>.
    <br />
    <br />
    <table align="center" ; width="1000" style="border-collapse:collapse; border-color:#17202A; text-align:center;">
        <tr height="30" ; style="background-color:#CED8F6; color:#17202A; font-weight:bold; font-size:20px; font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif;">
            <td colspan="2" ; style=" border-color:#FFFFFF; border-style:solid; border-width:thick; padding: 5px;">$Title$</td>
        </tr>
        <tr style="background-color:#143665; color:#FFFFFF; font-weight:bold; font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif;">$Columns$</tr>
        $Rows$
    </table>
    <br />
    <br />
    <b>Please take necessary actions.</b>
    <br />
    <br />
    Regards,
    <br />
    Ricky
</body>

我不想在代码本身中做这个表的设计,而是通过配置文件。而最关键的部分是while循环的设计。 $Title$、$Column$ 和 $Rows$ 是我想用 c# 中的一些代码替换的字符串,如下所示:

C#

public static void DataTableToHTML(DataTable Entries)
        {
            string mailbody = string.Empty;
            if (Entries.Rows.Count.Equals(0))
            {
                string email_body_error = File.ReadAllText(ConfigurationManager.AppSettings["Body_Fail"]);
                mailbody = email_body_error;
            }
            else
            {
                string email_body_success = string.Empty;
                string html = string.Empty;
                TextWriter writehtmlFile = new StreamWriter(Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".html");
                string ConfigTitle = ConfigurationManager.AppSettings["Title"];
                File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]).Replace("$Title$", ConfigTitle);
                for (int i = 0; i < Entries.Columns.Count; i++)
                {
                    html += ConfigurationManager.AppSettings["ForColumns"] + Entries.Columns[i].ColumnName + "</td>";
                }
                File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]).Replace("$Columns$", html);
                //add rows
                for (int i = 0; i < Entries.Rows.Count; i++)
                {
                    html += ConfigurationManager.AppSettings["ForRows"];
                    for (int j = 0; j < Entries.Columns.Count; j++)
                        html += ConfigurationManager.AppSettings["RowData"] + Entries.Rows[i][j].ToString() + "</td>";
                    html += "</tr>";
                }
                writehtmlFile.WriteLine(html);
                writehtmlFile.Flush();
                writehtmlFile.Close();
                email_body_success = File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]).Replace("$Rows$", html);

                mailbody = email_body_success;
            }
            SendEmail(mailbody, DateTime.Now);
        }

我想在配置文件(AppConfig.xml)中配置这个表的设置,并从那里在上面的代码中使用它。

配置文件

<add key="FileName" value="File Name"/>
    <add key="Date" value="Creation Date"/>
    <add key ="ForColumns" value="&lt;td style=\&quot; border-color:#FFFFFF; border-style:solid; border-width:thick; padding: 5px;\&quot;&gt;"/>
    <add key="ForRows" value="&lt;tr style =\&quot;color:#17202A; font-weight:bold; font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif;\&quot; &gt;"/>
    <add key="RowData" value="&lt;td style=\&quot; border-color:#FFFFFF; background-color:#F3E2A9; border-style:solid; border-width:thick; padding: 5px;\&quot;&gt;"/>
    <add key="Body_Success" value="HTMLBody\SuccessBody.html"/>

Body_Success 是 SuccessBody.html 的位置 = App 的位置。

$Title$ 很容易被替换。但是,$Column$ 和 $Rows$ 并没有像我希望的那样被替换。如果有人能帮助我,那就太好了。

【问题讨论】:

  • ReadAllText 返回一个字符串。你根本不存储它。 IIRC 编译器对此发出警告。

标签: c# html app-config


【解决方案1】:

在 .Net(和许多其他工具堆栈)中,字符串应该是不可变的。这意味着一旦你完成了:

string foo = "bar";

如果您检查 var foo,您总会找到“bar”。如果您希望 foo 成为其他内容,则必须为其分配一个新值:

string foo = "fubar";
string huh = foo.Replace("fu", "foo");

同样的原则也适用于你调用字符串的方法,比如Replace。该方法返回一个新字符串,其中原始字符串替换为新值。所以在上面的例子中,huh 的值是“foobar”,而foo 的值仍然是“fubar”。

因此在这一行:

File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]).Replace("$Title$", ConfigTitle);

您正在将替换的结果丢在地上。

改为这样做:

// read the template from the file once and put it in a variable
email_body_success = File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]);
// replace the title by storing the replaced value again the same variable
email_body_success = email_body_success.Replace("$Title$", ConfigTitle);

从现在开始,email_body_success 将拥有带有(部分)替换模板的字符串。您不需要(这样做是错误的)再次致电File.ReadAlltext。因为如果这样做,您将再次从文件中读取模板,丢弃已替换的内容。

现在我们来看看列和行的两个循环。一旦你建立了你需要的东西,html 的内容需要替换为email_body_success 中的标记。

代替:

File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]).Replace("$Columns$", html);

// replace the columns
email_body_success = email_body_success.Replace("$Columns$", html);
html = String.Empty; // html is stored, let's reset for its next use.

因为现在email_body_success 将使用我们用于 $Columns$ 的新 html 部分替换我们之前的部分模板。在您的 Rows 循环开始时,您希望将 html 字符串重新设置为空,这样它就不会仍然保留列

在 Rows 循环结束时,需要应用相同的修复程序。替换

email_body_success = File.ReadAllText(ConfigurationManager.AppSettings["Body_Success"]).Replace("$Rows$", html);

 // replace the rows
 email_body_success = email_body_success.Replace("$Rows$", html);

这应该会在email_body_success 中为您提供带有替换部分的模板。

我不确定你想用这行实现什么:

writehtmlFile.WriteLine(html);

但如果您打算将整个模板写入该文件,则需要将html 替换为email_body_success 变量并将这些行移到最后一个替换之后。

【讨论】:

  • 是的! @rene。我也在研究代码,并认为如果我遵循这种方法,我不需要流编写器来编写 html 文件。但还不够确定`:)。
【解决方案2】:
I would suggest - 
Create html file and save email html part along with keywords which you want to replace like as ForColumns ,ForRows.
e.g. 
<html>
  <body>
    <table>
      <thead>
       <th>ForColumns1 </th>
       <th>ForColumns2 </th>
      </thead>
     <tr>ForRows1</tr>
     <tr>ForRows2</tr>
   </table>
  </body>
</html>


while sending mail get replace keyword(ForColumns,ForRows) value from config and replace with html file data.

【讨论】:

    猜你喜欢
    • 2013-10-27
    • 2012-04-21
    • 2010-12-13
    • 2016-10-21
    • 2014-11-15
    • 2022-11-11
    • 2017-01-15
    • 1970-01-01
    • 2020-04-09
    相关资源
    最近更新 更多