+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Send items from Images and Documents module as e-mail attachments

by Radoslav Georgiev
In this blog post we will sample a custom control which allows users to select files uploaded to images and documents module and send them as e-mail attachments. We will create a custom control and make it look similar to the built in Download List control. However this control will allow users to select content items and send them to provided e-mail. Bellow is a sample of how our control will look like.



Let us first start by creating the control template for our custom control. We will populate the items in a RadGrid for ASP.NET AJAX as this control allows us to handle multiple selected items out of the box. We will make the control display items in a fashion similar to the built in Download List control. We will also need to add a text box for inputting user e-mail, a couple of validators for validating correct e-mails and a button, which when clicked will send items to specified e-mail address. The sample control template can be found bellow:

<%@ Control Language="C#" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<telerik:RadGrid ID="ItemsGrid"  runat="server" AllowAutomaticInserts="False" AllowAutomaticUpdates="False" AllowAutomaticDeletes="False" ShowStatusBar="True"
    AllowPaging="True" PageSize="50" EnableViewState="True" Skin="Sitefinity"
    AllowMultiRowSelection="True" GridLines="None" AutoGenerateColumns="False">
        <MasterTableView AllowMultiColumnSorting="false" CommandItemDisplay="None" CssClass="listItems listItemsBindOnClient" Width="98%">
            <Columns>
                <telerik:GridClientSelectColumn UniqueName="CheckboxSelectColumn" Text="Select"></telerik:GridClientSelectColumn>
                <telerik:GridBoundColumn UniqueName="ID" DataField="ID" Visible="false"></telerik:GridBoundColumn>
                <telerik:GridTemplateColumn UniqueName="Name" HeaderText="Name">
                    <ItemTemplate>
                        <asp:HyperLink ID="DownloadLink" runat="server">
                            <asp:Literal ID="Name" runat="server"></asp:Literal>
                        </asp:HyperLink>
                    </ItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn UniqueName="Extension" HeaderText="Extension">
                    <ItemTemplate>
                        <asp:Literal id="Extension" runat="server"></asp:Literal>
                    </ItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn UniqueName="Author" HeaderText="Author">
                    <ItemTemplate>
                        <asp:Literal id="Author" runat="server"></asp:Literal>
                    </ItemTemplate>
                </telerik:GridTemplateColumn>   
                <telerik:GridTemplateColumn UniqueName="UploadDate" HeaderText="Upload Date">
                    <ItemTemplate>
                        <asp:Literal id="UploadDate" runat="server" ></asp:Literal>
                    </ItemTemplate>
                </telerik:GridTemplateColumn>   
                <telerik:GridTemplateColumn UniqueName="Size" HeaderText="Size">
                    <ItemTemplate>
                        <asp:Literal id="Size" runat="server"></asp:Literal>
                    </ItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn UniqueName="FileDownloadLink" HeaderText="Download Link">
                <ItemTemplate>
                    <asp:HyperLink ID="FileDownloadLink" runat="server" Text="Download Item"></asp:HyperLink>
                </ItemTemplate>
                </telerik:GridTemplateColumn>
            </Columns>
        </MasterTableView>
        <ClientSettings>
            <Selecting AllowRowSelect="true" />
        </ClientSettings>
        <PagerStyle Mode="NumericPages" />
 </telerik:RadGrid>
<asp:Label ID="emailTxtLbl" runat="server" AssociatedControlID="emailTxt"></asp:Label>
<telerik:RadTextBox ID="emailTxt" runat="server" Skin="Sitefinity" ValidationGroup="sendemail"></telerik:RadTextBox>
<%--Regular expression validatior to ensure valid e-mail addresses are provided--%>
<asp:RegularExpressionValidator ID="emailValidator" runat="server" Display="Dynamic"
ErrorMessage="Please, enter valid e-mail address." ValidationExpression="^[\w\.\-]+@[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*(\.[a-zA-Z]{2,3}){1,2}$"
ControlToValidate="emailTxt" ValidationGroup="sendemail">
 </asp:RegularExpressionValidator>
<%-- a validator to ensure e-mails are entered before the send button is clicked--%>
<asp:RequiredFieldValidator ID="Requiredfieldvalidator1" runat="server" Display="Dynamic"
ControlToValidate="emailTxt" ErrorMessage="Please, enter an e-mail!" ValidationGroup="sendemail"/>
<asp:LinkButton ID="SendBtn" runat="server" Text="Send Selected" CausesValidation="true" ValidationGroup="sendemail" />

After we have created the control template for our control it is time to start building it. The control will inherit from Simple control. It will also implement the IFilterableContentControl to allow us to use filter expressions and filter content which will populate the grid. First lets get a reference of the controls in the template:

protected override void CreateChildControls()
{
    if (Page == null || DesignMode)
    {
        Label noDesignModeLabel = new Label();
        noDesignModeLabel.Text = "The Download List control cannot be rendered in Design Mode";
        this.Controls.Add(noDesignModeLabel);
    }
    else
    {
        base.CreateChildControls();
        libraryManager = new LibraryManager(ProviderName);
        //subscribe to comand event of the send button
        SendButton.Command += new CommandEventHandler(SendButton_Command);
        //subscibe to the ItemDataound event handler of the RadGrid
        ItemsGrid.ItemDataBound += new GridItemEventHandler(ItemsGrid_ItemDataBound);
        //check for filter expression
        if (FilterExpression != string.Empty)
        {
            //if we have specified a filter expression we will get only content which matches our filter expression
            ContentFilterBuilder filterBuilder = new ContentFilterBuilder(this);
            if (filterBuilder.IsFilterValid)
            {
 
                ItemsGrid.DataSource = libraryManager.GetContent(0, 0, filterBuilder.ParseMetaFieldsFilter(), filterBuilder.ParseParentsFilter());
            }
        }
        else
        {
            //if there is no filter expression we will only get content from non image libraries
            ItemsGrid.DataSource = libraryManager.GetContent(0,0,"Name ASC",this.GetParentIds());
        }
        ItemsGrid.DataBind();
    }
}
//gets IDs of libraries which are not Image type libraries
protected Guid[] GetParentIds()
{
    List<Guid> parentIDs = new List<Guid>();
    foreach (ILibrary library in libraryManager.GetAllLibraries("Image", false))
    {
        parentIDs.Add(library.ID);
    }
    return parentIDs.ToArray();
}


As you can see from the inline comments above we need to subscribe to the ItemDataBound event of the grid control. In this event we will populate the meta data and download links for each item in the grid. Bellow is the code for this event handler:

void ItemsGrid_ItemDataBound(object sender, GridItemEventArgs e)
{
    if (e.Item is GridDataItem)
    {
        IContent cnt = (IContent)e.Item.DataItem;
        foreach (var MetaKey in libraryManager.MetaKeys)
        {
            ITextControl textControl = (ITextControl)e.Item.FindControl(MetaKey.Key);
            if (textControl != null)
            {
                textControl.Text = cnt.GetMetaData(MetaKey.Key).ToString();
                if (MetaKey.Key == "Size")
                {
                    long num;
                    long.TryParse(textControl.Text, out num);
                    textControl.Text = LibraryHelper.FormatSizeString(num);
                }  
            }
        }
        Literal UploadDate = (Literal)e.Item.FindControl("UploadDate");
        HyperLink DownloadLink = (HyperLink)e.Item.FindControl("DownloadLink");
        HyperLink FileDownloadLink = (HyperLink)e.Item.FindControl("FileDownloadLink");
        if (UploadDate != null)
        {
            UploadDate.Text = cnt.DateCreated.ToShortDateString();
        }
        if (DownloadLink != null)
        {
            DownloadLink.NavigateUrl = cnt.UrlWithExtension;
        }
        if (FileDownloadLink != null)
        {
            FileDownloadLink.NavigateUrl = cnt.UrlWithExtension;
        }
    }
}

We also need to handle the click event of the send button. When this button is clicked we will get all selected items from the grid and add them as attachments to an e-mail message. You will need to have valid SMTP setting in order to make this work:

void SendButton_Command(object sender, CommandEventArgs e)
{
    GridItemCollection selectedItems = ItemsGrid.SelectedItems;
    MailMessage newMesssage = new MailMessage();
    //modify this to fit your requirements
    newMesssage.From = new MailAddress("admin@mymail.com");
 
    newMesssage.To.Add(new MailAddress(EmailText.Text));
    string message = String.Format("Message body");
    foreach (GridDataItem item in ItemsGrid.SelectedItems)
    {
        libraryManager = new LibraryManager();
        TableCell id = item["ID"];
        IContent contentItem = libraryManager.GetContent(new Guid(id.Text));
        string name = contentItem.GetMetaData("Name").ToString();
        MemoryStream stream = new MemoryStream((byte[])contentItem.Content);
        Attachment attachment = new Attachment(stream, String.Concat(name, contentItem.GetMetaData("Extension").ToString()), contentItem.MimeType);
        newMesssage.Attachments.Add(attachment);
    }
    SmtpClient smtpClient = new SmtpClient();
    smtpClient.Send(newMesssage);
}

This is the basic functionality of the control, which needs to be implemented. The complete code for the control and markup for its template can be downloaded from this link: MyDownloadListSource

2 comments

Leave a comment
  1. KingKong Mar 07, 2010
    I started by second Sitefinity project and this is one of the controls that I'm going to use for sure
  2. Abilio Duarte May 03, 2010
    Can I integrate this in the Newsletter Module in Sitefinity 3.6 SP2.
    What I mean is that when I create a Newsletter and send it to my Newsletter Subscribers I´m only sendig a link, and my Client says that whant the Attached Document selected in Library. Is that possible?

    Leave a comment