7

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

Keith Sirmons
  • 8,271
  • 15
  • 52
  • 75

10 Answers10

6

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
  • 61
  • 1
  • 2
  • 3
    (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 Apr 22 '10 at 15:35
1

SharePoint responds to a plain old HTTP PUT

Igal Serban
  • 10,558
  • 3
  • 35
  • 40
1

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
  • 14,175
  • 5
  • 41
  • 64
  • 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 Apr 27 '09 at 15:03
  • 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 Apr 27 '09 at 21:16
  • 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 Apr 27 '09 at 21:48
  • Running from my desktop connected through an f5 load balancer to one of three webfront end servers. – Nat Apr 28 '09 at 00:52
1

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
  • 8,271
  • 15
  • 52
  • 75
1

I get the same message when I use the default credentials. Try replacing them with this:

copyWebService.Credentials 
    = new NetworkCredential("Administrator", "pass", "MyDomain");
Christian Specht
  • 35,843
  • 15
  • 128
  • 182
Ian
  • 11
  • 1
0

I had a similiar problem, it turned out that the the client was configured to use NTLM security, but no NTLM header was attached.

I my case, becuase of the fact that I was using this code on the server-side of an ASP.NET applicaton, was to enable Windows authentication and set

identity impersonate="true"

in the server.web section.

Pawel Gorczynski
  • 1,227
  • 1
  • 15
  • 17
0

if your sharepoint server is built on a farm, Check your "Alternate Access Mapping" see if there is an entry: yourwebserverurl intranet yourwebserverurl if not, add it.

for my case, after adding this, the Copy service start working.

It probably due to farm load balance address resolve related.

Mark
  • 11
  • 1
0

I'm not sure if it will solve your problem but, when you reference the webservice, don't use the [site] part of the URL.

Try instead: http://[server]/_vti_bin/[webservice].

I'm not an expert in SP but I'm pretty sure the webservices belongs to the main server, not to an especific site.

Hope it helps.

Vitor
  • 9
  • 1
0

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
  • 109
  • 1
  • 3
-1

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

Kasper
  • 1,710
  • 2
  • 17
  • 31