我正在运行一个 SharePoint 2013 本地服务器,我在该服务器上部署了一个简单的 WCF 服务作为场解决方案。该服务接受包含单个 MS Word 文档作为有效负载的简单 Http 发布请求,并返回这些转换为 PDF 的文件。匿名用户可以通过 Http 访问该服务。WordAutomationService 作为 SharePoint 服务器的管理用户帐户运行。
服务类创建 Microsoft.Office.Word.Server.Conversions.SyncConverter 的新实例,并将 SharePoint 正在运行的 WordAutomationService 的代理传递给构造函数(连同一些 ConversionJobSettings)。最后,它使用输入流(Word 文档)和输出流(将包含 WordAutomationService 生成的 PDF 文档的 Web 响应)调用 SyncConverter 上的 Convert 方法。
创建 SyncConverter 时,我没有设置 UserToken 属性,因为对服务的访问是由匿名用户进行的。根据这里的评论https://msdn.microsoft.com/en-us/library/microsoft.office.word.server.conversions.syncconverter.usertoken.aspx这似乎没问题:
此属性的默认值是一个空引用(在 Visual Basic 中为 Nothing),它是匿名的。
此设置适用于具有几页的小型 Word 文档并返回预期的 PDF 文件。但是,一旦 SharePoint 上 WordAutomationService 的执行时间超过某个时间阈值(大约 5 秒),服务就会失败,因为它永远不会返回(这会导致客户端读取超时)。根据日志,其原因似乎是一段时间后同步转换作业将工作移至后台进程:
同步流作业转换时间过长。不要再等了。稍后检查其状态
然后,它通过调用 ConversionServiceApplicationProxy.BatchGetSyncJobStatus 定期轮询此作业的状态。不幸的是,这个调用失败了,因为它在内部尝试创建一个新通道来与这个进程对话,并为此请求一个安全令牌。然而,SecurityTokenService 无法完成令牌请求并引发异常:
An unhandled exception has occurred. The security token request cannot be completed. System.InvalidOperationException: The security token request cannot be completed.
at Microsoft.SharePoint.SPSecurityContext.SecurityTokenForServiceContext(Uri contextUri)
at Microsoft.SharePoint.SPChannelFactoryOperations.InternalCreateChannelActingAsLoggedOnUser[TChannel](ChannelFactory`1 factory, EndpointAddress address, Uri via)
at Microsoft.Office.ConversionServices.Service.ConfigChannelFactory`1.CreateChannel(EndpointAddress address)
at Microsoft.Office.ConversionServices.Service.ConversionServiceApplicationProxy.GetChannel(Uri uri)
at Microsoft.Office.ConversionServices.Service.ConversionServiceApplicationProxy.ExecuteOnChannel(Uri endpointAddress, Action`1 action)
at Microsoft.Office.ConversionServices.Service.ConversionServiceApplicationProxy.BatchGetSyncJobStatus(ICollection`1 ucids, Uri endpointAddress)
at Microsoft.Office.ConversionServices.Service.BatchGetStatusPollingThread.Run()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() StackTrace:
at onetnative.dll: (sig=37460b31-4453-4365-92f5-3a11c267be48|2|onetnative.pdb, offset=28F56) at onetnative.dll: (offset=15735)
我现在不知道如何摆脱令牌问题,以便系统可以创建必要的通道来轮询转换作业状态。非常感谢任何帮助。谢谢!
(我不能发布完整的日志,因为它注册为垃圾邮件)