首页 > 代码库 > 自定义开发的系统整合 office Web apps

自定义开发的系统整合 office Web apps

Office文档的web应用叫WOPI Host或者WOPI Server。
把查看编辑操作Office文档的web应用叫WOPI Client或者叫WOPI applications。
所以,Office Web Apps充当的就是WOPI Client的角色。
SharePoint,Exchange,自己开发的文档管理系统充当的就是WOPI Host的角色。
再看一下,浏览器,server,client三者的请求顺序及关系

技术分享

其实网上有关office web app的整合已经有相关的文章了,典型的是如何整合Office Web Apps至自己开发的系统(一) 和如何整合Office Web Apps至自己开发的系统(二),微软官网也有相应的demo。

这里在简单描述一下原理吧:office web apps(owas)扮演者一个客服端,它会访问我们asp.NET 站点的文件然后呈现出来。而我们常用的API主要有如下3个:

GET api/wopi/files/{name}?access_token={access_token}    
GET api/wopi/files/{name}/contents?access_token={access_token}     
POST api/wopi/files/{name}/contents?access_token={access_token}

至于每个API做什么 这里就不多说,第一个是owas 检查文件,传递的信息是json数据格式,第二个是owas获取文件流,第三个是owas post的文件流(保存修改文件)。首先我们来看看第一个API的实现:

[csharp] view plain copy print?技术分享技术分享
  1. [Route("files/{name}/")]  
  2.        public CheckFileInfo GetFileInfo(string name, string access_token)  
  3.        {  
  4.            Validate(name, access_token);  
  5.            var fileInfo = _fileHelper.GetFileInfo(name);  
  6.            bool updateEnabled = false;  
  7.            if (bool.TryParse(WebConfigurationManager.AppSettings["updateEnabled"].ToString(), out updateEnabled))  
  8.            {  
  9.                fileInfo.SupportsUpdate = updateEnabled;  
  10.                fileInfo.UserCanWrite = updateEnabled;  
  11.                fileInfo.SupportsLocks = updateEnabled;  
  12.            }  
  13.            return fileInfo;  
  14.        }  
技术分享
这里的 Validate(name, access_token) 方法主要是验证请求的文件名name与参数access_token是否一致,主要是验证是否是非法访问,返回一个CheckFileInfo对象,CheckFileInfo的定义如下:

[csharp] view plain copy print?技术分享技术分享
  1. public class CheckFileInfo  
  2.     {  
  3.         public CheckFileInfo()  
  4.         {  
  5.             this.SupportsUpdate = false;  
  6.             this.UserCanWrite = false;  
  7.         }  
  8.         public string BaseFileName { getset; }  
  9.         public string OwnerId { getset; }  
  10.         public long Size { getset; } //in bytes  
  11.         public string SHA256 { getset; } //SHA256: A 256 bit SHA-2-encoded [FIPS180-2] hash of the file contents  
  12.         public string Version { getset; }  //changes when file changes.  
  13.         public bool SupportsUpdate { getset; }  
  14.         public bool UserCanWrite { getset; }  
  15.         public bool SupportsLocks { getset; }  
  16.     }  
技术分享

现在在来看看第二个api的实现,主要返回对应文件的数据流:

[csharp] view plain copy print?技术分享技术分享
  1. [Route("files/{name}/contents")]  
  2.         public HttpResponseMessage Get(string name, string access_token)  
  3.         {  
  4.             try  
  5.             {  
  6.                 Validate(name, access_token);  
  7.                 var file = HostingEnvironment.MapPath("~/App_Data/" + name);  
  8.                 var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);  
  9.                 var stream = new FileStream(file, FileMode.Open, FileAccess.Read);  
  10.                 responseMessage.Content = new StreamContent(stream);  
  11.                 responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");  
  12.                 return responseMessage;  
  13.             }  
  14.             catch (Exception ex)  
  15.             {  
  16.                 var errorResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError);  
  17.                 var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(ex.Message ?? ""));  
  18.                 errorResponseMessage.Content = new StreamContent(stream);  
  19.                 return errorResponseMessage;  
  20.             }  
  21.         }  
技术分享

而第三个api是将返回的数据流保存到物理文件:

[csharp] view plain copy print?技术分享技术分享
  1. [Route("files/{name}/contents")]  
  2.         public async void Post(string name, [FromUri] string access_token)  
  3.         {  
  4.             var body = await Request.Content.ReadAsByteArrayAsync();  
  5.             var appData = HostingEnvironment.MapPath("~/App_Data/");  
  6.             var fileExt = name.Substring(name.LastIndexOf(‘.‘) + 1);  
  7.             var outFile = Path.Combine(appData,name);  
  8.             File.WriteAllBytes(outFile, body);  
  9.         }  
技术分享