Send a SharePoint document library file as email

Ever wanted to send a SharePoint item by email to someone? No? Well, neither have I. turns out, someone else did, though, and they did not know how, so I thought I’d help out. And you never know, it might turn out to be you next time, and what will you do then? Now you can just remember that weird Norwegian guy who wrote that thing back in the days and come here to pick up your solution. And, to save you some time, I’ll actually upload the entire solution for you, ready to use with just one simple step to do.

Scope

Ok, so what is our scope. I want to have some way of sending an individual file from a SharePoint library to someone. The file should be sent as an attachment and I should just have to enter the recipients email and perhaps a message.

To accomplish this I want to add a choice to the drop-down menu that appears on a library item when you hover-and-click a library item:

step-1

Clicking on that item should open up a form that I can use to fill out recipient address and a message. When I click a Send button on that page I should return to the list.

Let’s get down to business.

Solution walk-through

For this project I will use WSPBuilder that I wrote about in my Basic setup of SharePoint Visual Studio project article. Make sure you have WSPBuilder with the Visual Studio extensions installed, it will save you tons of work and make SharePoint development a joy. So much for advertising.

Our ingredients:

- One visual studio 2005 or 2008.

- WSPBuilder with Visual Studio Extensions.

- SharePoint in any v3 flavor, WSS or MOSS

- .Net Reflector

- An SMTP-server, like that of your ISP or your own

Step 1: Setup

First, start by creating a new WSPBuilder project in Visual Studio. Use whatever name you like, for example SendAsEmail as I did. Add a new empty feature to the project. With WSPBuilder extensions it is simply a matter of right-clicking the project in the solution explorer and click Add->New item. The items available to you includes an empty feature. Write a nice description and make sure the feature is web scoped.

Second, add a class file. I like to add my class files to a folder in the Project called FeatureCode. The reason for this is that WSPBuilder will also use this folder to add custom code, and I like to keep my code in one place in small projects such as this. To do so, right-click the project again and click Add->New folder. Call it FeatureCode. Then, right-click that folder and click Add->Class. Browse to the Visual C# Project items to find the Class file. Call it again whatever you like. I call mine SendAsEmail.cs.

Third, add references to your project. Right-click the References in solution explorer and add references to Windows SharePoint Services (microsoft.sharepoint.dll) and System.Web.

Finally, create a new blank ASPX page to your solution. This page will be the custom form we will use to input the recipients email and the message text. To do so, first right-click on the 12\Template folder under your project in the solution explorer. Click Add->New folder and call it Layouts. No, you cannot call this anything else, it must be named Layouts. This folder largely corresponds to the _layouts virtual directory in SharePoint and we want to put our file there to make it available everywhere. Next, right-click the layouts folder and click Add->New item. Again, browse to the Visual C# Project items and find a Text file item. There is no ASPX page item to add to a non-website project, but we can still get one by naming our new text file SendAsEmail.aspx. Or something else, the important thing is to call it [something].aspx.

Now, your solution explorer should look like this, save any differences in naming you have done:

step-2

If your solution does not look like this and you do not know why, retrace your steps to find out what you missed.

Now to start the actual development.

Step 2: Create a custom action feature

Open the empty feature you created in step 1. Browse to the folder in the solution explorer and open the elements.xml file. In the elements.xml file, add the following code:

 

    1 xml version="1.0" encoding="utf-8" ?>
    2 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    3   <CustomAction Title="Send as email"
    4                 Id="SendAsEmailECB"
    5                 RegistrationType="List" 
    6                 RegistrationId="101" 
    7                 ImageUrl="/_layouts/images/MSG16.GIF" 
    8                 Location="EditControlBlock" 
    9                 Sequence="225">
   10       <UrlAction Url="~site/_layouts/SendAsEmail.aspx?ItemId={ItemId}&ListId={ListId}" />
   11   CustomAction>
   12 
   13 Elements>

 

The customaction element allows you to modify action menus all around SharePoint. There are a few lines here that are critical to accomplish what we want. Line 5, RegistrationType, states that we want this to be linked to a list, and line 6, RegistrationId, states that the list type should be from template 101 or Document Library. If you develop your own list templates you can link a custom action to only that particular list by modifying RegistrationId to match you template type. List 8, Location, states that we want to add this to the EditControlBlock. That’s the name of the hover-and-lick menu where we want our custom action to appear.

Inside the CustomActions element we have a URL Action element. That simply tells SharePoint what should happen when we click that link. If you notice the Url-attribute it holds two tokens, ItemId and ListId. these tokens will be filled in for us by SharePoint. Tokens are widely used in SharePoint so I wont go into them in detail here, these two should be self-explanatory. Perhaps I will write an article on tokens one day.

Basically, that’s it for the feature code. If you are using WSPBuilder you can actually build, deploy and activate this feature and the menu item will appear. Of course, we haven’t actually built any code yet, so it will fail miserably. Let’s move on.

Step 3: Create the asp.net page to get input from user

Open the SendAsEmail.aspx page from the Layouts folder. Now, I am extremely far from being a designer, and I believe in separating code from design in any case so I’ll just make this extremely simple design-wise. There are a few things that we will need to do, though.

First, paste the following code into the aspx-file. Make sure you are in code view and not in design view:

<%@ Assembly Name="[STRONG NAME]" %>
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master"
        Inherits=”NittiTre.SendAsEmail”  %>


Second, get the strong name of your assembly, you need to paste that into where it says [STRONG NAME]. To do so, and I am assuming you are still using WSPBuilder, hit Build (Menu->Build->Build solution). Start up .net Reflector and open your assembly dll, often located in My documents\Visual Studio 2005\Projects\Solutionname\Projectname\bin\debug. At the bottom of reflector you will now see your strong name:

step-3

Simply copy the entire strong name, all four parts. Paste this into the code where it says [STRONG NAME].

You may also need to edit the Inherits-attribute of the Page directive. I have written NittiTre.SendAsEmail since that is the namespace and name of the class I will be writing in the next step.

The page itself is fit into the application.master of the SharePoint site. This master page has a contentplaceholder called PlaceHolderMain in which we put a simple table with a few controls with IDs of lblSendTo, lblMessage, btnSend, txtSendTo and txtMessage. You can basically hand this page over to your designer, but make sure that these IDs remain the same. This is important as we will be wiring up these controls in a code-behind file, and if the IDs do not match we get a runtime exception.

Let’s move over to the code.

Step 4: Write the class to send the email

Finally it’s time to do some coding.

Start by adding a few Using statements to the top to make our code a bit more readable:

    1 using System;
    2 using System.Collections.Generic;
    3 using System.Text;
    4 using System.Web.UI;
    5 
    6 using System.Net.Mail;
    7 using Microsoft.SharePoint;
    8 using Microsoft.SharePoint.WebControls;
    9 using System.Web.UI.WebControls;

Second, make sure your class inherits from LayoutsPageBase and add some controls that will have names matching the IDs of the controls we added on the aspx page. We will also add a few variables to hold our mail server configuration:

   10 
   11 namespace NittiTre
   12 {
   13     public class SendAsEmail : LayoutsPageBase
   14     {
   15 
   16         protected Label lblSendTo;
   17         protected Label lblMessage;
   18         protected Button btnSend;
   19 
   20         protected TextBox txtSendTo;
   21         protected TextBox txtMessage;
   22 
   23         private string mailServer = ""; // YOU NEED TO ADD SOMETHING HERE!
   24         private int mailPort = 25;
   25 

Ensure that you add the host name of your SMTP server in line 23.

See line 11 and 13? The namespace and the name of the class makes up what we should put in the aspx file Page inherits directive.

Since we want to have a button with an event handler we need to make sure that all our controls are created before the event handler wireup completes. A good place to do this is in the OnLoad method, so lets override that:

   26         protected override void OnLoad(EventArgs e)
   27         {
   28             EnsureChildControls();
   29         }
   30 

 

The EnsureChildControls makes sure that CreateChildControls() are called once and only once. If you happen to call EnsureChildControls again later in the code it will not create new child controls thus saving us the trouble of finding out if the controls have been added or not.

If you have ever experience adding event handlers to your controls and having them not fire it is often because you hooked up the event handler too late in the page life cycle. Often, an event handler not firing is because of just that. Simple fix, just call EnsureChildControls in your onload overridden method.

Of course, for CreateChildControls to actually, well, create child controls we need to override that method and make sure we hook up our event handler. I’ve also added a default text to the message box:

   31         protected override void CreateChildControls()
   32         {
   33             btnSend.Click += new EventHandler(btnSend_Click);
   34 
   35             txtMessage.Text = "Hello, this file is sent from SharePoint";
   36         }
   37 

Now for the bulk of our code, the btnSend_Click method that will fire when someone clicks that button. Notice line 33? That is where we hook it up. Now for the code. I’ve written inline comments to describe what is going on rather than commenting afterwards.

   38         void btnSend_Click(object sender, EventArgs e)
   39         {
   40             EnsureChildControls(); // Has been called already, but let's make sure...
   41 
   42             // Find the list and item ids from the querystring
   43             try
   44             {
   45                 Guid listId = new Guid(Server.UrlDecode(Request.QueryString["ListId"]));
   46                 int itemId = int.Parse(Request.QueryString["ItemId"]);
   47 
   48                 // Find our item from the current web
   49                 SPWeb web = this.Web;
   50                 SPListItem item = web.Lists[listId].GetItemById(itemId);
   51 
   52                 // Start building our mail message    
   53                 string senderMail = web.CurrentUser.Email;
   54                 string recipientMail = txtSendTo.Text;
   55                 MailMessage message = new MailMessage(senderMail, recipientMail);
   56                 message.Body = txtMessage.Text;
   57                 message.Subject = item.DisplayName;
   58 
   59                 // Add the file as an attachment
   60                 SPFile file = item.File;
   61                 Attachment attachment = new Attachment(file.OpenBinaryStream(), file.Name);
   62                 message.Attachments.Add(attachment);
   63 
   64                 // ...and finally try sending
   65                 SmtpClient smtp = new SmtpClient(mailServer, mailPort);
   66                 smtp.Send(message);
   67                 Response.Clear();
   68                 Response.Redirect(web.Lists[listId].DefaultViewUrl);
   69             }
   70             catch 
   71             {
   72                 throw;
   73             }
   74         }
   7
5     }
   76 }


Most of this code consists of finding information about the item selected and then start building the mail message from that information along with the input from the form.

Note that I have not added much error handling. This is bad and you should add better error handling code, especially around the SmtpClient.Send method call. A lot of things can go wrong when attempting to send an email to another server. Make sure you at least throw any exceptions up to the user so that they get an error message.

If everything goes according to plan, we send the user back to the list in line 68.

That is it. Nothing more. Let’s build, deploy and activate. I’ve uploaded a zipped solution containing everything as written here. You can download that from here. Do remember to edit your SMTP Server, that should be the only thing you need to do.

Step 4: Deploy

If you have been wise and paid attention you are using WSPBuilder. If so, right click you project in the Solution Explorer, click WSPBuilder->Build WSP. Next, do the same again, and not that now that you’ve built the WSP, more options become available in the menu. Click Deploy. Hang around for a while and your solution will be deployed.

Next, you need to activate your feature. Open your SharePoint site and go to Site Settings. Under web features you will find your SendAsEmail feature. Click activate and your document libraries now gets the new feature of sending a document library item as an attachment.

Finally!

Congratulations, you have created a hopefully useful feature. Go ahead, play around with it. Suggestions for improvements may be:

- Implement sending all documents in a folder at once (hint: folders are simply content types and you can limit the edit control box to only apply to certain content types)

- Look up recipients names in an existing contact list to avoid misspelling names

- Send to multiple recipients

- Add more mail related parameters such as Cc, Bcc, encryption, etc.

- Save user preferences for these parameters

Good luck, and let me know how it turns out.

Found this article valuable? Want to show your appreciation? Here are some options:

a) Click on the banners anywhere on the site to visit my blog's sponsors. They are all hand-picked and are selected based on providing great products and services to the SharePoint community.

b) Donate Bitcoins! I love Bitcoins, and you can donate if you'd like by clicking the button below.
Donate Bitcoins

c) Spread the word! Below, you should find links to sharing this article on your favorite social media sites. I'm an attention junkie, so sharing is caring in my book!

Pin It

Post Author

This post was written by who has written 415 posts on Furuknap's SharePoint Corner.

I do SharePoint. When I'm not doing SharePoint, I sleep, and then I dream about SharePoint. Oh, and I dabble a bit in cryptocurrencies (Bitcoin, Litecoin, etc)

19 Responses to “Send a SharePoint document library file as email”

  1. Rohit July 25, 2008 at 7:09 am #

    Thanks ,
    This is really usefull.
    Thanks again for sharing.

  2. Adrian Hughes August 14, 2008 at 1:39 pm #

    Thanks, good article. I have copied over the microsoft.sharepoint.dll from our sharepoint server to my local development machine.

    To deploy the solution I think I have to have sharepoint actually installed on my machine to make use of the sharepoint.dll.

    Is there a way around this?

  3. Bjørn Furuknap August 14, 2008 at 1:51 pm #

    I’m not really sure what you want to accomplish. to deploy you must have SharePoint, yes, but not on your development machine. You can deploy your solution to your server, developed on your workstation, by just putting the .wsp file on your server an running stsadm -o addsolution -name yourfilename.wsp.

    I never liked the idea of developing on anything but a server. For that purpose alone I keep a set of SharePoint VM images with Visual Studio installed. That way I can do local debugging, rapidly test deployment ready code, use tools that rely on the object model, such as SharePoint Manager 2007, etc.

    With VM software being free, including trial version of all required server software, I do not see the point of trying to hack together a recipe for developing on a workstation. I need at least five different setups and the only way to accomplish that is to use VMs.

    Now, Bamboo Solutions has posted a fix to get SharePoint installed on a workstation (http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2008/05/21/how-to-install-windows-sharepoint-services-3-0-sp1-on-vista-x64-x86.aspx) but I really, really do recommend you set up a virtual environment and develop on that.

    .b

  4. Anonymous September 4, 2008 at 1:19 pm #

    Hi, this is great… Nearly exactly what I have been looking for!

    I was wondering, would it be possible to do a similar thing but instead of being a form to send the email it could just use the users default email program i.e. Outlook?

    Basically clicking on the ‘Send as Email’ menu link would open a new email with the file attached.

    Thanks

    James

  5. Bjørn Furuknap September 4, 2008 at 3:45 pm #

    Hello, James.

    I am glad you liked the article.

    Your problem is a complex one since basically every email client would behave differently.

    What could be done is to create an Outlook 2007 only solution to accomplish something similar at least, but that would be for another show.

    .b

  6. Anonymous September 5, 2008 at 5:16 pm #

    Thanks for the reply… So there would be a problem even between the different versions of Outlook?

    Is this a challenge you may look at in the future? :-) !!!

    Thanks again for your help…

    James

  7. Bjørn Furuknap September 5, 2008 at 6:10 pm #

    Yes, perhaps I could. It wont be very soon as I am in the process of writing the article series on User Interface Customization and later will have to work on a few other things, to be announced.

    I will definitely keep this in mind. I have been pondering writing an article series on Office integration. Keep your eyes out and your feedreader current :-)

    .b

  8. Boris Gomiunik February 9, 2009 at 2:36 pm #

    Thank you! You don’t get to see so clear step-by-step articles and everything actually working for a beginner.

  9. Anonymous June 4, 2009 at 10:46 am #

    Hi,

    this is great… Nearly exactly what I have been looking for!

    Thanks a lot for ur post…

    Shiv

  10. Disha August 31, 2009 at 3:45 pm #

    Hello

    How can I use this for infopath library?

    Disha

  11. Anonymous December 3, 2009 at 12:22 pm #

    May be it's better to change elements.xml
    RegistrationType="ContentType"
    RegistrationId="0×0101"

    By doing this "send as mail" option will appear only for item with type Documents and not for folders.

  12. Sandesh July 1, 2010 at 7:42 am #

    Nice post, It would be better if you consider sharepoint smtp settings insted of manually configuring using coding. Great post , Keep on posting. Sandesh

  13. AJ January 7, 2011 at 5:26 pm #

    I’m guessing if you don’t have Visual Studio then you’ve got no chance of compiling and using this awesome feature?

  14. memento May 9, 2011 at 10:23 am #

    very great project, but maybe someone explained to me, how to do in order to send multiple files selection?

  15. Raquel Moreno July 13, 2011 at 4:37 pm #

    If I don’t have the development tools and no SharePoint developer, is there another way to accomplish this?

  16. Gudm Egilsson January 17, 2012 at 5:27 pm #

    Hi,
    This little application looks great… Exactly what I have been searching for now and then. Is it ok to deploy this plugin to Sharepoint 2010 server?

    • Bjørn Furuknap
      Twitter: furuknap
      January 17, 2012 at 7:03 pm #

      Should be OK to deploy in SP2010, but I haven’t tested :-) Feel free to tell me how it works (or not).

  17. Gudm Egilsson January 20, 2012 at 11:46 am #

    Hi again …
    I managed at last to have the SendAsEmail solution up and running on SP2010.
    I had to rename the “12″-Folder to 14
    Replace the Microsoft.SharePoint Reference file with the newer version, 14.0.0
    and finally Upgrade the WSP-Builder to version 1.4 (beta)
    Then … at the Server site I did use the PowerShell function “Add Solution”
    and that’s it … :)

    Thank you for the music … :) This is very useful to me.
    Regards
    Gudm.

  18. Dyuti July 24, 2012 at 5:33 am #

    exception throwing at this line–

    Guid listId = new Guid(Server.UrlDecode(Request.QueryString["ListId"]));

    ListId showing “Null” value…

    plz help..

Leave a Reply