When uploading an attachment to a list of SharePoint via WebService, the file cannot be too large...

Source: Internet
Author: User
Tags silver light

A submition project uses Silverlight to make a form to submit data to the list of SharePoint. In addition to entering some information, the form can also upload attachments, however, the problem is that the upload fails if the file size is large during attachment upload.

The general idea of this project is to use Silverlight to collect data and then use JavaScript to call the related WebService of Sharepoint to upload data. The related code is as follows:

1. Silverlight:

  1. Openfiledialog = new openfiledialog ();
  2. If (bool) openfiledialog. showdialog ())
  3. {
  4. Fileinfo = openfiledialog. file;
  5. Stream stream = fileinfo. openread ();
  6. Byte [] buffer = new byte [stream. Length];
  7. Stream. Read (buffer, 0, buffer. Length );
  8. String strfilecontent = convert. tobase64string (buffer );
  9. Stream. Close ();
  10. }

That is, the content of the selected file is obtained in Silverlight and converted into a string for calling in JavaScript.

2. Use JavaScript to upload files to SharePoint, that is, use the addattachment method in SharePoint's WebService lists. amsx:

  1. Function addattachment (listname, listitemid, filename, strfilecontent ){
  2. VaR xmlrequest;
  3. Xmlrequest = soapprefix + '<addattachment xmlns = "http://schemas.microsoft.com/sharepoint/soap/"> <listname>' +
  4. Listname + '</listname> <listitemid>' + listitemid + '</listitemid> <FILENAME>'
  5. + Filename + '</FILENAME> <attachment>' + strfilecontent + '</attachment> </addattachment>'
  6. Xmlrequest + = soappostfix;
  7. If (! Xmlhttplists)
  8. Xmlhttplists = gethttpobject ();
  9. Xmlhttplists. Open ("Post", "http: // localhost/_ vti_bin/lists. asmx? OP = addattachment ", false );
  10. Xmlhttplists. setRequestHeader ("Content-Type", "text/XML; charset = UTF-8 ");
  11. Xmlhttplists. setRequestHeader ("soapaction", "http://schemas.microsoft.com/sharepoint/soap/AddAttachment ");
  12. Xmlhttplists. setRequestHeader ("Content-Length", xmlrequest. Length );
  13. Xmlhttplists. Send (xmlrequest );
  14. Return xmlhttplists. readystate + "--" + xmlhttplists. status;
  15. }

Note:Listitemid is a listid returned after a record is added to the list of SharePoint by calling the updatelistitems method of WebService.

When the file is successfully uploaded within an hour, but the file size exceeds 30 mb, the upload fails, and an error such as "remote server cannot be called" or "the remote server returned an error: notfound" is thrown, the HTTP status code returned is 500. To find the root cause of the problem, I tried the following methods:

1. I suspect that the C # code of Silverlight does not pass strfilecontent to JavaScript.
During the test, 10 ~ 30 m file upload is normal, but fails when the file size exceeds 40 m. After tracking and debugging, when uploading a 40 m file, try to view the content of strfilecontent in C #, but the message "unable to evaluate the expression. Insufficient storage space, unable to complete this operation" is displayed ". It may be because the length of strfilecontent is too long and the memory is limited and cannot be properly displayed. Is it because strfilecontent cannot be correctly passed to Javascript, leading to upload failure? At the beginning of the addattachment function of JavaScript, I added a debug statement showing the strfilecontent length. The result shows that JavaScript has obtained the complete file content, so this possibility can be discharged. In fact, there is no length limit on the string, and the size depends on the memory. At least a few GB is fine.

2. I suspect that JavaScript cannot upload large files due to memory restrictions. I tried to directly use the C # WebClient in Silverlight to directly call the SharePoint web service to upload files.
Is JavaScript unable to upload large files due to certain restrictions (such as memory? To this end, I changed the method of using JavaScript to call WebService, but in C #, I directly used WebClient to call WebService to upload attachments.

  1. String xmlrequest = "<? XML version =/"1.0/" encoding =/"UTF-8/"?> <Soap: envelope xmlns: xsi =/"http://www.w3.org/2001/XMLSchema-instance/" xmlns: XSD =/"http://www.w3.org/2001/XMLSchema/" xmlns: Soap =/"http://schemas.xmlsoap.org/soap/envelope//"> <soap: body> "+" <addattachment xmlns =/"http://schemas.microsoft.com/sharepoint/soap//"> <listname> filelist </listname> <listitemid> 4 </listitemid> <FILENAME> testfilename </FILENAME> <attachment> "+ strfilecontent +" </attachment> </addattachment> ";
  2. Xmlrequest + = "</soap: Body> </soap: envelope> ";
  3. WebClient WC = new WebClient ();
  4. WC. headers ["Content-Type"] = "text/XML; charset = UTF-8 ";
  5. WC. headers ["soapaction"] = "http://schemas.microsoft.com/sharepoint/soap/AddAttachment ";
  6. // WC. headers ["Content-Length"] = xmlrequest. length. tostring ();
  7. WC. uploadstringcompleted + = new uploadstringcompletedeventhandler (wc_uploadstringcompleted );
  8. WC. uploadstringasync (New uri ("http: // localhost/_ vti_bin/lists. asmx? OP = addattachment ", urikind. Absolute), xmlrequest );

But the problem persists. When the uploaded file is too large, "the remote server returned an error: notfound" is returned ".

Note:To use the WebClient of silver light to call WebService, you must store the "clientaccesspolicy. xml" file in the site directory of SharePoint. Otherwise, the access will be rejected. If you use JavaScript to access WebService, you do not need to configure the policy file, but it must be in the same domain as Sharepoint.

3. If it is suspected that it is a Sharepoint issue, try to manually upload large attachments directly in SharePoint
Is it a problem with SharePoint itself? I tried to manually upload a 40 m file directly in Sharepoint. the upload was successful. Even if the file is a little larger (50 MB or less ). Is there a problem with accessing the Web service?

4. Try to use C # In silver light to directly reference SharePoint Web Service (add service reference) and call its method to upload attachments.
I changed the WebService calling method. XMLHTTP without JavaScript and WebClient of Silverlight are not used. In the Silverlight project, add service reference to generate a proxy and use a proxy to call WebService:

  1. Srlists. listssoapclient LSC = new uploadfiletow.pointlists. srlists. listssoapclient ();
  2. LSC. addattachmentcompleted + = new eventhandler <uploadfiletosharepointlists. srlists. addattachmentcompletedeventargs> (lsc_addattachmentcompleted );
  3. LSC. addattachmentasync ("filelist", "4", "testfilename002", buffer );

You still cannot upload files of 40 MB.

5. I suspect it is not a Sharepoint issue. I have customized a Web Service for Silverlight to call.
So far, it may not be a problem with Sharepoint. We have to leave SharePoint aside and it is probably a problem With WebService. Because we only send a WebService request to the server in a certain message format. Generally, as long as the server receives the data request, the server cannot process the request in real time and should not return the "unfound server" error. Maybe none of our request servers have received them correctly.
To this end, I write a WebService to replaceAddattachmentMethod, but this method only receives the request and returns the size of the file, without any actual file storage operations.

  1. [Webmethod]
  2. Public String addattachment (byte [] buffer)
  3. {
  4. Return buffer. length. tostring ();
  5. }

Similarly, when a small file is uploaded, the upload fails if the file is too large. But at least it proves that this problem has no substantive relationship with Sharepoint, most of which are problems at the web service level.

6. Finally, it is found to be related to the maxrequestlenght configuration in Web. config, but the Upload File fails when it is smaller than the specified size.
This caused me to think further. Is there a limit on the amount of data sent by WebService? If there are many parameters and the data volume is large, how can I send these requests to the server? Our problem lies in the fact that the parameter data volume during web service calling is too large.

This reminds me of the size limit when uploading files in ASP and. net. In fact, I should have remembered this, but I didn't know it very clearly before. From the server perspective, client requests are a bunch of HTTP packets, including httpheader and HTTP body (not rigorous in WebService ), the server needs to limit the size of the HTTP packet requested, otherwise it is prone to attacks. This configuration item exists in Web. config:

  1. <Configuration>
  2. <System. Web>
  3. <Httpruntime maxrequestlength = "1048576" executiontimeout = "3600"/>
  4. </System. Web>
  5. </Configuration>

TheMaxrequestlengthAttribute limits the maximum length of the request data packet. I tried to change my web. configMaxrequestlengthWhen this value is large, it can indeed be uploaded.40 m. The problem is a bit of an eye-catching. Then, find the configuration attributes of this section in the web. config under the SharePoint site and findMaxrequestlengthYes51200That is exactly 50 m. But why can't I upload 40 m of data?

Note:
MaxrequestlengthIndicates the maximum number of bytes uploaded by ASP. NET over HTTP. This restriction can be used to prevent DoS attacks caused by a large number of files being transferred to the server. The specified size is in KB. The default value is 4096 KB (4 MB ).

Executiontimeout: Indicates the maximum number of seconds allowed to execute a request before it is automatically disabled by ASP. NET. For other related attributes, refer to msdn. The default configuration of this attribute is in machine. config.

In addition, the server has limits on memory usage. You can refer to the following configuration section:
<Configuration>
<System. Web>
<Processmodel memorylimit = "80"/>
</System. Web>
</Configuration>

7. The basic locking is caused by the size limit on the uploaded files by web. config. Therefore, use simple fileupload in Asp.net to test
It has been basically determined that the maxrequestlength setting is a problem, but when the maxrequestlength is set to 50 m, the actual upload will not be 50 m, or even 40 m will not be uploaded. Is there an error in the middle? The error is too large. So I tested it in ASP. NET and putFileuploadControl, the background only calculates the file size:
. Aspx file content:

  1. <Asp: fileupload id = "Fu" runat = "server"/>
  2. <Asp: button id = "BTN" runat = "server" text = "Upload File" onclick = "btn_click"/>

. CS file:

  1. Protected void btn_click (Object sender, eventargs E)
  2. {
  3. Int Len = Fu. postedfile. contentlength;
  4. }

Indeed, when the size of the uploaded file exceeds maxrequestlength, an error such as "server inaccessible" may occur, which is similar to the preceding error. IfMaxrequestlengthIt is configured as 50 MB and cannot be uploaded.50 m, But can be uploaded49.99 m. The error is significantly reduced.

8. Use Fiddler to track data packets.
To thoroughly understand the problem above, we 'd better track the data transfer processHTTPThe packet sending information to see how many data packets have been sent. For this reason, I installFiddler.

1) When fileupload is used in Asp.net to upload a file, the transmitted HTTP packet is slightly larger than the selected file. The fiddler monitoring shows that the data sent is as large as the selected file size, but the HTTP header is too large.ViewstateAnd _EvengnameAnd other content (these are necessary for the ASP. NET mechanism, and I did not write them accurately), so they are slightly larger than the file size, which is alsoMaxrequestlengthIt is set to 50 m but the actual file passed can only be 49.99m.

2) When WebService is called in Silverlight to upload files, it is detected through fiddler that part of the HTTP request data is much larger than the actual file size. For example, to upload a 20 m file, the size of the body data in the HTTP request package is nearly27 m. I customized a text file with the content "abcd123456". When I uploaded the file, I found that the file content in the HTTP request was changed to "yqbiagmazaaxadiamwa0aduanga =", which indeed increased the file size. InFileuploadWhen uploading files in plain text, how does one change the file content when WebService is called? Is it encrypted? It was later discovered that this is not encrypted,Convert. tobase64string. Although the content of byte [] is converted into base64string, the length is indeed increased a lot. Although the parameter we pass to WebService is directly byte [], it does not explicitly convert. tobase64string, but it is automatically changedBase64stringThe transfer content is greatly increased.

At this point, we have figured out why the maximum upload allowed for Sharepoint is 50 MB, but it is impossible to upload 40 MB through WebService.

 

**************************************** **************************************** ****************************

About fiddler2:
Fiddler is a good debugging plug-in for monitoring HTTP data packets on IE, but it ignores requests to localhost during use, you can use the following methods to enable Fiddler to intercept local data packets:
Http: // localhost: 81/myweb ---------------- à http: // localhost.81/myweb (LThe ocalhost is followed by a dot ".", so is the reference WebService.).

By the way, I wrote a related short article:
========================================================== ==========================================
IE7 and the. NET Framework are hardcoded not to send requests for localhost through proxies. fiddler runs as a proxy. The workaround is to use your machine name as the hostname instead of localhost or 127.0.0.1.
So, for instance, rather than hitting http: // localhost: 8081/mytestpage. aspx, instead visit http: // machinename: 8081/mytestpage. aspx. alternatively, you can use http: // localhost.: 8081/mytestpage. aspx (note the trailing dot afterLocalhost). Alternatively, you can customize your rules file like so:
Static function onbeforerequest (osession: Fiddler. Session ){
If (osession. Host. toupper () = "MyApp") {osession. Host = "127.0.0.1: 8081 ";}
}
... And then navigate to http: // MyApp, which will act as an alias for 127.0.0.1: 8081.
I prefer the localhost. method.
If you use iis7, you can also customize it by yourself.
<System.net>
<Defaultproxy>
<Proxy proxyaddress = "http: // FIG: 8888"/>
</Defaultproxy>
</System.net>
In this way, the data is accessed through the proxy, so that the fiddler can capture the data.
 **************************************** **************************************** ****************************

Finally, let's summarize:
1. The key to the problem is that maxrequestlength limits the maximum data size of an HTTP request. maxrequestlength refers to the total data of an HTTP request (the content of the htt header already exists), rather than just a common conceptual file;
2. byte [] is converted to base64string to increase the data volume.
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.