Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Displaying Attachments with the Data View Web Part: Part 2

4.27/5 (6 votes)
24 Dec 2008CPOL3 min read 46.2K   180  
Displaying attachments with the Data View Web Part using an object model.

Introduction

This is part two of the Displaying Attachments with the Data View Web Part series. Please see Part 1 first.

SharePoint Designer’s Data View Web Part is a great control. I use it a lot when customizing list views. One thing I don’t like about it is the lack of attachment support. With Data View, you can only detect if an item has attachments or not. You can’t display them or get any information about them.

As I understand, Microsoft does not recommend any recursion while enumerating lists, and maybe this is the reason you can’t browse an item’s attachments.

I solved this issue in two ways: One using the Lists.asmx web service and is for authenticated environments, and the other with a custom Generic handler (ASHX) page.

Test Project

Here, you can find a test project with an ASHX file which you should copy to the SharePoint site later.

Let's Start

We need an ASPX page with a DataView. Please repeat steps 2 to 6 from Part 1.

We have to code a little in this example. So, open your Visual Studio. In this example, I have used VS2005. Create a new website project. Add a new item to the website. The file type should be a generic handler ASHX file. Let’s call it Attachments.ashx.

If you just want to see it work, copy this code into your ASHX file:

C#
<%@ WebHandler Language="C#" Class="Attachments" %>
using System;
using System.Web;
using Microsoft.SharePoint;
public class Attachments : IHttpHandler
{
    public void ProcessRequest (HttpContext context)
    {
        context.Response.ContentType = "text/javascript";
        SPSite sourceSite = new SPSite(@"http://localhost/"); 
        //SPControl.GetContextSite(Context);
        SPWeb sourceWeb = sourceSite.AllWebs["/"];
        Guid newListGuid = 
          new Guid(context.Request.QueryString["list"].ToString());
        SPList attList = sourceWeb.Lists[newListGuid];
        SPQuery query = new SPQuery(attList.Views[0]);
        string camlQuery = "<Where><Eq><FieldRef Name=\"ID\" />" + 
                           "<Value Type=\"Number\">";
        camlQuery += context.Request.QueryString["ID"].ToString();
        camlQuery += "</Value></Eq></Where>";
        query.Query = camlQuery;
        SPListItemCollection filteredEmployees = attList.GetItems(query);
        context.Response.Write("str='");
        foreach (SPListItem i in filteredEmployees)
        {
            for (int j = 0; j < i.Attachments.Count;j++ )
            {
                string att=i.Attachments[j].ToString();
                string ret = "";
                int found = 0;
                found = att.LastIndexOf(".");
                string ext = att.Substring(found+1);
                switch (ext){
                    case "jpg":
                    case "png":
                    case "gif":
                    case "jpeg":
                        ret = "<img src=\"" + sourceSite.Url;
                        ret += attList.ParentWebUrl;
                        ret += "/Lists/" + attList.Title+"/Attachments/" ;
                        ret += context.Request.QueryString["ID"].ToString();
                        ret+="/" + att + "\" />";
                        break;
                    default:
                        ret = "<a href=\"" + 
                              sourceSite.Url + attList.ParentWebUrl;
                        ret+="/Lists/" + attList.Title + 
                             "/Attachments/";
                        ret+= context.Request.QueryString["ID"].ToString();
                        ret+="/" + att + "\">"+ 
                             sourceSite.Url + attList.ParentWebUrl;
                        ret+= "/Lists/" + attList.Title + "/Attachments/";
                        ret += context.Request.QueryString["ID"].ToString();
                        ret += "/" + att + "</a>";
                        break;
                }
                context.Response.Write( ret + "<br />");
            }
        }
        context.Response.Write("';");
        if(sourceWeb!=null)sourceWeb.Dispose();
        //Comment this line if you use SPControl.GetContextSite
        if(sourceSite != null) sourceSite.Dispose();
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

Don’t forget to set your site URL or uncomment the SPControl.GetContextSite(Context); part. Our handler expects a GUID for the list and an ID for the item ID. We need the GUID to identify the list and the ID to identify the item we want. You can expand this and send the site name as a parameter too. Our handler expects the GUID and the ID to be send as query strings.

We are using the object model to get item’s attachments so you will need to reference Microsoft.Sharepoint.dll which is in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI most probably.

After you test your handler (for example, I just added this code to the Default.aspx page and run the website).

Test code:

JavaScript
<script type="text/javascript">var str='';</script>
<script src="Attachments.ashx?ID=1&list={9990D322-09E1-46FF-807D-A4009BCEA5CB}" 
        type="text/javascript"></script>
<script type="text/javascript">
    document.write(str);
    alert(str);
</script>

You need your values for the ID and the GUID (list). You can see the GUID for the list by going to the list settings in SharePoint. Note the address in the IE address bar (e.g., http://YourSite/_layouts/listedit.aspx?List=%7B89AE6AB1%2D117C%2D4FC1%2DB891%2DAB746592F1F5%7D). This is the GUID: %7B89AE6AB1%2D117C%2D4FC1%2DB891%2DAB746592F1F5%7D. %7B is { sign, %2D is -, and %7D is }. You can see the GUID in the SharePoint Designer too. When you add the Data View Web Part to your page, just go to the SharePoint:SPDataSource tag and look for the ListID element. After you see it work, copy your ASHX file (Attachments.ashx) to SharePoint. I copied it to the JavaScriptClient folder in my SharePoint web application. After that, just copy this code in your Data View page (the same place where you were copying code in Part I, below the <value-of disable-output-escaping="yes" select="@YourColumn" /> tag):

XML
<xsl:if test="normalize-space(@Attachments) != '0'"><div>
  <script type="text/javascript"><![CDATA[var str=&apos;&apos;;]]></script>
  <script src="/JavaScriptClient/Attachments.ashx?ID={@ID}&amp;list=YourGUID"
    type="text/javascript"></script>
  <script type="text/javascript"><![CDATA[document.write(str); ]]></script> </div>
</xsl:if>

That’s it! Now, you will see the attachments with your list items.

Att8.jpg

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)