【问题标题】:How to access the underlying object in SetDefaultContentHeaders?如何访问 SetDefaultContentHeaders 中的底层对象?
【发布时间】:2012-09-24 10:55:31
【问题描述】:

我有一个 web api,我在其中返回一个对象。当我使用接受标头“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 中读取它来在测试版中做到这一点,但它已被删除。

【问题讨论】:

    标签: asp.net-web-api


    【解决方案1】:

    您无法在此处获取对象实例。

    格式化程序中您可以访问该对象的唯一位置是WriteToStreamAsync,到那时您无法再修改标头,因为它们已经发送。

    您有两个选择,将文件名保存在控制器中的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);
            }
    

    另一种方法是在管道末端使用委托处理程序: IE。 (当然,当你想反序列化等时你已经过滤掉了):

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

    【讨论】:

    • 确保从 GetPerRequestFormatterInstance 返回一个新实例,否则您将遇到线程问题(单个默认实例将用于所有请求)。
    猜你喜欢
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    相关资源
    最近更新 更多