views:

4818

answers:

7

Howdy,

I am writting a winforms c# 2.0 application that needs to put an XML file into a document library on SharePoint.

I want to use a WebService instead of using the object model (no sharepoint.dll to reference here)

I am currently using the http://webserver/site/_vti_bin/copy.asmx webservice.

Here is some code:

byte[] xmlByteArray;
using (MemoryStream memoryStream = new MemoryStream())
{
    xmlDocument.Save(memoryStream);
    xmlBytes = memoryStream.ToArray();
}

string[] destinationUrlArray = new string[] {"http://webserver/site/Doclib/UploadedDocument.xml"};

FieldInformation fieldInfo = new FieldInformation();
FieldInformation[] fields = { fieldInfo };


CopyResult[] resultsArray;

using (Copy copyService = new Copy())
{
    copyService.Credentials = CredentialCache.DefaultCredentials;
    copyService.Url = "http://webserver/site/_vti_bin/copy.asmx";

    copyService.Timeout = 600000;

    uint documentId = copyService.CopyIntoItems("", destinationUrlArray, fields, xmlByteArray, out resultsArray);
}

When this code runs, I get a single result in the resultsArray out parameter:

DestinationURL: "http://webserver/site/Doclib/UploadedDocument.xml"
ErrorCode: UnKnown
ErrorMessage: "Object reference not set to an instance of an object."

From my searching, I have found a couple of possible helps.

  • Microsoft TechNet -- "The copy.asmx copyintoitems will only work if the source and destination urls are in the same SPWebApplication (Site Collection)."

  • Microsoft Social -- "Object reference not set to an instance of an object error occurs because of SharePoint not able to identified that particular property."

This leads me to believe my source url should be set to something, but what? This is originating from a client workstation and does not have a source URL.

Any help would be appricated.

hank you,
Keith

A: 

Here's some code I wrote awhile (i apologize, i've had to piece meal it together, but hopefully you get the point of it)

    // Create a request using a URL that can receive a post. 
WebRequest request = WebRequest.Create("http://sharepointsite/somefile.txt");

// Set the Method property of the request to POST.
request.Method = "PUT"

Stream dataStream;

// Set the ContentType property of the WebRequest.
request.ContentType = "multipart/form-data; charset=ISO-8859-1";

byte[] byteArray = File.ReadAllBytes(@"c:\somefile.txt");

// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;

// Get the request stream.
dataStream = request.GetRequestStream();

// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);

// Close the Stream object.
dataStream.Close();

// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
HttpStatusCode statCode = response.StatusCode;

// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();

// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
Tony Testa
A: 

I don't get it, why are you using Copy rather then UpdateListItems. Perhaps UpdateListItems will be a better match?

Kasper
Copy is used for uploading files to doc libraries while UpdateListItems for lists (example: tasks).
Robert MacLean
+1  A: 

your code is fine, just use the destination url instead of an empty string. See below:

byte[] xmlByteArray;
using (MemoryStream memoryStream = new MemoryStream())
{
    xmlDocument.Save(memoryStream);
    xmlBytes = memoryStream.ToArray();
}

string destinationUrl = “http://webserver/site/Doclib/UploadedDocument.xml”
string[] destinationUrlArray = new string[] { destinationUrl };

FieldInformation fieldInfo = new FieldInformation();
FieldInformation[] fields = { fieldInfo };


CopyResult[] resultsArray;

using (Copy copyService = new Copy())
{
    copyService.Credentials = CredentialCache.DefaultCredentials;
    copyService.Url = "http://webserver/site/_vti_bin/copy.asmx";

    copyService.Timeout = 600000;

    uint documentId = copyService.CopyIntoItems(destinationUrl , destinationUrlArray, fields, xmlByteArray, out resultsArray);
}
Nat
Am I missing something? I still see the SourceURL parameter as an empty string? I have fill that parameter with “http://webserver/site/Doclib/UploadedDocument.xml” and it still gives the same results when ran. Keith
Keith Sirmons
Sorry, I am an idiot. I missed out the parameter. Interesting that you are still having an issue because your code runs sweet on my machine.
Nat
Are you running this code on the same machine as your SharePoint instance? My coworker has this code running as well, but it is on the same machine as his SP instance. I am running the code on my machine, but my SP is running in a Virtual Machine to help replicate real world situations. Interested if this is the underlying issue.
Keith Sirmons
Running from my desktop connected through an f5 load balancer to one of three webfront end servers.
Nat
A: 

Here is what is currently working:

WebRequest request = WebRequest.Create(“http://webserver/site/Doclib/UploadedDocument.xml”);
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "PUT";
byte[] buffer = new byte[1024];
using (Stream stream = request.GetRequestStream())
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        dataFile.MMRXmlData.Save(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);
        for (int i = memoryStream.Read(buffer, 0, buffer.Length); i > 0;
            i = memoryStream.Read(buffer, 0, buffer.Length))
        {
            stream.Write(buffer, 0, i);
        }
    }
}

WebResponse response = request.GetResponse();
response.Close();

So... Does anyone have an opinion as to if this "PUT" method is better in the SharePoint environment than using a built-in webservice?

Right now I would have to say the "PUT" method is better since it works and I could not get the WebService to work.

Keith

Keith Sirmons
Here is the source I used for this answer: http://geek.hubkey.com/2007/10/upload-file-to-sharepoint-document.html
Keith Sirmons
A: 

What I know that you can't upload a file to document library using share point web service
you can do it simply using object model:

using (SPSite site = new SPSite(siteUrl))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPFolder folder = web.Folders[listName];
                folder.Files.Add(fileName, fileContent);//fileContent is byte[]
                folder.Update();
            }

        }
Khaled Musaied
Thank you.. But the client computers do not have copies of the sharepoint.dll and I do not want to distribute that along with the application. Take a look at question 2 on this site: http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/5834679b-482b-4924-b881-fa2146840d05/
Keith Sirmons
You can create you own web service with this code and deploy it on the server then consume it and pass the same parameters to it.
Khaled Musaied
A: 

I know this is an old thread but it kept coming up as I was searching for a solution to the same problem.

Check Steve Curran's answer on this thread http://social.msdn.microsoft.com/Forums/en-SG/sharepointdevelopment/thread/833e38a8-f13c-490d-8ba7-b889b6b25e38. Looks like Basically the request fails because the destination url can't be resolved.

(Limitations of a new stackflow user - can't post more than one link. See my comment for the rest)

pat

pat
(here's the rest)I set up sharepoint Alternate Access Mapping according to his article here http://blogs.msdn.com/sharepoint/archive/2007/03/06/what-every-sharepoint-administrator-needs-to-know-about-alternate-access-mappings-part-1.aspx (just the mapping part - not the proxy bit) and - Success.One other request detail, 'SourceUrl' can't be blank but it doesn't have to be a valid url. 'Fields' can be blank.One other detail - I'm using Python Suds as the client.pat
pat