Writing to Output Stream from Action

前端 未结 5 726
悲&欢浪女
悲&欢浪女 2020-11-29 04:13

For some strange reasons, I want to write HTML directly to the Response stream from a controller action. (I understand MVC separation, but this is a special case.)

C

5条回答
  •  鱼传尺愫
    2020-11-29 04:43

    I used a class derived from FileResult to achieve this using normal MVC pattern:

    /// 
    /// MVC action result that generates the file content using a delegate that writes the content directly to the output stream.
    /// 
    public class FileGeneratingResult : FileResult
    {
        /// 
        /// The delegate that will generate the file content.
        /// 
        private readonly Action content;
    
        private readonly bool bufferOutput;
    
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Name of the file.
        /// Type of the content.
        /// Delegate with Stream parameter. This is the stream to which content should be written.
        /// use output buffering. Set to false for large files to prevent OutOfMemoryException.
        public FileGeneratingResult(string fileName, string contentType, Action content,bool bufferOutput=true)
            : base(contentType)
        {
            if (content == null)
                throw new ArgumentNullException("content");
    
            this.content = content;
            this.bufferOutput = bufferOutput;
            FileDownloadName = fileName;
        }
    
        /// 
        /// Writes the file to the response.
        /// 
        /// The response object.
        protected override void WriteFile(System.Web.HttpResponseBase response)
        {
            response.Buffer = bufferOutput;
            content(response.OutputStream);
        }
    }
    

    The controller method would now be like this:

    public ActionResult Export(int id)
    {
        return new FileGeneratingResult(id + ".csv", "text/csv",
            stream => this.GenerateExportFile(id, stream));
    }
    
    public void GenerateExportFile(int id, Stream stream)
    {
        stream.Write(/**/);
    }
    

    Note that if buffering is turned off,

    stream.Write(/**/);
    

    becomes extremely slow. The solution is to use a BufferedStream. Doing so improved performance by approximately 100x in one case. See

    Unbuffered Output Very Slow

提交回复
热议问题