If you’re following along with the post on creating a WOPI host, it’s never fully apparent that you MUST adhere to the path shown in the article here:

http://blogs.msdn.com/b/officedevdocs/archive/2013/03/20/introducing-wopi.aspx

That is, the path to your host must contain ‘/wopi/files’.  It wasn’t clear to me in that article, nor could I find it in the WOPI spec. http://msdn.microsoft.com/en-us/library/hh622722(v=office.12).aspx

So, for example, here are some Routes I used in MVC

 

            config.Routes.MapHttpRoute(
                name: "Contents",
                routeTemplate: "api/wopi/files/{name}/contents",
                defaults: new { controller = "files", action = "GetFile" }
                );

            config.Routes.MapHttpRoute(
                name: "FileInfo",
                routeTemplate: "api/wopi/files/{name}",
                defaults: new { controller = "Files", action = "Get" }
                );

 

 

Here are the Actions

public class FilesController : ApiController
    {

        IFileHelper _fileHelper;
        public FilesController() : this(new FileHelper())
        {

        }

        public FilesController(IFileHelper fileHelper)
        {
            _fileHelper = fileHelper;
        }


        /// <summary>
        /// Required for WOPI interface - on initial view
        /// </summary>
        /// <param name="name"></param>
        /// <param name="access_token"></param>
        /// <returns></returns>
        public CheckFileInfo Get(string name, string access_token)
        {
            var fileInfo = _fileHelper.GetFileInfo(name);
            return fileInfo;
        }


        /// <summary>
        /// Required for View WOPI interface - returns stream of document.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="access_token"></param>
        /// <returns></returns>
        public HttpResponseMessage GetFile(string name, string access_token)
        {
            try
            {
                var file = HostingEnvironment.MapPath("~/App_Data/" + name);
                var rv = new HttpResponseMessage(HttpStatusCode.OK);
                var stream = new FileStream(file, FileMode.Open, FileAccess.Read);

                rv.Content = new StreamContent(stream);
                rv.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                return rv;

            }
            catch (Exception ex)
            {
                var rv = new HttpResponseMessage(HttpStatusCode.InternalServerError);
                var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(ex.Message ?? ""));
                rv.Content = new StreamContent(stream);
                return rv;
            }
        }





    }

 

And here is the helper

 

    public interface IFileHelper
    {
        CheckFileInfo GetFileInfo(string name);
    }

    public class FileHelper : IFileHelper
    {
        public CheckFileInfo GetFileInfo(string name)
        {
            var fileName = GetFileName(name);
            FileInfo info = new FileInfo(fileName);
            string sha256 = "";

            using (FileStream stream = File.OpenRead(fileName))
            using (var sha = SHA256.Create())
            {
                byte[] checksum = sha.ComputeHash(stream);
                sha256 = Convert.ToBase64String(checksum);
            }

            var rv = new CheckFileInfo
            {
                BaseFileName = info.Name,
                OwnerId = "admin",
                Size = (int)info.Length,
                SHA256 = sha256,
                Version = DateTime.Now.ToString("s")
            };

            return rv;
        }


        internal string GetFileName(string name)
        {
            var file = HostingEnvironment.MapPath("~/App_Data/" + name);
            return file;
        }
    }