首页 > 解决方案 > 导出的文件返回为 JSON 而不是 Excel 文件

问题描述

我试图返回一个 Excel 文件,但它总是试图保存一个 JSON 文件而不是 Excel 文件。你能告诉我这段代码有什么问题吗?我认为内容类型是错误的,但我在那里尝试了几个选项,但仍然返回 JSON ......

/Excel 生成器

public class ExcelFileBuilder
{
    public byte[] BuildEmployeeRecordFile(IEnumerable<EmployeeRecordDto> records)
    {
        byte[] fileContents;
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
        using (var package = new ExcelPackage())
        {
            var worksheet1 = package.Workbook.Worksheets.Add("TEST");
            //ADD data here

            // Export it to byte array
            fileContents = package.GetAsByteArray();
        }
        return fileContents;
}

/查询类

public class ExportEmployeeRecordQuery : IRequest<ExportEmployeeRecordVm>
{

}

public class ExportEmployeeRecordQueryHandler : IRequestHandler<ExportEmployeeRecordQuery, ExportEmployeeRecordVm>
{
    private readonly IApplicationDbContext _context;
    private readonly IExcelFileBuilder _fileBuilder;

    public ExportEmployeeRecordQueryHandler(IApplicationDbContext context, IExcelFileBuilder fileBuilder)
    {
        _context = context;
        _fileBuilder = fileBuilder;
    }

    public async Task<ExportEmployeeRecordVm> Handle(ExportEmployeeRecordQuery request, CancellationToken cancellationToken)
    {
        var vm = new ExportEmployeeRecordVm();
        
        //get data from db here
        vm.Content = _fileBuilder.BuildEmployeeRecordFile(null); //pass null for now
        vm.ContentType = "application/octet-stream";
        vm.FileName = "TestFile.xlsx";

        return await Task.FromResult(vm);
    }
}

/虚拟机

public class ExportEmployeeRecordVm
{
    public string FileName { get; set; }

    public string ContentType { get; set; }

    public byte[] Content { get; set; }
}

/Azure 函数

public class ExportAgentEmployeeRecordFunction
{
    private readonly IMediator _mediator;
    private readonly IHttpFunctionExecutor _httpFunctionExecutor;

    public ExportAgentEmployeeRecordFunction(IMediator mediator, IHttpFunctionExecutor httpFunctionExecutor)
    {
        _mediator = mediator;
        _httpFunctionExecutor = httpFunctionExecutor;
    }

    [FunctionName("ExportAgentEmployeeRecordFunction")]
    public async Task<IActionResult> Run(
       [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]
        ExportEmployeeRecordQuery qry)
    {
        return await _httpFunctionExecutor.ExecuteAsync(async () =>
        {
            var res = await _mediator.Send(qry);
            return new OkObjectResult(res);
        });
    }
}

我试图返回一个 Excel 文件,但它总是试图保存一个 JSON 文件而不是 Excel 文件。你能告诉我这段代码有什么问题吗?我认为内容类型错误,但我在那里尝试了几个选项,但仍然返回 JSON。

标签: c#excelazure-functionsasp.net-core-webapiepplus

解决方案


您使用了错误的派生操作结果类型

OkObjectResult

一个 ObjectResult,执行时执行内容协商,格式化实体主体,如果协商和格式化成功,将产生一个 Status200OK 响应

这意味着它正在包装传递的视图模型并根据请求将其作为 JSON 返回。

鉴于您要实现的目标,您需要使用FileContentResult Class

表示一个 ActionResult,执行时会将二进制文件写入响应。

并使用返回的视图模型的成员填充它

例如

//...

[FunctionName("ExportAgentEmployeeRecordFunction")]
public async Task<IActionResult> Run(
   [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]
    ExportEmployeeRecordQuery qry) {
    return await _httpFunctionExecutor.ExecuteAsync(async () => {
        ExportEmployeeRecordVm response = await _mediator.Send(qry);
        FileContentResult result =  new FileContentResult(response.Content, response.ContentType){
            FileDownloadName = response.FileName
        };
        return result;
    });
}

//...

推荐阅读