我正在构建一个从SharePoint 2013或SharePoint 2010中提取文件以便在HTML中查看的应用程序。在C#中,文件从SharePoint(Word,Excel,PDF,TIFF等多页文档)中提取出来,然后被送入各种第三方软件(DataLogics和Aspose) - 将文档分解为各自的页面,然后流以PNG格式显示浏览器的各个页面。
因此在HTML中,我们有一个img元素,其src设置为ASHX服务中的特定URL。 ASHX服务从SharePoint中获取文件,并根据查询字符串参数将所需页面作为流返回。
以下是我们拍摄的方式:
[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指向的url,打开一个新窗口并粘贴它,图像显示就好了。
我甚至试图在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只是没有渲染它......
我试图在这个小提琴中使用knockout JS在我们的SharePoint环境之外重新创建这个问题。基本上,我抓住了大量的大图像,并按下每个按钮将它们扔到屏幕上。但它的工作正常。如果我也使用jQuery,它的工作原理很完美。
不知道从哪里开始。
有什么想法吗?
答案 0 :(得分:1)
事实证明,图像尺寸导致了问题。我将图像缩小到服务器端的缩略图大小并将其返回给浏览器。此时一切正常。