【问题标题】:Change Response Headers on Media Type Formatter for ASP.NET Web API更改 ASP.NET Web API 的媒体类型格式化程序的响应标头
【发布时间】:2013-01-07 19:10:08
【问题描述】:

我创建了一个 ASP.NET Web API 控制器,它在操作上返回一个强类型对象,如下所示:

// GET api/iosdevices/5
public iOSDevice Get(string id) {
  return new iOSDevice();
}

我创建了一个 BufferedMediaTypeFormatter 来处理 iOSDevice 类型:

public class iOSDeviceXmlFormatter : BufferedMediaTypeFormatter
{
    public iOSDeviceXmlFormatter() {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
    }

    public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content) {
        content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
        iOSDevice device = (iOSDevice)value;
        using (XmlWriter writer = XmlWriter.Create(writeStream)) {
            writer.WriteStartElement("iOSDevice");
            if (device.identifierForVendor != Guid.Empty) {
                writer.WriteElementString("identifierForVendor", device.identifierForVendor.ToString());
                writer.WriteElementString("userInterfaceIdiom", device.userInterfaceIdiom);
                writer.WriteElementString("systemName", device.systemName);
                writer.WriteElementString("systemVersion", device.systemVersion);
                writer.WriteElementString("model", device.model);
            }
            writer.WriteEndElement();
        }
        writeStream.Close();
    }
}

我的问题是当我捕获类型“text/html”(例如,有人试图从他或她的网络浏览器访问 API)时,响应类型是“text/html”而不是“application/xml”。我想覆盖响应类型,以便用户获得“application/xml”而不是“text/html”的响应。

我无法在 ApiController 类型中访问常规 MVC 控制器上的“响应”属性,我不知所措。如何覆盖媒体类型格式化程序正在处理的此操作的响应类型?

编辑:有用的说明

我之前尝试过这个:

var response = Request.CreateResponse<iOSDevice>(HttpStatusCode.Accepted, device);
response.Headers.Remove("Content-Type");
response.Headers.Add("Content-Type", "application/xml; charset=utf-8");
return response;

它声称我“滥用”了标题。

但是当我使用下面 Filip 的直接设置 Content 的示例时,它起作用了!

var response = Request.CreateResponse();
response.Content = new ObjectContent<iOSDevice>(device, new iOSDeviceXmlFormatter());
return response;

【问题讨论】:

  • ContentType 不是响应标头,而是有效负载标头。所以你可以做 response.Content.Headers.ContentType = ...

标签: c# asp.net asp.net-mvc-4 asp.net-web-api mediatypeformatter


【解决方案1】:

当您在格式化程序中写入流时,标头已经发送。

你可以这样做:

    public HttpResponseMessage Get(string id) {
    {
        var value = new iOSDevice();
        var response = Request.CreateResponse();
        response.Content = new ObjectContent(typeof(iOSDevice), value, new iOSDeviceXmlFormatter());
        //set headers on the "response"
        return response;
    }

或者您可以这样做(将此方法添加到您的格式化程序):

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, string mediaType)
    {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/xml");
    }

以下是我如何将 SetDefaultContentHeaders 与自定义格式化程序一起使用的示例: http://www.strathweb.com/2012/09/generate-kindle-mobi-ebooks-with-your-asp-net-web-api/

   public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
   {
      if (CanWriteType(type) && mediaType.MediaType == supportedMediaType)
      {
         headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
         headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
         headers.ContentDisposition.FileName = "ebook.mobi";
      }
      else
      {
         base.SetDefaultContentHeaders(type, headers, mediaType);
      }
   }

【讨论】:

  • 太棒了!有效!但是......它不喜欢这样: var response = Request.CreateResponse(HttpStatusCode.Accepted, device); response.Headers.Remove("内容类型"); response.Headers.Add("Content-Type", "application/xml; charset=utf-8");返回响应;我必须按照您所说的方式设置 Content 属性。谢谢!!
  • 跟进问题。是否可以从格式化程序中更改文件名,以便文件名特定于每个请求,而不是一般设置为“ebook.mobi”?
猜你喜欢
  • 1970-01-01
  • 2013-12-10
  • 2023-03-27
  • 2014-11-16
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 2015-10-15
  • 2013-07-09
相关资源
最近更新 更多