用于将数据导出到excel而不是返回viewmodel的基本控制器

时间:2014-08-18 15:53:17

标签: c# asp.net-web-api

我有一个Web API项目,我的控制器返回一个视图模型,以便客户端应用程序可以将数据显示到网格中。

这是一个带有示例方法的示例控制器,因此我可以更好地解释:

public class SampleController: ApiControllerBase
{ 
     [HttpGet, AppAuthorize(null)]
     public HttpResponseMessage GetSampleData(int employeeId, DateTime fromDate, DateTime toDate)
     {
         HttpResponseMessage returnVal = null;

         // THIS IS NEW, SO INSTEAD OF RETURNING A MODEL I WILL RETURN A FILE
         // BUT I DON'T WANT TO ADD THIS TO EVERY CONTROLLER, I WOULD LIKE TO HAVE IT IN A BASE CONTROLLER OR SOMETHING?
         // CHECK IF USER REQUEST TO EXPORT GRID TO EXCEL

         if (this.Request.GetQueryStrings().ContainsKey("exportdata"))
         {
             // here I will have to generate the excel file

             returnVal = new HttpResponseMessage(HttpStatusCode.OK);

             returnVal.Content = new ByteArrayContent(fileBytes);

             returnVal.Content.Headers.ContentDisposition = new Headers.ContentDispositionHeaderValue("attachment");
             returnVal.Content.Headers.ContentDisposition.FileName = fileName;
             returnVal.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

             return returnVal;
         }

         var model = SampleRepository.GetConsumptionSummary(employeeId, fromDate.ToUniversalTime().Date, toDate.ToUniversalTime().Date);

         if (model != null)
         {
             returnVal = Request.CreateResponse(HttpStatusCode.OK, new Model.Custom.JsonResponse {
                 data = model,
                 message = "",
                 num = model.Count,
                 success = true
             });
         } else {
             returnVal = Request.CreateResponse(HttpStatusCode.OK, new Model.Custom.JsonResponse {
                 data = null,
                 message = "There was an error processing the data.",
                 num = 0,
                 success = false,
                 code = "ERR-001"
             });
         }

         return returnVal;
     }
 }

在客户端上,用户可以请求将相同的网格数据导出到excel。在这种情况下,我将使用相同的网格方法生成excel文件并返回浏览器。

if (this.Request.GetQueryStrings().ContainsKey("exportdata"))
{
}

此行在方法中具有神奇功效,因此我知道用户是否已请求将数据导出为ex​​cel。

但是,我不想把这个逻辑放在每个控制器上的每个方法上,我想在一个单独的地方,但这适用于所有方法。

  

我正在考虑创建一个Filter,我可以放在我想要发生逻辑的方法或控制器中。

我应该在我的过滤器中使用的代码或替代方法是:

// CHECK IF USER REQUEST TO EXPORT GRID TO EXCEL
if (this.Request.GetQueryStrings().ContainsKey("exportdata"))
{
    // here I will have to generate the excel file...

    returnVal = new HttpResponseMessage(HttpStatusCode.OK);
    returnVal.Content = new ByteArrayContent(fileBytes);
    returnVal.Content.Headers.ContentDisposition = new Headers.ContentDispositionHeaderValue("attachment");
    returnVal.Content.Headers.ContentDisposition.FileName = fileName;
    returnVal.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    return returnVal;
}

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

你有FileStreamResult可以帮助你,所以你不必总是声明太多东西。

我会创建一个自定义ActionResult。在我们的一个应用程序中,我们使用这样的自定义“ExcelResult”:

public class ExcelResult : FileStreamResult
{
    public ExcelResult(Stream fileStream, string fileName)
        : base(fileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    {
        FileDownloadName = fileName;
    }
}

因此,当我们需要生成并返回一个Excel文件时,我们会这样做(我们甚至将这个位作为“BaseController”中的方法提取出来):

using (MemoryStream result = (MemoryStream)ExportService.ExportToExcel(foo))
{
    return Excel(new MemoryStream(result.GetBuffer()), fileName);
}

Excel方法(在我们的基本控制器中):

public ExcelResult Excel(Stream stream, string fileName)
{
    if (stream == null)
        throw new ArgumentNullException("stream");
    if (string.IsNullOrWhiteSpace(fileName))
        throw new ArgumentNullException("fileName");

    return new ExcelResult(stream, fileName);
}