Recommended way to create an ActionResult with a file extension

前端 未结 4 1447
余生分开走
余生分开走 2020-12-24 02:58

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

相关标签:
4条回答
  • 2020-12-24 03:32

    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"
         */
    };
    
    0 讨论(0)
  • 2020-12-24 03:38

    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.

    0 讨论(0)
  • 2020-12-24 03:50

    The answer you accepted is good enough, but it keeps the content of the output in memory as it outputs it. What if the file it generates is rather large? For example, when you dump a contents of the SQL table. Your application could run out of memory. What you do want in this case is to use FileStreamResult. One way to feed the data into the stream could be using pipe, as I described here

    0 讨论(0)
  • 2020-12-24 03:52

    This is how I'm doing something similar. I'm treating it as a download:

    var disposition = String.Format(
      "attachment;filename=\"{0}.csv\"", this.Model.Name);
    Response.AddHeader("content-disposition", disposition);
    

    This should show up in the browser as a file download with the given filename.

    I can't think of a reason why yours wouldn't work, though.

    0 讨论(0)
提交回复
热议问题