Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recommended way to create an ActionResult with a file extension

I need to create an ActionResult in an ASP.NET MVC application which has a .csv filetype.

I will provide a 'do not call' email list to my marketing partners and i want it to have a .csv extension in the filetype. Then it'll automatically open in Excel.

 http://www.example.com/mailinglist/donotemaillist.csv?password=12334

I have successfully done this as follows, but I want to make sure this is the absolute best and recommended way of doing this.

    [ActionName("DoNotEmailList.csv")]
    public ContentResult DoNotEmailList(string username, string password)
    {
            return new ContentResult()
            {
                Content = Emails.Aggregate((a,b)=>a+Environment.NewLine + b), 
                ContentType = "text/csv"
            };
    }

This Actionmethod will respond to the above link just fine.

I'm just wondering if there is any likelihood of any unexpected conflict of having the file extension like this with any different version of IIS, any kind of ISAPI filter, or anything else I cant think of now.

I need to be 100% sure because I will be providing this to external partners and don't want to have to change my mind later. I really cant see any issues, but maybe theres something obscure - or another more "MVC" like way of doing this.

like image 781
Simon_Weaver Avatar asked Jun 13 '09 03:06

Simon_Weaver


People also ask

What is ActionResult method?

The ActionResult method works as a return type of any controller method in the MVC. It acts as the base class of Result classes. It is used to return the models to the Views, file streams, and also redirect to the controllers. It is the responsibility of the Controller that connects the component.

Can I write ActionResult Instead of view result?

ActionResult is the best thing if you are returning different types of views. Show activity on this post. ActionResult is an abstract class, and it's base class for ViewResult class. In MVC framework, it uses ActionResult class to reference the object your action method returns.

What is the file extension of a view file ASP NET?

aspx. cs or . aspx. vb extension on them.


2 Answers

I used the FileContentResult action to also do something similar.

public FileContentResult DoNotEmailList(string username, string password)
{
        string csv = Emails.Aggregate((a,b)=>a+Environment.NewLine + b);
        byte[] csvBytes = ASCIIEncoding.ASCII.GetBytes( csv );
        return File(csvBytes, "text/csv", "DoNotEmailList.csv");
}

It will add the content-disposition header for you.

like image 97
Peter Riesz Avatar answered Nov 13 '22 21:11

Peter Riesz


I think your Response MUST contain "Content-Disposition" header in this case. Create custom ActionResult like this:

public class MyCsvResult : ActionResult {

    public string Content {
        get;
        set;
    }

    public Encoding ContentEncoding {
        get;
        set;
    }

    public string Name {
        get;
        set;
    }

    public override void ExecuteResult(ControllerContext context) {
        if (context == null) {
            throw new ArgumentNullException("context");
        }

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = "text/csv";

        if (ContentEncoding != null) {
            response.ContentEncoding = ContentEncoding;
        }

        var fileName = "file.csv";

        if(!String.IsNullOrEmpty(Name)) {
            fileName = Name.Contains('.') ? Name : Name + ".csv";
        }

        response.AddHeader("Content-Disposition",
            String.Format("attachment; filename={0}", fileName));

        if (Content != null) {
            response.Write(Content);
        }
    }
}

And use it in your Action instead of ContentResult:

return new MyCsvResult {
    Content = Emails.Aggregate((a,b) => a + Environment.NewLine + b)
    /* Optional
     * , ContentEncoding = ""
     * , Name = "DoNotEmailList.csv"
     */
};
like image 25
eu-ge-ne Avatar answered Nov 13 '22 21:11

eu-ge-ne