12

ASP.Net Web API プロジェクトに Csv Media Type Formatter を正常に実装しました。結果を Csv 形式で取得できます。ただし、結果のファイル名は拡張子のない「パーツ」です。

理想的には、コントローラーでこのファイル名を設定できるようにしたいのですが、拡張子をグローバルに追加できることは最小限です。

以下は私が見つけた例です

OnGetResponseHeaders をオーバーライドします - 現在のバージョンではオプションとして表示されません。 http://forums.asp.net/t/1782973.aspx/1?Setting+response+and+content+headers+esp+ContentDisposition+inside+a+MediaTypeFormatter

その記事によると、これはうまくいくはずです

public override IEnumerable<KeyValuePair<string, string>> OnGetResponseHeaders(Type objectType, string mediaType, HttpResponseMessage responseMessage)
{
       return new[] { new KeyValuePair<string, string>("Content-Disposition", "attachment; filename=testing.csv") };
}

ただし、Visual Studio は「オーバーライドに適したメソッドはありません」と表示し、それをカスタム Csv Formatter に追加するとコンパイルされません。

コントローラーから HttpMessageResponse を返す - ASP.NET Web API でダウンロード ファイル名を設定する 方法 以下は、このアプローチを機能させる試みです。

public HttpResponseMessage Get(string id)
{
    var response = new HttpResponseMessage();

    if (id == "test")
    {
        var data = GetTestData();
        response.StatusCode = HttpStatusCode.OK;
        response.Content = new StreamContent(data);
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        response.Content.Headers.ContentDisposition.FileName = "testorama.csv";
        return response;
    }

    return null;
}

ここでの問題は、new StreamContent() がストリームを予期していることです。Custom Csv Formatter が作成した現在のストリームを取得する方法はありますか?

要するに、最初に Csv 形式にシリアル化された結果セットのファイル名を設定するにはどうすればよいですか?

解決

ありがとうクラウディオ - それは私を正しい方向に向かわせました. あなたが投稿したものからのいくつかの変更:

  1. カスタム Csv Formatter の BufferedMediaTypeFormatter から派生していましたが、SetDefaultContentHeaders を使用するには、代わりに MediaTypeFormatter から派生する必要がありました。

  2. SetDefaultContentHeaders は、文字列ではなく MediaTypeHeaderValue 型の mediaType パラメータを受け入れます。

最終的なコードは次のとおりです。

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
    base.SetDefaultContentHeaders(type, headers, mediaType);
    headers.Add("Content-Disposition", "attachment; filename=testorama.csv");
}
4

2 に答える 2

15

SetDefaultContentHeadersMediaTypeFormatterのメソッドをオーバーライドする

public override void SetDefaultContentHeaders(
    Type type, HttpContentHeaders headers, string mediaType)
{
    base.SetDefaultContentHeaders(type, headers, mediaType);
    headers.Add("Content-Disposition", "attachment; filename=yourname.csv");
}
于 2012-09-07T21:19:09.827 に答える
7

(少なくとも Web API 2 では) データに基づいてカスタム名を提供するには、GetPerRequestFormatterInstance をオーバーライドする必要があります。そこから、HttpRequestMessage にアクセスできます。

private string FileName { get; set; }

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
    base.SetDefaultContentHeaders(type, headers, mediaType);
    if (!string.IsNullOrEmpty(FileName))
        headers.Add("Content-Disposition", string.Format("attachment; filename={0}", FileName));
}

public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
    // We aren't setting the name, so just return the current instance.
    if (!request.Properties.ContainsKey("filename")) return this;

    var formatter = new CsvFormatter();
    var fileName = request.Properties["filename"] as string;
    formatter.FileName = string.Format("{0}.csv", fileName);
    return formatter;
}

次に、コントローラーアクションで、次のようにファイル名を設定できます...

if (!Request.Properties.ContainsKey("filename"))
    Request.Properties.Add("filename", "MyFile.{ext}");

ファイル名を必要とする追加のフォーマッターを追加する場合に備えて、{ext} を使用します。理論的には、他の形式をサポートするために変更する必要があるのは拡張子だけです。

于 2014-03-12T01:40:31.520 に答える