Ask a questionAsk a question
 

AnswerHow to use SPFile.Add in the loop?

  • Saturday, November 07, 2009 3:50 AMvladta Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello,
    I need to be able to add files to Sharepoint Document library based on the content of the text box. The text box has IDs in the following format: 22;33;44
    So I need to add 3 files into the document library and update AssociationID column with the id from the text box.

    Here is part of my code that works:

                                       
                                        MemoryStream mstream = new MemoryStream();
                                        string strRTFFileName = string.Empty;
                                        string sourceList = "Shared Documents"; //Name of Document library to save file.

                                        SPList sourceListObj = get_web().Lists[sourceList];
                                       
                                        //Declare a streamwriter and output it's value to memory stream
                                        StreamWriter sw = new StreamWriter(mstream);
                                        sw.Write("Empty File");
                                        // Creating file name dynamically based on datetime value

                                       
                                       // strRTFFileName = "file_" + sourceListObj.ItemCount + ".rtf";

                                        // End of dynamic file name creation

                                        // On flushing StreamWriter, value is copied to memorystream.
                                        sw.Flush();
                                        byte[] contents = new byte[mstream.Length];
                                        mstream.Read(contents, 0, (int)mstream.Length);

                                        get_web().AllowUnsafeUpdates = true;


                                       
                                        strRTFFileName = "file_102.rtf";
                                            SPFile sp_file1 = get_web().Files.Add(get_web().Url + "/"
                                                + sourceListObj.RootFolder.ToString() + "/" + strRTFFileName, mstream, true);
                                            //get_web().Folders["Shared Documents"].Update();
                                            sp_file1.Item["AssignmentID"] = "102";
                                            sp_file1.Item.Update();

                                            strRTFFileName = "file_103.rtf";
                                            SPFile sp_file2 = get_web().Files.Add(get_web().Url + "/"
                                                    + sourceListObj.RootFolder.ToString() + "/" + strRTFFileName, mstream, true);
                                            //get_web().Folders["Shared Documents"].Update();
                                            sp_file2.Item["AssignmentID"] = "103";
                                            sp_file2.Item.Update();
                                        
                                      
                                            mstream.Close(); get_web().AllowUnsafeUpdates = false;
                                     
    How can I implement this in the loop:
                                        string[] separator = tbName.Text.Split(';');
                                        string str_i = "";
                                       
                                        foreach (string str_id in separator)
                                        {
                                         }

    I've tried so many different things and it only adds one file. Never gets to the second.
    Any ideas how can I accomplish this task?

    Thank you.






    vlad
    • Moved byMike Walsh MVPMVP, ModeratorSaturday, November 07, 2009 10:14 AMprogramming not customization (From:SharePoint - Design and Customization)
    •  

Answers

  • Monday, November 09, 2009 3:38 PMvladta Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    I just figured this out this morning.
    There were 2 issues.
    The content of the text box was 22;33;44;
    So, when you use .Split(';') and loop through it, there are 4 iterations. The last time has value after last ; -  so it is empty.
    Now, the second issue was that I needed to include this command:
    sourceListObj.Update();
    Apparently, if you don't use this, it is only the file on the very last iteration will be created. And because the last interaction had nothing after ; it was updating AssignmentID field to empty string only once.



     string
     sourceList = "Shared Documents"
    ; //Name of Document library to save file.
    

    using (SPWeb myWeb = get_web())
    {
    SPList sourceListObj = myWeb.Lists[sourceList];


    string str_all_ids = tbName.Text;
    str_all_ids = str_all_ids.Remove(str_all_ids.LastIndexOf(';'));
    string [] separator = str_all_ids.Split(';' );
    string str_i = "" ;

    myWeb.AllowUnsafeUpdates = true ;

    foreach (string str_id in separator)
    {
    MemoryStream mstream = new MemoryStream();
    string strRTFFileName = string .Empty;

    // Creating file name dynamically based on datetime value
    strRTFFileName = "file_" + sourceListObj.ItemCount + ".rtf" ;
    // End of dynamic file name creation

    //Declare a streamwriter and output it's value to memory stream
    StreamWriter sw = new StreamWriter(mstream);
    sw.Write("Empty File" );
    sw.Flush();

    byte [] contents = new byte [mstream.Length];
    mstream.Read(contents, 0, (int )mstream.Length);

    SPFile myFile = myWeb.Files.Add(myWeb.Url + "/"
    + sourceListObj.RootFolder.ToString()
    + "/"
    + strRTFFileName, mstream, true );

    myFile.Item["AssignmentID" ] = str_id;
    myFile.Item.Update();
    sourceListObj.Update();
    mstream.Close();

    }

    myWeb.AllowUnsafeUpdates = false ;

    }


    vlad
    • Marked As Answer byvladta Monday, November 09, 2009 3:38 PM
    •  

All Replies

  • Saturday, November 07, 2009 5:12 PMCharlie Holland Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    what does str_id represent? I'm not clear on what you're trying to achieve. Do you want to add multiple files with their names being read from tbName?

    Ch. - My Blog
  • Saturday, November 07, 2009 5:37 PMvladta Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Charlie, this is pretty much what I am trying to do. Only the name I'd generate based on .ItemCount: strRTFFileName = "file_" + sourceListObj.ItemCount + ".rtf";

    Right now I am hardcoding it.
    str_id would be a value of the text box that I will update the AssignmentID for the file that is just added:   sp_file2.Item["AssignmentID"] = str_id;
    So, if the content of the text box is 22;33;44 the the function within the loop:

                                         string[] separator = tbName.Text.Split(';');
                                       
                                        foreach (string str_id in separator)
                                        {

                                         }

    would create new file and will update the value of AssignementID column to 22, 33, 44.
    --------------------------------------
    |file name|AssignementID|
    --------------------------------------
    |file_1.rtf |22                   |
    |file_2.rtf |33                   |
    |file_3.rtf |44                   |
    vlad
  • Saturday, November 07, 2009 5:54 PMCharlie Holland Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Apart from the obvious, what does get_web do? Is there a reason for calling it multiple times rather than just using the same SPWeb referece throughout?
    Ch. - My Blog
  • Saturday, November 07, 2009 6:01 PMCharlie Holland Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Have you tried something like this:

         string sourceList = "Shared Documents"; //Name of Document library to save file.
    
                using (SPWeb myWeb = get_web())
                {
                    SPList sourceListObj = myWeb.Lists[sourceList];
    
                    //How can I implement this in the loop:
                    string[] separator = tbName.Text.Split(';');
                    string str_i = "";
    
                    myWeb.AllowUnsafeUpdates = true;
    
                    foreach (string str_id in separator)
                    {
                        MemoryStream mstream = new MemoryStream();
                        string strRTFFileName = string.Empty;
    
                        // Creating file name dynamically based on datetime value
                        strRTFFileName = "file_" + sourceListObj.ItemCount + ".rtf";
                        // End of dynamic file name creation
                        
                        //Declare a streamwriter and output it's value to memory stream
                        StreamWriter sw = new StreamWriter(mstream);
                        sw.Write("Empty File");
                        sw.Flush();
    
                        byte[] contents = new byte[mstream.Length];
                        mstream.Read(contents, 0, (int)mstream.Length);
    
                        SPFile myFile = myWeb.Files.Add(myWeb.Url + "/"
                                                        + sourceListObj.RootFolder.ToString() 
                                                        + "/" 
                                                        + strRTFFileName, mstream, true);
                        
                        myFile.Item["AssignmentID"] = str_id;
                        myFile.Item.Update();
                                            
                        mstream.Close();
    
                    }
    
                    myWeb.AllowUnsafeUpdates = false;
    
                }
    
    

    Ch. - My Blog
  • Saturday, November 07, 2009 8:32 PMvladta Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Yes, I did. But I just put your code it and I am getting the same behavior.
    About get_web()
    public SPWeb get_web()
        {
            SPWeb web = SPContext.Current.Web;
                    return web;

        }



    So, here is what I have based on your code:

    string sourceList = "Shared Documents"; //Name of Document library to save file.
                                       
                                        SPList sourceListObj = get_web().Lists[sourceList];

                                            //How can I implement this in the loop:
                                            string[] separator = tbName.Text.Split(';');
                                            string str_i = "";

                                            get_web().AllowUnsafeUpdates = true;

                                            foreach (string str_id in separator)
                                            {
                                                MemoryStream mstream = new MemoryStream();
                                                string strRTFFileName = string.Empty;

                                                // Creating file name dynamically based on datetime value
                                                strRTFFileName = "file_" + sourceListObj.ItemCount + ".rtf";
                                                // End of dynamic file name creation

                                                //Declare a streamwriter and output it's value to memory stream
                                                StreamWriter sw = new StreamWriter(mstream);
                                                sw.Write("Empty File");
                                                sw.Flush();

                                                byte[] contents = new byte[mstream.Length];
                                                mstream.Read(contents, 0, (int)mstream.Length);

                                                SPFile myFile = get_web().Files.Add(get_web().Url + "/"
                                                                                + sourceListObj.RootFolder.ToString()
                                                                                + "/"
                                                                                + strRTFFileName, mstream, true);

                                                myFile.Item["AssignmentID"] = "000";
                                                myFile.Item.Update();

                                                mstream.Close();

                                            }

                                            get_web().AllowUnsafeUpdates = false;

    It still only creates 1 file. Also, when I have myFile.Item["AssignmentID"] = str_id;
    the field never gets updated. When I have myFile.Item["AssignmentID"] = "000"; It does get updated.
    I can output the values of srt_id into the label and can see that it looks good.  Really, don't understand where is it that we are wrong.




    vlad
  • Monday, November 09, 2009 2:56 PMCharlie Holland Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     


    Can you stick a debugger on it and check the value of string[] separator?

    It's strange that the AssignmentID isn't getting updated when using str_id. I'm wondering if the iterator isn't seeing all the items that you're expecting. That would explain both problems.

    Where is this code being called from? Is it an event handler or on init or whatever? Is it in a webpart or codebehind for a custom page?


    Ch. - My Blog
  • Monday, November 09, 2009 3:38 PMvladta Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    I just figured this out this morning.
    There were 2 issues.
    The content of the text box was 22;33;44;
    So, when you use .Split(';') and loop through it, there are 4 iterations. The last time has value after last ; -  so it is empty.
    Now, the second issue was that I needed to include this command:
    sourceListObj.Update();
    Apparently, if you don't use this, it is only the file on the very last iteration will be created. And because the last interaction had nothing after ; it was updating AssignmentID field to empty string only once.



     string
     sourceList = "Shared Documents"
    ; //Name of Document library to save file.
    

    using (SPWeb myWeb = get_web())
    {
    SPList sourceListObj = myWeb.Lists[sourceList];


    string str_all_ids = tbName.Text;
    str_all_ids = str_all_ids.Remove(str_all_ids.LastIndexOf(';'));
    string [] separator = str_all_ids.Split(';' );
    string str_i = "" ;

    myWeb.AllowUnsafeUpdates = true ;

    foreach (string str_id in separator)
    {
    MemoryStream mstream = new MemoryStream();
    string strRTFFileName = string .Empty;

    // Creating file name dynamically based on datetime value
    strRTFFileName = "file_" + sourceListObj.ItemCount + ".rtf" ;
    // End of dynamic file name creation

    //Declare a streamwriter and output it's value to memory stream
    StreamWriter sw = new StreamWriter(mstream);
    sw.Write("Empty File" );
    sw.Flush();

    byte [] contents = new byte [mstream.Length];
    mstream.Read(contents, 0, (int )mstream.Length);

    SPFile myFile = myWeb.Files.Add(myWeb.Url + "/"
    + sourceListObj.RootFolder.ToString()
    + "/"
    + strRTFFileName, mstream, true );

    myFile.Item["AssignmentID" ] = str_id;
    myFile.Item.Update();
    sourceListObj.Update();
    mstream.Close();

    }

    myWeb.AllowUnsafeUpdates = false ;

    }


    vlad
    • Marked As Answer byvladta Monday, November 09, 2009 3:38 PM
    •