SharePoint Developer Center > SharePoint Products and Technologies Forums > SharePoint - Development and Programming > Download attachment from MOSS document lobrary programatically based on a custom field
Ask a questionAsk a question
 

AnswerDownload attachment from MOSS document lobrary programatically based on a custom field

  • Wednesday, November 04, 2009 2:16 PMRachanaD Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello,
    How can I programatically download attachment from MOSS document library using either MOSS web services or Object model?
    I want to download the file based on FileName field.User will specify the file name when uploading the file.The file names will be unique.
    There will be only one attachment per document library item.
    Can the same SP objects can be used for downloading attahments for Lists as well as document library?

Answers

  • Wednesday, November 04, 2009 2:51 PMMarkus I_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    you can do this by both ways. Webservice is more complicated:

    firsyoz take use of the Lists.asmx-Service and get all document of the user. Afterwards you calculate the documents URL, get them by a WebRequest and store them locally

    XmlDocument xmlDoc = new XmlDocument();
      
    
    XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
    XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
    XmlNode ndQueryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
    
    ndQueryOptions.InnerXml =
                       "<IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>" +
                       "<DateInUtc>TRUE</DateInUtc>" +
                       "<ViewAttributes Scope='RecursiveAll' />";
    
    ndQuery.InnerXML += = @"<Where><Eq><FieldRef Name=\"Author\" /><Value Type=\"User\">domain\username</Value></Eq></Where><OrderBy><FieldRef Name=\"Modified\" Ascending=\"False\" /></OrderBy>";           
    
    
    
    Lists wsSourceList = new Lists();
    wsSourceList.Url = "http://server/site/Lists.asmx";
    wsSourceList.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
    XmlNode ndListSourceItems = wsSourceList.GetListItems(
                            "MyDocLib", viewName, ndQuery,
                            ndViewFields, rowLimit, ndQueryOptions, null
                     );
    
    
    
     foreach (XmlNode sourceItem in ndListSourceItems.ChildNodes[1].ChildNodes)
                        {
    
                                if (!(sourceItem is XmlWhitespace))
                                {
                                    if (!sourceItem.Attributes["ows_ContentType"].Value.Equals("Folder"))
                                    {
                                        
                                        String sourceURL = sourceItem.Attributes["ows_FileRef"].Value;
                                        sourceURL = "http:server/site/" + sourceURL.Substring(sourceURL.IndexOf("#") + 1);
    
                                        String sourceName = sourceUrl.Substring(sourceUrl.LastIndexof("/")+1);
    
    				    System.Net.WebRequest requestForAttachment = System.Net.FileWebRequest.Create(sourceURL);
                			    requestForAttachment.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
                			    using (Stream httpStream= requestForAttachment.GetResponse().GetResponseStream()) {
                		            	StreamReader reader = new StreamReader(httpStream);
    
                				using (FileStream outFile = new FileStream("c:\\"+sourceName, FileAccess.Write, FileMode.Create)) {
    
                					byte[] buff = new byte[1024];
                					int len = 0;
                					while ( (len = reader.Read(buff, 0,1024) >0))
                    					outFile.Write(buff, 0,len);
    
    
    				 	}
    
                                        }
    
    		                }
                                 }
                         }
    
    
  • Wednesday, November 04, 2009 2:56 PMSteve.CurranMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Based on your needs you should probably just store the attachment/file as a document in a document librarry. The out of the box web services do not support retrieving atttachments to list items based on the name of the attachment. If you store the attachment as a document in a document library you will be able to retrieve it various ways with the url of the document using either webdav, copy web service or rpc.

    http://sharepointfieldnotes.blogspot.com/2009/09/downloading-content-from-sharepoint-let.html

    You could create your own web service that takes the name of the attachment but you will also need to pass in the item id that it is attached to. Otherwise you wlll have to loop through all the listitems and check their attachements collection.
    certdev.com
  • Wednesday, November 04, 2009 3:10 PMMarkus I_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Steve, not really out of the box but you can do it this way

    //get the IDs of the appopriate ListItem and iterate with them through this code
    
    XmlNode attachments = 
    
       listsWebServiceSource.GetAttachmentCollection("Sourcelistname", itemID);
    
    
    
    foreach (XmlNode ndAttachment in attachments.ChildNodes){
       
    
           String SourcePath = ndAttachment.InnerText;
    
           System.Net.WebRequest requestForAttachment =      System.Net.FileWebRequest.Create(sourcePath);
           requestForAttachment.Credentials =  System.Net.CredentialCache.DefaultCredentials;
    
           using (Stream httpStream= requestForAttachment.GetResponse().GetResponseStream()) <br/>       {
    
              StreamReader reader = new StreamReader(httpStream);
    
              //read attachment as stream binary and save it as file or store it somewhere else
           }
    
    
    }
    
    
  • Thursday, November 05, 2009 7:19 AMMarkus I_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    using (SPWeb oWebsiteRoot = SPContext.Current.Site.RootWeb)
    {
    
        SPList oList = oWebsiteRoot.Lists["<em>[DocumentLibraryName]</em>"];
    
        SPQuery oQuery = new SPQuery();
        oQuery.Query = "<Where><Eq><FieldRef Name='Title'/>" +
            "<Value Type='Text'><em>[uniqueName]</</em>Value></Eq></Where>";
        SPListItemCollection collListItems = oList.GetItems(oQuery);
    
        foreach (SPListItem oListItem in collListItems)
        {
          if (oListitem.File != null) {
            Stream streamFileContent = oLIstItem.File.OpenBinary();
             //do with the stream what you want
          }
        }
    }
    
    
    

All Replies

  • Wednesday, November 04, 2009 2:51 PMMarkus I_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    you can do this by both ways. Webservice is more complicated:

    firsyoz take use of the Lists.asmx-Service and get all document of the user. Afterwards you calculate the documents URL, get them by a WebRequest and store them locally

    XmlDocument xmlDoc = new XmlDocument();
      
    
    XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
    XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
    XmlNode ndQueryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
    
    ndQueryOptions.InnerXml =
                       "<IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>" +
                       "<DateInUtc>TRUE</DateInUtc>" +
                       "<ViewAttributes Scope='RecursiveAll' />";
    
    ndQuery.InnerXML += = @"<Where><Eq><FieldRef Name=\"Author\" /><Value Type=\"User\">domain\username</Value></Eq></Where><OrderBy><FieldRef Name=\"Modified\" Ascending=\"False\" /></OrderBy>";           
    
    
    
    Lists wsSourceList = new Lists();
    wsSourceList.Url = "http://server/site/Lists.asmx";
    wsSourceList.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
    XmlNode ndListSourceItems = wsSourceList.GetListItems(
                            "MyDocLib", viewName, ndQuery,
                            ndViewFields, rowLimit, ndQueryOptions, null
                     );
    
    
    
     foreach (XmlNode sourceItem in ndListSourceItems.ChildNodes[1].ChildNodes)
                        {
    
                                if (!(sourceItem is XmlWhitespace))
                                {
                                    if (!sourceItem.Attributes["ows_ContentType"].Value.Equals("Folder"))
                                    {
                                        
                                        String sourceURL = sourceItem.Attributes["ows_FileRef"].Value;
                                        sourceURL = "http:server/site/" + sourceURL.Substring(sourceURL.IndexOf("#") + 1);
    
                                        String sourceName = sourceUrl.Substring(sourceUrl.LastIndexof("/")+1);
    
    				    System.Net.WebRequest requestForAttachment = System.Net.FileWebRequest.Create(sourceURL);
                			    requestForAttachment.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
                			    using (Stream httpStream= requestForAttachment.GetResponse().GetResponseStream()) {
                		            	StreamReader reader = new StreamReader(httpStream);
    
                				using (FileStream outFile = new FileStream("c:\\"+sourceName, FileAccess.Write, FileMode.Create)) {
    
                					byte[] buff = new byte[1024];
                					int len = 0;
                					while ( (len = reader.Read(buff, 0,1024) >0))
                    					outFile.Write(buff, 0,len);
    
    
    				 	}
    
                                        }
    
    		                }
                                 }
                         }
    
    
  • Wednesday, November 04, 2009 2:56 PMSteve.CurranMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Based on your needs you should probably just store the attachment/file as a document in a document librarry. The out of the box web services do not support retrieving atttachments to list items based on the name of the attachment. If you store the attachment as a document in a document library you will be able to retrieve it various ways with the url of the document using either webdav, copy web service or rpc.

    http://sharepointfieldnotes.blogspot.com/2009/09/downloading-content-from-sharepoint-let.html

    You could create your own web service that takes the name of the attachment but you will also need to pass in the item id that it is attached to. Otherwise you wlll have to loop through all the listitems and check their attachements collection.
    certdev.com
  • Wednesday, November 04, 2009 3:10 PMMarkus I_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Steve, not really out of the box but you can do it this way

    //get the IDs of the appopriate ListItem and iterate with them through this code
    
    XmlNode attachments = 
    
       listsWebServiceSource.GetAttachmentCollection("Sourcelistname", itemID);
    
    
    
    foreach (XmlNode ndAttachment in attachments.ChildNodes){
       
    
           String SourcePath = ndAttachment.InnerText;
    
           System.Net.WebRequest requestForAttachment =      System.Net.FileWebRequest.Create(sourcePath);
           requestForAttachment.Credentials =  System.Net.CredentialCache.DefaultCredentials;
    
           using (Stream httpStream= requestForAttachment.GetResponse().GetResponseStream()) <br/>       {
    
              StreamReader reader = new StreamReader(httpStream);
    
              //read attachment as stream binary and save it as file or store it somewhere else
           }
    
    
    }
    
    
  • Wednesday, November 04, 2009 4:10 PMRachanaD Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thanks.I will explain the process at my end in details.

    1 : User will upload the file to sharepoint Document library (as per your suggestion) with a unique file name using an asp.net utility that I am creating for them.The unique file name will be generated by Oracle and File Name will be stored in the Oracle DB.
    2:When I have to retreive the FIle from MOSS, I will get the FileName field from Oracle table and based on the file name field I need to download the attachment.
     For achieving point 2, since you mentioned that I cannot do it based on the fileName field , here is what i am planning to do.
     when my utility for uploading the file to MOSS uploads the file , as the next step, it will save the file name/COmplete URL and the List Item ID to a custom SQL table.

    When I am retreiving the file, I will get the file name from Oracle and match that file name in the SQL table and get the item ID.Based on that item id I will retreive the attachment.

    Does this process look fine to you?Or do you think there is a better way?   
  • Wednesday, November 04, 2009 7:28 PMSteve.CurranMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I think that is fine. I am still confused as to why you are using a single attachment versus just putting the document in a document library.
    certdev.com
  • Wednesday, November 04, 2009 8:36 PMRachanaD Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I did not understand "why you are using a single attachment versus just putting the document in a document library."

    I am planning to upload the document to the document library.I will also upload the file Name and Document Library List ID to SQl server to match against later.
  • Wednesday, November 04, 2009 8:53 PMRachanaD Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Also,
    I want to upload files to document library and also add 5-6 metadata field to it programatically .What are the ways I can do it?
    Are there any out of Box MOSS web service / Object model that will allow me to upload document as well as metadata?
    Also, I need to get the Document library ID back as response.

    Please suggest.
  • Wednesday, November 04, 2009 10:18 PMHereICome SharePoint Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed Answer
    Hi Rachana,  For downloading file from a MOSS document library you can use SPQuery class with your unique file name to retrieve document library item.  Once you have item object you can use SPFile object to download file.  I will send you code snippets later.
  • Thursday, November 05, 2009 3:49 AMRachanaD Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello HereICome SharePoint ,
    Could you find time to send me the code snippets.I need it urgently.
  • Thursday, November 05, 2009 7:19 AMMarkus I_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    using (SPWeb oWebsiteRoot = SPContext.Current.Site.RootWeb)
    {
    
        SPList oList = oWebsiteRoot.Lists["<em>[DocumentLibraryName]</em>"];
    
        SPQuery oQuery = new SPQuery();
        oQuery.Query = "<Where><Eq><FieldRef Name='Title'/>" +
            "<Value Type='Text'><em>[uniqueName]</</em>Value></Eq></Where>";
        SPListItemCollection collListItems = oList.GetItems(oQuery);
    
        foreach (SPListItem oListItem in collListItems)
        {
          if (oListitem.File != null) {
            Stream streamFileContent = oLIstItem.File.OpenBinary();
             //do with the stream what you want
          }
        }
    }