Search This Blog

Friday, January 25, 2013

How to send the attachment(s) from a SharePoint List through email

Recently one of my client requested that they want an alert email every time an item is created or modified. Moreover if there is any attachment in that list, they want that attachment to be the part of email alert. The first part of the request is pretty simple. A simple alert can do the job but sending email is where it gets tricky.
To tackle this, I knew I had to create a workflow but the simple “SPUtility.SendEmail” doesn’t allow you to send emails with attachment so this is how I tackled it.

            List<SPFile> _fileList = null;
            SPWeb myweb = SPContext.Current.Web;
            SPSite mysite = SPContext.Current.Site;
            SPList mylist = SPContext.Current.List;
            SPListItem myitem = SPContext.Current.ListItem;
            SPAttachmentCollection myattach = myitem.Attachments;
            if (myattach.Count != 0)
            {
                myweb.AllowUnsafeUpdates = false;
 
                List<SPFile> lstSPFile = null;
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (SPSite oSite = new SPSite(myitem.ParentList.ParentWeb.Site.ID))
                    {
                        using (SPWeb oWeb = oSite.OpenWeb(myitem.ParentList.ParentWeb.ID))
                        {
                          SPFolder folder = myitem.ParentList.RootFolder.SubFolders["Attachments"].SubFolders[myitem.ID.ToString()];
                            lstSPFile = new List<SPFile>();
                            foreach (SPFile file in folder.Files)
                            {
                                lstSPFile.Add(file);
                            }
                            _fileList  = lstSPFile;

                        }
                    }
                });
               
                string smtpServer = SPAdministrationWebApplication.Local.OutboundMailServiceInstance.Server.Address;
                string smtpFrom = SPAdministrationWebApplication.Local.OutboundMailSenderAddress;
  
                MailMessage mailMessage = new MailMessage(smtpFrom, "email@email.com");
                mailMessage.Body = "body body body body body body body body body ";
                mailMessage.Subject = "subject subject subject";

                foreach(var file in _fileList){
                    WebClient webClient = new WebClient();

                    //Supply the WebClient with the network credentials of our user
                    webClient.Credentials = CredentialCache.DefaultNetworkCredentials;
                    string mypath = "http://server/" + file;
                    //Download the byte array of the file
                    byte[] data = webClient.DownloadData(mypath);

                    MemoryStream memoryStreamOfFile = new MemoryStream(data);
                    mailMessage.Attachments.Add(new System.Net.Mail.Attachment(memoryStreamOfFile, file.Name.ToString()));
                }

                //Create the SMTP client object and send the message
                SmtpClient smtpClient = new SmtpClient(smtpServer);
                smtpClient.Send(mailMessage);
            }

Well I don’t know if I have to explain the code line by line as it self-explanatory. With the help of this, no matter how many attachments are there in the List Item, it will send out the email. Please do leave a comment if you need more explanation. 

How to submit data from an InfoPath 2010 form to SharePoint 2010 List, in just 10 Steps

How to submit data from an InfoPath 2010 form to SharePoint 2010 List, in just 10 Steps

This post covers a step by step guide to add/update data from InfoPath to SharePoint.

The prerequisites for this post and the tasks covered are SharePoint 2010 and Microsoft Office

InfoPath Designer 2010 installed on your machine. 


Having a good understanding about CAML(Collaborative Application Markup Language), a 

knowledge of the methods of the SharePoint Lists web service would be really helpful.


To get more information about the SharePoint Lists web service:

Open IE navigate to "http://servername/_vti_bin/lists.asmx?WSDL

(You will be able to see all the web methods associated with the Lists web service. For our 

purpose we will be using UpdateListItemsweb method).

STEP 1. Create a Custom List in a SharePoint Site, 'Employee'. Also create some columns as 

per your need. 

Note that there will be a default column called 'Title' and lets not change it and keep it that way to 

store EmployeeName, I've create EmployeeAddress, EmployeeNo, EmployeeEmail as columns 

which are Single text. 

STEP 2. Open Microsoft Office InfoPath Designer 2010 and select a Blank Form and click 

Design Form. Then do as follows.

Form Options

Security and Trust

Full Trust

Programming

Design

Design

Design

Renaming the button


Add fields






STEP 3. In SharePoint site under Employee list, in ribbon under List Tools select List and then select List Settings. In that page click Advanced Settings and select Allow management of content types to Yes.

List Settings



STEP 4.  Again go to List Settings click Metadata navigation settings and copy the list GUID.

Copy list GUID

STEP 5. Go back to InfoPath form right click on listID and paste GUID under value field.




STEP 6. Open Notepad and type,

<?xml version="1.0" encoding="UTF-8" >?
<Batch>
<Method ID="1" Cmd="New">
     <Field Name='Title' />
     <Field Name="EmployeeAddress" />
     <Field Name="EmployeeNo" />
     <Field Name="EmployeeEmail" />
</Method>
</Batch>

Save the file as an xml file and name it Submit.xml.

STEP 7. Now lets create Data Connections. Go to InfoPath form and click Manage Data Connections. First we need to create a Receive Data connection. I am naming it as 'Submit'.


Receive Data

XML Document

Browse for the created Submit.xml file


Naming the connection as 'Submit'

STEP 8. Now we need to create a Submit Data Connection. Again in Manage Data Connections click Add.

Add

Submit Data

To a Web Service

http://servername/_vti_bin/lists.asmx?WSDL

UpdateListItems

listname

listID

Include : Text and child elements only

Updates

Secondary


Batch

Include : XML Subtree, including selected element


Web Service Submit


Edit Form Code

STEP 9. Click Edit Form Code and btnSubmit_Clicked event will be created. In that block, type the following code.

try
{
    XPathNavigator root = MainDataSource.CreateNavigator();

    // Retrieve the values for the separation list item
    string listID = root.SelectSingleNode("/my:myFields/my:listID", NamespaceManager).Value;
    string eNameDS = root.SelectSingleNode("/my:myFields/my:EmployeeName", NamespaceManager).Value;
    string eAddressDS = root.SelectSingleNode("/my:myFields/my:EmployeeAddress", NamespaceManager).Value;
    string eNoDS = root.SelectSingleNode("/my:myFields/my:EmployeeNo", NamespaceManager).Value;
    string eEmailDS = root.SelectSingleNode("/my:myFields/my:EmployeeEmail", NamespaceManager).Value;

    if (listID == null)
    {
    
    }
    else
    {
        //This is CAML xml file. it contains batch and method nodes
        XPathNavigator batch = DataSources["Submit"].CreateNavigator();

        batch.SelectSingleNode("/Batch/Method/Field[@Name='Title']", NamespaceManager).SetValue(eNameDS);
        batch.SelectSingleNode("/Batch/Method/Field[@Name='EmployeeAddress']", NamespaceManager).SetValue(eAddressDS);
        batch.SelectSingleNode("/Batch/Method/Field[@Name='EmployeeNo']", NamespaceManager).SetValue(eNoDS);
        batch.SelectSingleNode("/Batch/Method/Field[@Name='EmployeeEmail']", NamespaceManager).SetValue(eEmailDS);

        DataConnections["Web Service Submit"].Execute();
}
catch (Exception ex)
{
    ex.Message.ToString();
}


STEP 10. And finally thats all. Preview the form and try submitting the data. After that publish the form and upload the form template into SharePoint and start using.

There are few important things to remember carefully. 
  • There is a significant difference between Display name and the Field name. When we are doing the coding we are using the value under the Field name. If you can remember, I have mentioned to keep the default 'Title' column as it is, because if we rename the 'Title' column it will just change the display name. The Field name will be remain as 'Title'.
  • No of updating list fields should be the same as no xml field names.
  • When I am creating columns in SharePoint list, if you can remember I have included no spaces between words. Thats because it will add characters into Field names. So when we are referring to Field names from looking at Display names, the Field name is actually differs from the Display name.
  • List fieldname should be same as xml fieldname.
  • Make sure when creating the Submit Data connection 'Web Service Submit' to select following things,
    • listName - listID : Include : Text and Child elements only
    • updates - Batch : Include : XML subtree, including selected element