Print This Article Post Comment Add To Favorites Email to Friends Ezine Ready

Send A Sharepoint Document Library File As Email

By: Bjrn Furuknap-31850 Home | Computers-and-Technology


This article was orignially posted to http://furuknap.blogspot.com/2008/07/send-sharepoint-document-library-file.html

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.

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 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:

<>
<>

<asp:Content ID="main" runat="server" ContentPlaceHolderID="PlaceHolderMain">

<table>
<tr><td><asp:label runat="server" ID="lblSendTo" Text="Send to:"/></td><td><asp:TextBox runat="server" ID="txtSendTo" /></td></tr>
<tr><td><asp:label runat="server" ID="lblMessage" Text="Message:"/></td><td><asp:TextBox runat="server" ID="txtMessage" TextMode="MultiLine" Rows="5" /></td></tr>
<tr><td><asp:button runat="server" ID="btnSend" Text="Send message" /></td></tr>
</table>

</asp:Content>

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.

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 }
75 }
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 http://furuknap.googlepages.com/SendAsEmail.zip. 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 note 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.



Article Source: http://www.eArticlesOnline.com

About the Author:
Bjrn Furuknap of Norway holds more than 10 MCP titles, including every SharePoint certification from Microsoft. He has worked on SharePoint projects for all the largest companies in Norway as well as having been hired by Microsoft to develop SharePoint solutions. He also writes regularly for SharePoint Magazine and in his SharePoint blog at http://furuknap.blogspot.com/.

Tags: , , , , ,

Please Rate this Article

 

Not yet Rated

Click the XML Icon Above to Receive Computers-and-Technology Articles Via RSS!

Recent Related Articles From Computers-and-Technology

  • Double Text - Starting The Program From Within Visual Studio
    By: George Gilbert | Aug 15th 2007
    Make Double Text readily available whenever you are working on any language in Visual Studio. Read

  • Overview Of Visual Studio
    By: Wade Harvey | Aug 23rd 2007
    This article focuses on Visual Studio 2005. It describes the major components and the various editions. Read

  • Rad For Visual Studio - Codeless Programming!
    By: kkchoon | May 28th 2008
    Conventional programmer will code their way to the end of the project, but new Visual Studio 2005 and 2008 allows developer to "drag and draw" their application from start till the end! They call it Rapid Application Development. Programmer from Borland Delphi in the old days already familiar with RAD programming, but until ... Read

  • Developer Guide For Pocket Pc Application Using Oracle Lite
    By: Ghanshyam Shah | Jul 12th 2008
    Nowadays, people often need working away from their desks and still require access to corporate data, normally found only on their desktop device connected to enterprise networks.

    Wireless connectivity offers the promise of remote access of enterprise data for mobile users but persistent wireless connections ...
    Read

  • Datagridview Versus Datagrid
    By: Russ Sabitov | Apr 24th 2007
    DataGridView control is a quite new .NET control introduced in .NET 2.0 is a good alternative to the VS .NET 1.x DataGrid control. Obviously we do not need to disregard the .NET DataGrid control. Read

  • Firebird Odbc Versus Driver Ole Db. Introduction To Data Access Ways.
    By: Andrew Merkulov | Mar 29th 2008
    Many people do not understand the differences between Firebird ODBC and OLE DB technologies. In this article we'll compare them and review Interbase components. Read

  • Microsoft 70-536 Exam (.net Framework): Scope And Proven Resources For Getting Certified
    By: Jessica Sol | Mar 2nd 2011
    Master the Microsoft 70-536 exam (aka TS: Microsoft .NET Framework - Application Development Foundation) skills and a great developer career awaits you in international IT market. Success becomes lot more easier and interesting when you can find the suitable resources to learn and analyzeâ€

    Read

  • Getting Audio Video Recording For An Event
    By: Brett John | Dec 27th 2010
    Audio recording coupled with video recording is a money-spinning technique that helps to get two things done at the price of one. It is beneficial for all and sundry in the trade and involves gathering of information obtainable at a particular event. Accordingly, audio video recording for conferences as well as events have ... Read

  • Make Your Event Successful By Hiring An Event Management Company
    By: Brett John | Oct 21st 2010
    Businesses keep on launching new products and thus need new ways to promote and market them across their audience. Corporate events and road shows are a great way of attracting the attention of the public. Road shows are entertaining; people like to take part in road shows because they are fun. Also you get to launch your n ... Read

  • How To Solve When Exchange Server Fails To Save Appointments?
    By: Axel Culver | Jan 13th 2010
    Microsoft Exchange Server Calendaring agent is the tool that allows performing several scheduling tasks, which include creating and saving appointments etc. Read


Copyright © 2005-2011 eArticlesOnline, LLC - All Rights Reserved
Terms of Service | Privacy Policy