views:

94

answers:

1

Hey! I have a scenario where the user have the option to click the button "download" and I should create a csv file, that contains history data, and then let the user save the file locally. As I haven't done this before, I started to look around for how to do this and basically came across both Custom View Engine, and Custom Action Result.

My question now is what is the benefit/disadvantages with these? What is the preferred way to go?

The CSV file, is basically just containing headers, and data (up to about 15 columns/fields) with a few thousand rows. so nothing special really.

+4  A: 

I would probably go for a custom action result (the actual serialization in my example is done with 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);
    }
}

You could even prettify this return statement (generics are ugly and superfluous in this case) by using an extension method:

public static class ControllerExtensions
{
    public static ActionResult Csv<T>(this Controller controller, IEnumerable<T> records)
    {
        return new CsvResult<T>(records);
    }
}

and then simply:

public ActionResult Index()
{
    var customers = new[]
    {
        new Customer { Id = 1, Name = "customer 1" },
        new Customer { Id = 2, Name = "customer 2" },
    };
    return this.Csv(customers);
}
Darin Dimitrov
looks like a good way to do it. I'll give it a go and see how it ends up. Thanks! :)
MrW