我正在构建一个从SharePoint 2013或SharePoint 2010中提取文件以在HTML中查看的应用程序。在C#中,文件从SharePoint(多页文档,如Word,Excel,PDF,TIFF等)中拉出,然后被馈送到各种第三方软件(DataLogics和Aspose)中,后者将文档分解为单独的页面,然后进行流式处理浏览器以PNG格式显示各个页面。
因此,在HTML中,我们有一个img元素,其src设置为ASHX服务中的特定URL。 ASHX服务从SharePoint中获取文件,并根据查询字符串参数将所需的页面作为Stream返回。
这是我们将其拍摄回来的方法:
[WebService(Namespace = "url")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileTransfer : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
var stream = GetStream(context.Request);
int chunkSize = 2097152; //2MB
byte[] chunk = new byte[chunkSize];
int bytesRead = 0;
do {
bytesRead = stream.Read(chunk, 0, chunkSize);
HttpContext.Current.Response.OutputStream.Write(chunk, 0, bytesRead);
}
while (bytesRead > 0);
}
当我们要分解的文件直接来自SharePoint时,这在所有浏览器中都可以完美地100%地正常工作。
我们还提供了用户可以上传文档的功能。这就是问题所在。上载的文档未保存在SharePoint中。而是将其数据存储在SessionState中,直到用户选择保存为止。文件被上传到ASMX服务,然后浏览器通过上述ASHX请求它们的各个页面。
在ASMX服务中按以下方式上传文件:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Public object Upload()
{
var request = HttpContext.Current.Request;
if (request.Files.Count == 1)
{
var uniqueId = request["uniqueId"];
var file = request.Files[0];
using (var memoryStream = new MemoryStream())
{
file.InputStream.CopyTo(memoryStream);
docInfo = UploadItem(uniqueId, pageNum, memoryStream.ToArray());
}
}
}
UploadItem将uniqueId和byte []添加到SessionState。
文件是通过javascript这样发送的(FileUpload与type = file输入的change事件相关联):
this.FileUpload = function (files) {
var upload = new XMLHttpRequest();
upload.onreadystatechange = () => {
if (this._curUploadRequest.readyState == 4) {
// handle response
}
};
UpdateFormDigest((<any>window)._spPageContextInfo.webServerRelativeUrl,(<any>window)._spFormDigestRefreshInterval);
var data = new FormData();
data.append("uniqueId", uniqueId);
data.append("pageNum", pageNum);
data.append("data", files[0]);
upload.open('POST', "myurl");
upload.setRequestHeader("X-RequestDigest", $("#__REQUESTDIGEST").val());
upload.send(data);
};
现在我们来看看实际的错误。
使用以下方式渲染图像:
<img src="url to ASHX service" />
在FireFox和Chrome中,上传文档中的页面图像总是显示得很好。但是在IE(9、10或11)中,它仅渲染其中的第一部分,然后在图像占位符上显示损坏的图像图标。对于这些损坏的图像,IE的NET选项卡显示它收到了0kb的错误事件。但是,如果在返回流之前在ASHX中放置一个断点,则它始终具有大小。
更有趣的是,如果您使用src所指向的网址,请打开一个新窗口并将其粘贴到其中,图像就会很好地显示出来。
我什至尝试像这样首先在javascript中加载图像:
var img = new Image();
img.onload = function(){
// use jquery to append image to page
};
img.src = "url to ASHX service";
在这种情况下,Chrome和Firefox可以正常运行,但是IE再次失败。 IE的NET选项卡以这种方式除外,显示它收到了正确的大小kb作为响应。但是,它仍然显示损坏的图像图标,并且在某些未知阈值后不会将图像渲染到屏幕上。前几张图像会恢复,但是一旦中断,其余所有图像都会中断。
我还修改了ASHX服务以返回base64数据而不是流,然后将base64绑定到src。在调试器中,您可以看到分配给显示残破图像图标的img元素的src的base64。因此,数据肯定存在,但是IE并未呈现它...
我试图使用敲除JS在我们的SharePoint环境之外重新创建此问题。基本上,每次单击按钮时,我都会捕获大量的大图像并将其扔到屏幕上。但这很好。如果我也使用jQuery,它会完美地工作。
http://jsfiddle.net/bsdez92f/
不知道从这里去哪里。
有任何想法吗?
最佳答案
因此,事实证明图像大小引起了问题。我在服务器端将图像缩小到缩略图大小,然后将其返回给浏览器。此时一切正常。