You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Function下载SharePoint Online文件时的FileContentResult编码异常问题

问题:Azure Function从SharePoint下载文件后损坏(编码问题)

我在使用HTTP触发的Azure Function从SharePoint Online下载文件时遇到了编码问题,文件可成功下载但显示损坏,无法识别文件类型。以下是相关代码:

DownloadFile方法代码

public dynamic DownloadFile(Guid fileUniqueId)
{
    const string apiUrl = "{0}/_api/web/GetFileById('{1}')/$value";

    try
    {
        var fileInfo = GetFileInfo(fileUniqueId);
        if (string.IsNullOrEmpty(_sharepointSiteUrl)) return null;

        string api = string.Format(apiUrl, _sharepointSiteUrl, fileUniqueId.ToString());
        string response = new TokenHelper().GetAPIResponse(api);
        if (string.IsNullOrEmpty(response)) return null;

        
        return new {
            fileInfo.FileName,
            Bytes = Encoding.UTF8.GetBytes(response)
        };
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Azure Function触发代码

string guidString = req.Query["id"];
if (!Guid.TryParse(guidString, out var fileId))
    return new BadRequestResult();

var fileManager = new FileManager();
dynamic fileData = fileManager.DownloadFile(fileId);
if (null == fileData) return new NotFoundResult();

var contentType = (((string)fileData.FileName).ToUpper().EndsWith(".PNG") || ((string)fileData.FileName).ToUpper().EndsWith(".JPEG") || ((string)fileData.FileName).ToUpper().EndsWith(".JPG")) ? "image/jpeg" : "application/octet-stream";

return new FileContentResult(fileData.Bytes, contentType)
{
    FileDownloadName = fileData.FileName
};

问题原因与修复方案

核心问题

SharePoint的$value接口返回的是文件原始二进制流,但你当前代码把二进制数据先转换成UTF-8字符串,再转回字节数组——这个过程会彻底破坏非文本文件(图片、文档等)的字节结构:二进制数据中大量不符合UTF-8编码规则的字节序列会被替换成占位符(如�),最终导出的字节数组和原始文件完全不一致,导致文件损坏。

修复步骤

  1. 修改TokenHelper的GetAPIResponse方法,让它直接返回byte[],跳过字符串转换,保留原始二进制数据:

    public byte[] GetAPIResponse(string apiUrl)
    {
        using (var client = new HttpClient())
        {
            // 此处添加你的身份验证逻辑(如设置Authorization请求头)
            var response = client.GetAsync(apiUrl).Result;
            response.EnsureSuccessStatusCode();
            return response.Content.ReadAsByteArrayAsync().Result;
        }
    }
    
  2. 更新DownloadFile方法,直接使用二进制字节数组返回:

    public dynamic DownloadFile(Guid fileUniqueId)
    {
        const string apiUrl = "{0}/_api/web/GetFileById('{1}')/$value";
    
        try
        {
            var fileInfo = GetFileInfo(fileUniqueId);
            if (string.IsNullOrEmpty(_sharepointSiteUrl)) return null;
    
            string api = string.Format(apiUrl, _sharepointSiteUrl, fileUniqueId.ToString());
            byte[] fileBytes = new TokenHelper().GetAPIResponse(api);
            if (fileBytes == null || fileBytes.Length == 0) return null;
    
            return new {
                fileInfo.FileName,
                Bytes = fileBytes
            };
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
    
  3. (可选优化)修正ContentType判断逻辑,PNG文件需匹配image/png类型,避免浏览器识别错误:

    var fileName = (string)fileData.FileName;
    var contentType = fileName.ToUpper() switch
    {
        var name when name.EndsWith(".PNG") => "image/png",
        var name when name.EndsWith(".JPG") || name.EndsWith(".JPEG") => "image/jpeg",
        _ => "application/octet-stream"
    };
    

内容的提问来源于stack exchange,提问作者Hubert Solecki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:32:33