2013-01-07 67 views
13

我已經創建了一個行動返回一個強類型對象的ASP.NET的Web API控制器,如下:變化響應頭對的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的」(例如有人試圖從他或她的Web瀏覽器訪問API),響應類型爲「text/HTML「而不是」application/xml「。我想覆蓋響應類型,以便用戶獲得「application/xml」而不是「text/html」的響應。

我不能在ApiController類型中獲取對常規MVC控制器上的「Response」屬性的訪問權限,並且我很茫然。如何覆蓋媒體類型格式化程序正在處理的此操作的響應類型?

編輯:樂於助人注意

我嘗試這種以前:

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; 
+3

ContentType不是響應頭,它是一個有效載荷頭。所以你可以做response.Content.Headers.ContentType = ... –

回答

18

當您在格式化程序中寫入流時,標頭已經發送。

你可以這樣做:

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

太棒了!有效!然而...它不是這樣的: var response = Request.CreateResponse (HttpStatusCode.Accepted,device); \t \t \t response.Headers.Remove(「Content-Type」); \t \t \t response.Headers.Add(「Content-Type」,「application/xml; charset = utf-8」); \t \t \t return response; 我必須按照你所說的方式來設置Content屬性。謝謝!! –

+0

跟進問題。是否可以在格式化程序中更改文件名,以便文件名是特定於每個請求的,而不是通常設置爲「ebook.mobi」? –

相關問題