Sending aspx page with gridviews as email

2020-05-07 19:32发布

问题:

I was handed a new requirement and this one is new to me. After a day or two of research, I'm still unable to figure this one out. The requirement is to find a way to send our "Report" page as an email. This report page has multiple gridviews and multiple SqlDataSources connected to it. This page is very heavy on the asp controls. This page does belong to a website that uses Forms authentication. I was able to make this page view-able to unauthenticated users. I recommended just sending the link to the page and everyone, even if they don't have a login, are able to see the page. This idea seemed to be over looked as they are now printing this page, scanning it in as a pdf, then emailing it. It seems like it is defeating the purpose. I have placed a "Send as Email" button inside the aspx page and one click I'm trying to send this page as the body of the email. This is what I have tried so far..

protected void btnEmail_Click(object sender, EventArgs e)
        {
            using (System.IO.StreamReader reader = System.IO.File.OpenText(Server.MapPath("~/Reporting/Report.aspx")))
            {
                string fromAddress = "fromaddress@something.com";
                string toAddress = "toaddress@something.com;
                System.Net.Mail.MailMessage sendMail = new System.Net.Mail.MailMessage(fromAddress, toAddress);
                sendMail.Subject = "Testing";
                sendMail.IsBodyHtml = true;
                sendMail.Body = reader.ReadToEnd();

                SmtpClient smtp = new SmtpClient("mail.something.com");
                smtp.Send(sendMail);

            }
        }

This sends the email, but unfortunately, it only sends a single word which is "Back" and that is the link button that is in my aspx page. Here is a single gridview example of what I'm trying to send in the body of the email aslong with the buttons that are included....

    <script lang="javascript" type="text/javascript">
        function printPage() {
            document.getElementById('<%= btnPrint.ClientID %>').style.display = 'none';
            document.getElementById('<%= lbBack.ClientID %>').style.display = 'none';
            document.getElementById('<%= btnEmail.ClientID%>').style.display = 'none';
            window.print();
            document.getElementById('<%= btnPrint.ClientID %>').style.display = 'none';
            document.getElementById('<%= lbBack.ClientID %>').style.display = 'none';
            document.getElementById('<%= btnEmail.ClientID%>').style.display = 'none';
        }
    </script>
    <div class="content-wrapper">
        <asp:LinkButton ID="lbBack" runat="server" OnClientClick="JavaScript:window.history.back(1);return false;">Back</asp:LinkButton>
        <asp:Button ID="btnPrint" runat="server" Text="Print" Font-Size="X-Small" Height="27px" Width="44px" OnClientClick="printPage()" />
        <asp:Button ID="btnEmail" runat="server" Font-Size="X-Small" Height="27px" OnClick="btnEmail_Click" Text="Send as Email" Width="105px" />
    </div>
    <div class="content-wrapper">
        <asp:Label ID="lblAlexandria" runat="server" Text="Alexandria" Font-Bold="True" Font-Size="Large"></asp:Label>
    </div>
    <div class="total-header" style="text-align: right">
        <asp:Label ID="lblTotalAlexandria" runat="server" Text="Total" BackColor="Black" ForeColor="White" Font-Bold="true"></asp:Label>
    </div>
    <asp:GridView ID="gvAlexandria" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataSourceID="AlexandriaDataSource" GridLines="None" PageSize="200" HorizontalAlign="Center" ShowFooter="True" OnRowDataBound="gvAlexandria_RowDataBound">
        <Columns>
            <asp:BoundField DataField="Dealership" HeaderText="Dealership" SortExpression="DEALER NAME" Visible="False">
                <HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="150px" BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Left" />
            </asp:BoundField>
            <asp:BoundField DataField="DealDate" DataFormatString="{0:MM/dd/yyyy}" HeaderText="DealDate" SortExpression="DealDate">
                <HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="150px" BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Left" />
            </asp:BoundField>
            <asp:BoundField DataField="Location" HeaderText="Status" SortExpression="Location" Visible="False">
                <HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="150px" BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Left" />
            </asp:BoundField>
            <asp:BoundField HeaderText="Bounced" SortExpression="Bounced" DataField="Bounced">
                <FooterStyle />
                <HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="150px" BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Left" ForeColor="#CC0000" />
            </asp:BoundField>
            <asp:BoundField DataField="StockNumber" HeaderText="StockNumber" SortExpression="STOCK NO">
                <HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="150px" BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Left" />
            </asp:BoundField>
            <asp:BoundField DataField="Buyer" HeaderText="Buyer" SortExpression="LAST NAME">
                <HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="150px" BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Left" />
            </asp:BoundField>
            <asp:BoundField HeaderText="Reason" SortExpression="Reason" DataField="Reason">
                <HeaderStyle Width="150px" BackColor="Black" ForeColor="White" HorizontalAlign="Left" />
                <ItemStyle HorizontalAlign="Left" />
            </asp:BoundField>
            <asp:TemplateField HeaderText="AmtFinanced" SortExpression="AmtFinanced">
                <ItemTemplate>
                    <asp:Label ID="lblAmtFinanced" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "AmtFinanced","{0:C}") %>'></asp:Label>
                </ItemTemplate>
                <FooterTemplate>
                    <%--<asp:Label ID="lblTotal" runat="server" Text="Total" BackColor="Black" ForeColor="White" Font-Bold="true"></asp:Label>--%>
                </FooterTemplate>
                <HeaderStyle BackColor="Black" ForeColor="White" />
                <ItemStyle HorizontalAlign="Right" />
            </asp:TemplateField>
            <asp:TemplateField HeaderText="D.O">
                <ItemTemplate>
                    <asp:Label ID="lblDaysOut" runat="server" Text='<%# Eval("DaysOut") %>'></asp:Label>
                </ItemTemplate>
                <HeaderStyle BackColor="Black" ForeColor="White" HorizontalAlign="Center" VerticalAlign="Middle" Width="60px" />
                <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" />
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

I'm not too sure what I'm missing, or if it is even possible to send this page as the body of the email. If more information is needed, let me know! Thanks!

EDIT: After using Sain Pradeep suggestion, I was receiving an error. The error was..

"Control 'FeaturedContent_gvAlexandria' of type 'GridView' must be placed inside a form tag with runat=server."

To fix this, I inserted..

public override void VerifyRenderingInServerForm(Control control)
        {
            /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
               server control at run time. */
        } 

Which overrides the exception and sends the email correctly. I also removed the "Using" from the button click and replaced sendMail.Body = reader.ReadToEnd() with sendMail.Body += GetGridviewData(gvAlexandria) and added one for each gridview. All gridviews now send in the email. Thanks again for all the help!

回答1:

Please do like this

Msg.Body += GetGridviewData(gvUserInfo);

function to convert gridview data

 // 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();
}


回答2:

You will not be able to send any 'asp' code in an email and have it displayed correctly at the other end, you need a webserver in order to translate the asp code to the readable format on the screen.

Your idea about having a separate, unsecured page is spot on.

Another idea would be to 'print' the html to an image and send this.

Another option would be to generate a page that outputs html that is compatible with email clients and email this as the body.



回答3:

Why not use a tool such as wkhtmltopdf c# wrapper or EvoPDF to convert the page to PDF and email as an attachment?

Please note: The wkhtmltopdf c# library is free whereas the EvoPDF is unfortunately a commercial product.