13

Utworzono kontroler API web ASP.NET że wraca silnie typami obiektu na działania w następujący sposób:Zmiany nagłówków odpowiedzi na typ nośnika Formatter dla ASP.NET Web API

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

Stworzyłem BufferedMediaTypeFormatter obsłużyć iOSDevice typ:

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

Mój problem jest kiedy złapię typu „text/html” (np ktoś próbuje uzyskać dostęp do API z jego przeglądarka internetowa), rodzaj odpowiedzi jest „text/html "zamiast" application/xml ". Chcę zastąpić typ odpowiedzi, aby użytkownik otrzymał odpowiedź "application/xml" zamiast "text/html".

Nie mogę w typie ApiController uzyskać dostępu do właściwości "Odpowiedź", która jest na zwykłych kontrolerach MVC i jestem zagubiony. W jaki sposób przesłonić typ odpowiedzi dla tego działania, które jest obsługiwane przez formater typu nośnika?

EDIT: pomocne UWAGA

Próbowałam to wcześniej:

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; 

I twierdził, że był "nadużywania" nagłówki.

Ale kiedy użyłem przykładu Filipa poniżej, aby ustawić zawartość bezpośrednio, zadziałało!

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

ContentType nie jest odpowiedzią nagłówek, to nagłówek ładunku. Więc możesz zrobić odpowiedź.Content.Headers.ContentType = ... –

Odpowiedz

18

Podczas pisania do strumienia w programie formatującym, nagłówki zostały już wysłane.

Można to zrobić:

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

lub można to zrobić (dodaj tę metodę do swojego formater):

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

Oto przykład, w jaki sposób użyłem SetDefaultContentHeaders ze zwyczajem formater: 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

Genialny! Zadziałało! Jednak ... to się nie podobało: var response = Request.CreateResponse (HttpStatusCode.Accepted, device); \t \t \t response.Headers.Remove ("Typ zawartości"); \t \t \t response.Headers.Add ("Typ zawartości", "application/xml; charset = utf-8"); \t \t \t odpowiedź zwrotna; Musiałem zrobić to tak, jak powiedziałeś, ustawiając właściwość Zawartość. Dziękuję Ci!! –

+0

Kolejne pytanie. Czy możliwa jest zmiana nazwy pliku z poziomu formatyzatora, więc nazwa pliku jest specyficzna dla każdego żądania, a nie ustawiana ogólnie jako "ebook.mobi"? –

Powiązane problemy