带有特殊字符的WOPI文件名无法在在线编辑器中打开文件

时间:2019-04-26 10:51:38

标签: c# ms-wopi office-online-server wopi

有一个专门为其中一个Web应用程序设置的WOPI客户端和主机,并且当文件名正确且没有任何URL保留字符时,但当文件名包含+,#,&时,在线编辑器可以正常工作。标志WOPI协议路由将这些字符视为分隔符,并提供404错误,因为该路由不适用于GetFile,GetFileInfo端点。

示例:

        [Route("files/{fileName}/")]
        [HttpGet]
        public async Task<FileInfoBE> GetFileInfo(string fileName, string access_token)
        { //Logic here }

在上述端点调用中,如果文件名包含加号(+),并且如果对该端点的调用是url编码的,则加号将转换为%2b,理想情况下,它将击中该端点,但在调用之前由网络客户端制作的%2b已转换为+号,并显示404错误。

注意:由于OWA服务器与WOPI服务进行交互,因此自定义编码无济于事。

1 个答案:

答案 0 :(得分:1)

问题在于,路由属性参数经过URL编码后将不接受任何保留字符,甚至

https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

将起作用

https://localhost:44349/files/?fileName=mydocument%2B%23%26.docx&access_token=test-token

[Route("files/")]
[HttpGet]
public async Task<string> GetFileInfo2(string fileName, string access_token)
{
    return "Test";
}

无效

https://localhost:44349/files/mydocument%2B%23%26.docx?access_token=test-token

[Route("files/{fileName}/")]
[HttpGet]
public async Task<string> GetFileInfo(string fileName, string access_token)
{
    return "Test";
}

使用WebClient代理调用从Javascript前端到C#后端的完整示例:

Javascript:

let fileName = encodeURIComponent('mydocument+#&.docx');
fetch(`files?fileName=${fileName}&access_token=test-token`)
    .then(function (response) {
        return response.json();
    })
    .then(function (myJson) {
        console.log(JSON.stringify(myJson));
    });

C#:

[Route("files/")]
[HttpGet]
public async Task<string> GetFileInfo(string fileName, string access_token)
{
    using (WebClient client = new WebClient())
    {
        var host = $"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}";

        var data = client.DownloadString($"{host}/proxy/files/?fileName={HttpUtility.UrlEncode(fileName)}&access_token={HttpUtility.UrlEncode(access_token)}");

        return data;
    }
}

[AllowAnonymous]
[Route("proxy/files/")]
[HttpGet]
public async Task<string> ProxyGetFileInfo(string fileName, string access_token)
{
    return "MyValues";

}

enter image description here

为什么不允许使用这些字符以及为什么需要首先处理它:

URI语法中不允许的排除的US-ASCII字符:

   control     = <US-ASCII coded characters 00-1F and 7F hexadecimal>
   space       = <US-ASCII coded character 20 hexadecimal>
   delims      = "<" | ">" | "#" | "%" | <">

排除字符“#”,因为它用于从片段标识符中分隔URI。排除百分比字符“%”,因为它用于转义字符的编码。换句话说,“#”和“%”是必须在特定上下文中使用的保留字符。

允许列出不明智的字符,但可能会导致问题:

   unwise      = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"

在查询组件中为reserved和/或在URI / URL中具有特殊含义的字符:

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","

上面的“保留”语法类指的是URI中允许的那些字符,但是通用URI语法的特定组件中可能不允许的那些字符。 并非在所有上下文中都保留了“保留”集中的字符。例如,主机名可以包含可选的用户名,因此它可能类似于ftp://user@hostname/,其中的'@'字符具有特殊含义。

来源:

https://stackoverflow.com/a/13500078/3850405