我有一个场景,用户可以选择单击“下载”按钮,我应该创建一个包含历史数据的 csv 文件,然后让用户将文件保存在本地。因为我以前没有这样做过,所以我开始四处寻找如何做到这一点,并且基本上遇到了自定义视图引擎和自定义操作结果。
我现在的问题是这些有什么好处/坏处?首选的方式是什么?
CSV 文件基本上只包含标题和几千行的数据(最多约 15 列/字段)。所以真的没什么特别的。
我有一个场景,用户可以选择单击“下载”按钮,我应该创建一个包含历史数据的 csv 文件,然后让用户将文件保存在本地。因为我以前没有这样做过,所以我开始四处寻找如何做到这一点,并且基本上遇到了自定义视图引擎和自定义操作结果。
我现在的问题是这些有什么好处/坏处?首选的方式是什么?
CSV 文件基本上只包含标题和几千行的数据(最多约 15 列/字段)。所以真的没什么特别的。
我可能会选择自定义操作结果(我的示例中的实际序列化是使用FileHelpers完成的):
public class CsvResult<T> : ActionResult
{
public IEnumerable<T> Records { get; private set; }
public CsvResult(IEnumerable<T> records)
{
Records = records;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.ContentType = "text/csv";
var engine = new FileHelperEngine(typeof(T));
engine.WriteStream(response.Output, Records);
}
}
[DelimitedRecord(",")]
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var customers = new[]
{
new Customer { Id = 1, Name = "customer 1" },
new Customer { Id = 2, Name = "customer 2" },
};
return new CsvResult<Customer>(customers);
}
}
你甚至可以通过使用扩展方法来美化这个返回语句(在这种情况下泛型是丑陋和多余的):
public static class ControllerExtensions
{
public static ActionResult Csv<T>(this Controller controller, IEnumerable<T> records)
{
return new CsvResult<T>(records);
}
}
然后简单地说:
public ActionResult Index()
{
var customers = new[]
{
new Customer { Id = 1, Name = "customer 1" },
new Customer { Id = 2, Name = "customer 2" },
};
return this.Csv(customers);
}