如何从HttpInputStream获取docx文件的字节数组?

10

我正在使用这篇帖子中第一个答案的方法:如何从HttpPostedFile创建字节数组,但是由于某种原因它不能处理.docx文件。

//viewmodel.File is HttpPostedFileBase

byte[] fileData;
using (var binaryReader = new BinaryReader(viewModel.File.InputStream))
{
    fileData = binaryReader.ReadBytes(viewModel.File.ContentLength);
}

.docx文件的fileData显示为{byte[0]},但它可以与pdf、excel文件(xlsx)、2007年之前的Word文件(doc)和图像一起使用(即值大于零)。 将其保存到数据库中,文件数据是 0x

如何从HttpInputStream获取.docx文件的字节数组?

更新
我的web.config已配置为

<httpRuntime targetFramework="4.5" maxRequestLength="102400" />

这段代码可以处理大于4MB的xslx文件,但是小于80KB的docx文件无法处理。

更新2
我可以使用这里的方法来填充fileData。

byte[] fileData = new byte[viewModel.File.ContentLength];
viewModel.File.InputStream.Read(fileData, 0, viewModel.File.ContentLength);

但如果我将该字节数组保存到数据库并尝试写入文件,则会严重损坏。在这种情况下保存到数据库中看起来像是0x00000000000000000000000...

更新3
以下是整个控制器方法,尽管我认为看到整个内容并不是必要的:

    [HttpPost]
    public ActionResult SaveChangeFile(AttachmentFormViewModel viewModel)
    {
        if (viewModel.File == null)
            return Json(new { success = false, message = "No file was found, please select a file and try again." }, "text/x-json",
                        JsonRequestBehavior.DenyGet);
        try
        {

            //Validate that the right kind of File has been uploaded
            OperationResponse response = _attachmentProcessor.ValidateAttachmentContentType(viewModel.File, (ChangeFileTypeEnum)viewModel.FileType);
            if (!response.IsSuccess)
                return Json(new { success = response.IsSuccess, message = response.Message }, "text/x-json", JsonRequestBehavior.DenyGet);

            UpdateProjectFromCostCalculatorRequest projectValues = null;

            Workbook workbook = null;
            Document document = null;

            if (_attachmentProcessor.IsWorkbook(viewModel.File))
                workbook = new Workbook(viewModel.File.InputStream);

            if (_attachmentProcessor.IsDocument(viewModel.File))
                document = new Document(viewModel.File.InputStream);

            var filename = Path.GetFileName(viewModel.File.FileName);

            //if cost calc, validate that the values are correct and update related project
            switch ((ChangeFileTypeEnum)viewModel.FileType)
            {
                case ChangeFileTypeEnum.CostCalculator:
                    response = _attachmentProcessor.ValidateCostCalculator(workbook, filename);
                    if (response.IsSuccess)
                        projectValues = _attachmentProcessor.GetDataFromCostCalculator(workbook);

                    break;
                case ChangeFileTypeEnum.DataValidation:
                    response = _attachmentProcessor.ValidateDataValidation(workbook);
                    break;
                case ChangeFileTypeEnum.WorkPaper:
                    response = _attachmentProcessor.ValidateWorkPaper(document);
                    break;
            }

            //return error message if any of the validations above failed
            if (!response.IsSuccess)
                return Json(new { success = response.IsSuccess, message = response.Message }, "text/x-json", JsonRequestBehavior.DenyGet);

            //get the file from the stream and put into a byte[] for saving the database
            byte[] fileData;
            using (var binaryReader = new BinaryReader(viewModel.File.InputStream))
            {
                fileData = binaryReader.ReadBytes(viewModel.File.ContentLength);
            }
            var file = new ChangeFile
                               {
                                   ChangeRequestID = viewModel.ChangeRequestId,
                                   ChangeFileTypeID = viewModel.FileType,
                                   File = fileData,
                                   Filename = filename,
                                   ContentType = viewModel.File.ContentType,
                                   CreatedBy = User.UserNameWithoutDomain(),
                                   UpdatedBy = User.UserNameWithoutDomain(),
                                   CreatedDate = DateTime.Now,
                                   UpdatedDate = DateTime.Now
                               };

                _changeRequestService.SaveChangeFile(file);

            var log = new ChangeFileImportLog { CreatedDate = DateTime.Now };
            switch ((ChangeFileTypeEnum)viewModel.FileType)
            {
                case ChangeFileTypeEnum.CostCalculator:
                    var project = _changeRequestService.GetChangeProjectByPsrs(file.ChangeRequestID, projectValues.PsrsNumber);
                    if (project != null)
                    {
                        _attachmentProcessor.UpdateChangeProjectWithProjectValues(project, projectValues);
                        log.NumberOfErrors = 0;
                        log.NumberOfSegmentChanges = 0;
                        log.NumberOfWarnings = 0;
                    }
                    else
                    {
                        log.NumberOfWarnings = 1;
                        log.Warnings =
                            String.Format(
                                "There is no project on this Change Request with PSRS \"{0}\". If there was, the new cost would be updated with \"{1:C0}\"",
                                projectValues.PsrsNumber, projectValues.Cost);
                    }
                    break;
                case ChangeFileTypeEnum.DataValidation:
                    log = _attachmentProcessor.CreateChangeSegmentsFromDataValidation(workbook, file.ChangeRequestID, file.ChangeFileID, User);
                    break;
                case ChangeFileTypeEnum.WorkPaper:
                    log = _attachmentProcessor.UpdateChangeProjectsFromWorkPaper(document, file.ChangeRequestID, file.ChangeFileID,
                                                                                 User);
                    break;
            }

            log.CreatedBy = User.UserNameWithoutDomain();
            log.CreatedDate = DateTime.Now;
            log.UpdatedBy = User.UserNameWithoutDomain();
            log.UpdatedDate = DateTime.Now;

            _changeRequestService.SaveChangeFileImportLog(log, file.ChangeFileID);
            _changeRequestService.Commit();
            return Json(new { success = response.IsSuccess, message = response.Message }, "text/x-json", JsonRequestBehavior.DenyGet);
        }
        catch (Exception ex)
        {
            return Json(new { success = false, message = String.Format("A system error was encountered: {0}", ex) }, "text/x-json", JsonRequestBehavior.DenyGet);

        }
    }

1
一个docx文件不应该被视为与其他文件类型有所不同。 - Trevor Elliott
如果其他文件可以正常上传,那么很可能该文件的大小超过了允许的上传大小。请参考这篇文章 https://dev59.com/9nVC5IYBdhLWcg3wcwwm 来配置文件大小。 - Mike Perrenoud
@neo,问题不在于文件太大,我们谈论的是其中一些文件大小为71KB,而我的web.config文件具有<httpRuntime targetFramework="4.5" maxRequestLength="102400" /> - wilsjd
@TrevorElliott 我也是这么想的,但是像这样的帖子让我有不同的想法:http://stackoverflow.com/questions/18243668/what-is-wrong-with-this-binary-file-transfer-corrupting-docx-files - wilsjd
以下是关于编程的内容,请将其翻译成中文。并展示完整的控制器方法。 - Moho
显示剩余5条评论
1个回答

12

结果发现,由于我已经在使用该流(参见问题中的控制器方法),当我尝试保存它时,它是空的。

我不确定为什么在处理 docx 文件时会出现这种情况,而在处理 xlsx 文件时却不会,因为它们在保存之前都会消耗其流。 我猜测这与Aspose.Cells和Aspose.Words实现中的差异有关。

无论如何,我将流的位置设置回0,然后它就能正常工作了。

//viewmodel.File is HttpPostedFileBase

viewModel.File.InputStream.Position = 0; //<-----This fixed it!

byte[] fileData;
using (var binaryReader = new BinaryReader(viewModel.File.InputStream))
{
    fileData = binaryReader.ReadBytes(viewModel.File.ContentLength);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接