创建带有文件扩展名的 ActionResult 的推荐方法

发布于 2024-07-25 01:53:07 字数 838 浏览 7 评论 0原文

我需要在具有 .csv 文件类型的 ASP.NET MVC 应用程序中创建 ActionResult。

我将向我的营销合作伙伴提供“请勿致电”电子邮件列表,并且我希望其文件类型具有 .csv 扩展名。 然后它会自动在 Excel 中打开。

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

我已成功完成此操作,如下所示,但我想确保这是绝对最佳且推荐的方法。

    [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"
            };
    }

这个 Actionmethod 将很好地响应上面的链接。

我只是想知道这样的文件扩展名是否可能与任何不同版本的 IIS、任何类型的 ISAPI 过滤器或我现在无法想到的任何其他内容发生意外冲突。

我需要 100% 确定,因为我会将其提供给外部合作伙伴,并且不想稍后改变主意。 我真的看不到任何问题,但也许有一些模糊的东西 - 或者另一种更像“MVC”的方式来做到这一点。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

感悟人生的甜 2024-08-01 01:53:07

我使用 FileContentResult 操作也做了类似的事情。

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");
}

它将为您添加内容处置标头。

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.

叹梦 2024-08-01 01:53:07

在这种情况下,我认为您的响应必须包含“Content-Disposition”标头。 像这样创建自定义 ActionResult:

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);
        }
    }
}

并在 Action 中使用它而不是 ContentResult:

return new MyCsvResult {
    Content = Emails.Aggregate((a,b) => a + Environment.NewLine + b)
    /* Optional
     * , ContentEncoding = ""
     * , Name = "DoNotEmailList.csv"
     */
};

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"
     */
};
无人接听 2024-08-01 01:53:07

这就是我正在做类似事情的方式。 我将其视为下载:

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

这应该在浏览器中显示为具有给定文件名的文件下载。

不过,我想不出你的不起作用的原因。

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.

青瓷清茶倾城歌 2024-08-01 01:53:07

您接受的答案已经足够好了,但它在输出时将输出内容保留在内存中。 如果它生成的文件相当大怎么办? 例如,当您转储 SQL 表的内容时。 您的应用程序可能会耗尽内存。 在这种情况下,您真正​​想要的是使用 FileStreamResult。 将数据输入流的一种方法是使用管道,正如我在此处所述

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文