3

オブジェクトを返す Web API があります。Acceptヘッダー「image/jpg」を使用すると、そのオブジェクトの画像表現が必要になりますが、返されるオブジェクトに基づいてファイル名を設定したいと思います。私は実装しましたが、次のようなBufferedMediaTypeFormatterメソッドでこれを行う必要があると考えました:SetDefaultContentHeaders

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
    base.SetDefaultContentHeaders(type, headers, mediaType);
    var myObject = // How do I get this from the response?
    var contentDispositionHeader = new ContentDispositionHeaderValue("attachment") 
        { FileName = myObject.FileName };
    headers.ContentDisposition = contentDispositionHeader;
}

だから問題は、私がいるときに基になるオブジェクトをどのように取得するのSetDefaultContentHeadersですか? HttpResponseMessageメソッドに渡されたから読み取ることで、ベータ版でそれを行うことができましたが、それは削除されました。

4

1 に答える 1

7

そこでオブジェクトインスタンスを取得することはできません。

フォーマッタでオブジェクトにアクセスできる唯一の場所は、です。WriteToStreamAsyncその時点では、ヘッダーはすでに送信されているため、変更することはできません。

2つのオプションがあります。ファイル名をコントローラーに保存するか、request.Propertiesオーバーライドしてフォーマッターで取得しますGetPerRequestFormatterInstance(前に実行されるためSetDefaultContentHeaders)。次に、この値をで使用できますSetDefaultContentHeaders

//Controller
public Url Get(int id)
        {
            Request.Properties.Add("name", _repo.Get(id).Name);
            return _repo.Get(id);
}

//Formatter
        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {
            //here save the request.Properties["name"] to some local field which you can use later
            return base.GetPerRequestFormatterInstance(type, request, mediaType);
        }

もう1つは、パイプラインの最後で委任ハンドラーを使用することです。つまり、(もちろん、逆シリアル化する場合などにフィルターを適用します):

public class RenameHandler : DelegatingHandler
    {
        protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
            {
                var msg = t.Result;
                var myobj = msg.Content.ReadAsAsync<IMobi>().Result;
                msg.Content.Headers.ContentDisposition.FileName = myobj.Name + ".mobi";

                return msg;
            });
        }
    }
于 2012-09-24T12:58:22.160 に答える