I need help in achieveing a requirement, please. How do I achieve a situation where I can send pdf documents, as attachment, via email to multiple recipients displayed in a GridView, without mixing up the document?
What I mean is, let's say I have about 5 recipients that I want to send these documents attachment to. Each document bears the name of each recipient, and I want to send them to each recipient accordingly.
For example:
Recipients: Timothy, Sandra, Eric, Michael, Rita
Documents: 1, 2, 3, 4, 5.
Document 1 has Timothy's name on it, Document 2 has Sandra's name on it, Document 3 has Eric's name on it, and so on.... So I want to send these documents such that Document 1 will not go to Eric, Sandra, Michael or Rita because it's Timothy's document, and Document 2 will not go any other recipient but only to Sandra. I also do not want one particular document to be sent to all recipients.
The documents are saved in the Database in PDF format. My GridView has Pagination. I would want that even if I have hundred names in the Gridview, I can send to the names even if some names will be displayed in other GridView pages due to the Pagination. I hope my explanation can be easily understood?
Thank you
Here is my GridView where the recipients' names are displayed along with their email addresses
<div class="col-sm-11" style="width: 100%; margin: 0 auto; padding: 10px; margin-right: auto; margin-left: auto;">
    <asp:Label ID="createby" runat="server" Text="1"></asp:Label>
    <asp:UpdatePanel ID="panel" runat="server" ChildrenAsTriggers="true">
        <ContentTemplate>
            <div class="container-fluid p-3 mb5 bg-white rounded" id="card" style="margin: 0 auto; padding: 10px; border: 1.3px solid #e4e7e8;">
                <asp:GridView ID="GridView1" runat="server" GridLines="None" DataKeyNames="Id" AllowPaging="true" HeaderStyle-BackColor="#fdfdfd" HeaderStyle-Font-Bold="false" HeaderStyle-ForeColor="#05214d" HeaderStyle-Font-Size="10pt" Font-Size="9pt"
                    AutoGenerateColumns="false" HeaderStyle-HorizontalAlign="left" RowStyle-HorizontalAlign="Left" OnPageIndexChanging="OnPageIndexChanging" class="table" Width="100%">
                    <EmptyDataTemplate>
                        <div style="text-align: center; font-weight: 500; margin-top: 2%;">
                            <i class="fal fa-file-times" style="margin: 0 auto; font-size: 30pt; color: #145c7c;"></i>
                            <p id="P1" runat="server" style="font-size: 11pt; font-weight: 400;">No Recipient</p>
                        </div>
                    </EmptyDataTemplate>
                    <Columns>
                        <asp:TemplateField>
                            <ItemTemplate>
                                <asp:CheckBox ID="CheckSelected" runat="server" />
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:BoundField DataField="Id" HeaderText="ID" HeaderStyle-Font-Bold="false" />
                        <asp:BoundField DataField="Recipient" HeaderText="Recipients" HeaderStyle-Font-Bold="false" />
                        <asp:TemplateField HeaderText="Email" HeaderStyle-Font-Bold="false">
                            <ItemTemplate>
                                <asp:HyperLink ID="emailLink" runat="server" Text='<%# Eval("RecEmail") %>' NavigateUrl='<%# Eval("RecEmail", "mailto:{0}") %>' />
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:BoundField DataField="AwardDate" HeaderText="Date" HeaderStyle-Font-Bold="false" />
                    </Columns>
                </asp:GridView>
 
                <div style="float: right; font-size: 10pt; margin-right: 1%;">
                    Showing Page 
                    <asp:Label ID="lblPageIndex" runat="server" Text="Label" />
                     of 
                    <asp:Label ID="lblTotalPage" runat="server" />
                    (<asp:Label ID="lblTotal" runat="server" />
                    Records)  
                    <div class="dvPager">
                        <asp:Repeater ID="rptPager" runat="server">
                            <ItemTemplate>
                                <asp:LinkButton ID="lnkPage" runat="server" Text='<%#Eval("Text") %>' CommandArgument='<%# Eval("Value") %>'
                                    CssClass='<%# Convert.ToBoolean(Eval("Enabled")) ? "page_enabled" : "page_disabled" %>'
                                    OnClick="Page_Changed" OnClientClick='<%# !Convert.ToBoolean(Eval("Enabled")) ? "return false;" : "" %>'></asp:LinkButton>
                            </ItemTemplate>
                        </asp:Repeater>
                    </div>
                </div>
                <br />
                <br />
            </div>
        </ContentTemplate>
    </asp:UpdatePanel>
</div>
<div class="col-sm-10" style="width: 100%; margin: 0 auto; padding: 10px; padding-bottom: 10px;">
    <div class="row">
        <div class="col-sm-11">
            <div class="form-group">
                <asp:Label CssClass="element" ID="Label1" runat="server">Subject</asp:Label>
                <div class="input-group">
                    <asp:TextBox ID="TextSubject" runat="server" AutoCompleteType="None" Height="32" CssClass="form-control" placeholder="e.g Document File" />
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-11">
            <div class="form-group">
                <div class="input-group">
                    <asp:TextBox ID="txtBody" runat="server" CssClass="form-control" Width="100%" Font-Size="10pt" TextMode="MultiLine" placeholder="e.g. Please download your documents below" Style="overflow: hidden; resize: none;" oninput="Resize(this)" />
                    <script type="text/javascript">
                        function Resize(textbox) {
                            textbox.style.height = "";
                            textbox.style.height = Math.min(textbox.scrollHeight, 300) + "px";
                        }
                    </script>
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-11">
            <div class="form-group">
                <div class="input-group">
                    <asp:Button ID="SendBtn" CssClass="btn btn-primary" Text="Send Documents" runat="server" OnClick="SendBulkDocument" />
                </div>
            </div>
        </div>
    </div>
</div>
Stored Procedure
CREATE PROCEDURE [dbo].[Recipients]
     @CreatedBy VARCHAR(50)
    ,@PageIndex INT
    ,@PageSize INT
    ,@RecordCount INT OUT
 
AS
    BEGIN
    SELECT ROW_NUMBER() OVER(ORDER BY Id DESC) RowNumber
            ,Id
            ,Recipient
            ,RecEmail
            ,DocumentData
            ,AwardDate
            ,CreatedBy
    INTO #Temp
    FROM DpcumentTable
    WHERE CreatedBy = @CreatedBy ORDER BY Id DESC
 
    SELECT @RecordCount = COUNT(*) FROM #Temp
 
    SELECT * FROM #Temp
    WHERE (RowNumber BETWEEN ((@PageIndex-1) * @PageSize) + 1 AND (@PageIndex * @PageSize)) OR @PageIndex = - 1 ORDER BY Id DESC
    
    DROP TABLE #Temp
 
END
C# Sending documents to each recipient
private void GetRecipient(int pageIndex)
{
    using (SqlConnection con = new SqlConnection())
    {
        con.ConnectionString = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
        try
        {
            using (SqlCommand cmd = new SqlCommand("Recipients", con))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@CreatedBy", createby.Text.Trim());
                cmd.Parameters.AddWithValue("@PageIndex", pageIndex);
                cmd.Parameters.AddWithValue("@PageSize", PageSize);
                cmd.Parameters.Add("@RecordCount", SqlDbType.Int, 4);
                cmd.Parameters["@RecordCount"].Direction = ParameterDirection.Output;
                con.Open();
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    cmd.Connection = con;
                    sda.SelectCommand = cmd;
                    using (DataTable dt = new DataTable())
                    {
                        sda.Fill(dt);
                        using (SqlDataReader dr = cmd.ExecuteReader())
                            if (dr.HasRows)
                            {
                                GridView1.DataSource = dt;
                                GridView1.DataBind();
                            }
                            else
                            {
                            }
                        int recordCount = Convert.ToInt32(cmd.Parameters["@RecordCount"].Value);
                        this.PopulatePager(recordCount, pageIndex);
                    }
                }
                con.Close();
            }
        }
        catch (SqlException ex)
        {
            string msg = "Error:";
            msg += ex.Message;
            throw new Exception(msg);
        }
    }
}
protected void Page_Changed(object sender, EventArgs e)
{
    int pageIndex = int.Parse((sender as LinkButton).CommandArgument);
    this.GetRecipient(pageIndex);
}
private void PopulatePager(int recordCount, int currentPage)
{
    double dblPageCount = (double)((decimal)recordCount / (decimal)PageSize);
    int pageCount = (int)Math.Ceiling(dblPageCount);
    List<ListItem> pages = new List<ListItem>();
    if (pageCount > 0)
    {
        if (currentPage != 1)
        {
            pages.Add(new ListItem("Prev", (currentPage - 1).ToString()));
        }
        if (pageCount < 4)
        {
            for (int i = 1; i <= pageCount; i++)
            {
                pages.Add(new ListItem(i.ToString(), i.ToString(), i != currentPage));
            }
        }
        else if (currentPage < 4)
        {
            for (int i = 1; i <= 4; i++)
            {
                pages.Add(new ListItem(i.ToString(), i.ToString(), i != currentPage));
            }
            pages.Add(new ListItem("...", (currentPage).ToString(), false));
        }
        else if (currentPage > pageCount - 4)
        {
            pages.Add(new ListItem("...", (currentPage).ToString(), false));
            for (int i = currentPage - 1; i <= pageCount; i++)
            {
                pages.Add(new ListItem(i.ToString(), i.ToString(), i != currentPage));
            }
        }
        else
        {
            pages.Add(new ListItem("...", (currentPage).ToString(), false));
            for (int i = currentPage - 2; i <= currentPage + 2; i++)
            {
                pages.Add(new ListItem(i.ToString(), i.ToString(), i != currentPage));
            }
            pages.Add(new ListItem("...", (currentPage).ToString(), false));
        }
        if (currentPage != pageCount)
        {
            pages.Add(new ListItem("Next", (currentPage + 1).ToString()));
        }
    }
    rptPager.DataSource = pages;
    rptPager.DataBind();
 
    lblPageIndex.Text = currentPage.ToString();
    lblTotalPage.Text = ((recordCount / PageSize) + ((recordCount % PageSize) > 0 ? 1 : 0)).ToString();
    lblTotal.Text = recordCount.ToString();
}
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    this.GetRecipient(1);
}
protected void SendBulkDocument(object sender, EventArgs e)
{
    using (SqlConnection con = new SqlConnection())
    {
        con.ConnectionString = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
        using (SqlCommand cmd = new SqlCommand("SELECT * FROM DocumentTable WHERE CreatedBy = @CreatedBy", con))
        {
            cmd.Parameters.AddWithValue("@CreatedBy", createby.Text);
            con.Open();
            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.Read())
            {
                byte[] DataByte = (byte[])dr["DataCert"];
                iTextSharp.text.Image bytes = iTextSharp.text.Image.GetInstance(DataByte);
            }
                //Create a temporary DataTable
                DataTable dtCustomers = new DataTable();
            dtCustomers.Columns.AddRange(new DataColumn[2] { new DataColumn("Recipient", typeof(string)),
                new DataColumn("RecEmail",typeof(string)) });
 
            //Copy the Checked Rows to DataTable
            foreach (GridViewRow row in GridView1.Rows)
            {
                if ((row.FindControl("CheckSelected") as CheckBox).Checked)
                {
                    dtCustomers.Rows.Add(row.Cells[2].Text, (row.FindControl("emailLink") as HyperLink).Text);
                }
            }
 
            string subject = TextSubject.Text;
            string body = "Dear {0},<br /><br />" + txtBody.Text + "<br /><br />";
 
            //Using Parallel Multi-Threading send multiple bulk email.
            Parallel.ForEach(dtCustomers.AsEnumerable(), row =>
            {
                SendEmail(row["RecEmail"].ToString(), subject, string.Format(body, row["Recipient"]));
            });
        }
    }
}
private bool SendEmail(string recipient, string subject, string body, byte Attachment)
{
    MailMessage mm = new MailMessage("sender@gmail.com", recipient);
    mm.Subject = subject;
    mm.Body = body;
    mm.Attachments.Add(new Attachment(new MemoryStream(Attachment), "Document.pdf"));
    mm.IsBodyHtml = true;
    SmtpClient smtp = new SmtpClient();
    smtp.Host = "smtp.gmail.com";
    smtp.EnableSsl = true;
    NetworkCredential NetworkCred = new NetworkCredential();
    NetworkCred.UserName = "sender@gmail.com";
    NetworkCred.Password = "<password>";
    smtp.UseDefaultCredentials = true;
    smtp.Credentials = NetworkCred;
    smtp.Port = 587;
    smtp.Send(mm);
    return true;
}