C#中从服务器向客户端传输.dotx文件时的数据丢失问题
Azure Blob Storage 文件下载末尾数据缺失导致Office文档无法正常打开
我将文件存储在Azure Blob Storage中,通过ASP.NET实现下载功能,点击按钮触发以下代码调用中间服务获取文件:
protected async void WebPagePopupDownloadDocumentButtonOnClick(object sender, EventArgs e) { string rawJson = JsonResultHiddenField.Value; string unescapedJson = System.Web.HttpUtility.HtmlDecode(rawJson).Trim('"'); if (unescapedJson.StartsWith("\"") && unescapedJson.EndsWith("\"")) { unescapedJson = unescapedJson.Substring(1, unescapedJson.Length - 2); } unescapedJson = unescapedJson.Replace("\\\"", "\""); unescapedJson = unescapedJson.Replace("\\r", "").Replace("\\n", ""); try { var jsonObject = JObject.Parse(unescapedJson); string fileUrl = (string)jsonObject["Documents"]?[0]?["FileUrl"]; if (fileUrl != null) { using (var httpClient = new HttpClient()) { string guidText = GuidLabel.Text; string guid = guidText.Substring(guidText.IndexOf(":") + 2).Trim(); var configManager = Container.Resolve<IFeConfigManager>(); var nawServicesUrl = configManager.GetModel<KeyValueConfig>(ConfigurationModels.SendToInfolex, ApplicationManager.Instance.RecoverProductId())["NawServicesUrl"]; var accessToken = SessionManager.Instance.RecoverSession()?.OidcWorkflowData?.TokenResponseData?.AccessToken; httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); string fileName = Path.GetFileName(fileUrl); string url = $"{nawServicesUrl}{DOWNLOAD_DOCUMENT_OP}?guid={guid}&fileName={fileName}"; var response = await httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var fileBytes = await response.Content.ReadAsByteArrayAsync(); string tempFilePath = Path.Combine(Path.GetTempPath(), fileName); File.WriteAllBytes(tempFilePath, fileBytes); Response.Clear(); Response.ContentType = GetContentType(fileName); Response.AddHeader("Content-Disposition", $"attachment; filename={fileName}"); Response.TransmitFile(tempFilePath); Response.End(); } } else { Console.WriteLine("No FileUrl found."); } } catch (JsonReaderException ex) { Console.WriteLine($"JSON parse error: {ex.Message}"); } } private string GetContentType(string fileName) { string extension = Path.GetExtension(fileName).ToLower(); switch (extension) { case ".pdf": return "application/pdf"; case ".doc": return "application/msword"; case ".docx": return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; case ".html": return "text/html"; case ".dotx": return "application/vnd.openxmlformats-officedocument.wordprocessingml.template"; default: return "application/octet-stream"; } }
问题现象
目前HTML、PDF文件下载后可正常打开,但Office文档出现异常:
- .docx文件打开时,Microsoft Word提示存在不可读内容,确认后可打开;
- .dotx文件直接无法打开。
直接从Azure Blob Storage下载的文件可正常打开,对比发现通过应用下载的文件大小更小,用HxD工具查看后确认缺失了最后10KB数据。
已尝试的解决方案
我试过几种方案但都未解决问题:
- 先将文件下载到服务器临时路径再传输(即上述原始代码逻辑)
- 直接传输字节数组:
var fileBytes = await response.Content.ReadAsByteArrayAsync(); Response.Clear(); Response.ContentType = GetContentType(fileName); Response.AddHeader("Content-Disposition", $"attachment; filename={fileName}"); Response.BinaryWrite(fileBytes); Response.End();
- 异步写入临时文件:
var fileBytes = await response.Content.ReadAsByteArrayAsync(); string tempFilePath = Path.Combine(Path.GetTempPath(), fileName); await WriteBytesAsync(tempFilePath, fileBytes); ... private async Task WriteBytesAsync(string filePath, byte[] bytes) { using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true)) { await fileStream.WriteAsync(bytes, 0, bytes.Length); } }
内容的提问来源于stack exchange,提问作者Julio Escudero Cuesta
相关产品推荐
相关产品推荐

