2013-01-07 18 views
13

मुझे लगता है कि एक कार्रवाई पर एक जोरदार टाइप किया वस्तु लौटा रहा है एक ASP.NET वेब एपीआई नियंत्रक बनाया है, इस प्रकार है:बदलें प्रतिक्रिया हेडर पर ASP.NET वेब एपीआई के लिए मीडिया प्रकार फ़ॉर्मेटर

// 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 एक्सेस करने का प्रयास करता है) कर रहा है/एचटीएमएल "के बजाय" एप्लिकेशन/एक्सएमएल "। मैं प्रतिक्रिया प्रकार को ओवरराइड करना चाहता हूं ताकि उपयोगकर्ता को "टेक्स्ट/एचटीएमएल" के बजाय "एप्लिकेशन/एक्सएमएल" प्रतिक्रिया मिल सके।

मैं एपीकंट्रोलर प्रकार में नियमित एमवीसी नियंत्रकों पर "प्रतिक्रिया" संपत्ति तक पहुंच प्राप्त नहीं कर सकता हूं और मुझे नुकसान हुआ है। मैं इस प्रकार की प्रतिक्रिया के लिए प्रतिक्रिया प्रकार को कैसे ओवरराइड कर सकता हूं जिसे मीडिया प्रकार फ़ॉर्मेटर द्वारा नियंत्रित किया जा रहा है?

संपादित करें: उपयोगी नोट

मैं इस पहले से कोशिश कर रहा था:

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; 

और यह दावा किया मैं गया था "दुरुपयोग" हेडर।

लेकिन जब मैंने सीधे सामग्री सेट करने के नीचे फिलिप का उदाहरण इस्तेमाल किया, तो यह काम किया!

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

सामग्री प्रकार प्रतिक्रिया नहीं है हेडर, यह एक पेलोड हेडर है। तो आप प्रतिक्रिया कर सकते हैं। सामग्री। हेडर। सामग्री टिप = ... –

उत्तर

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 प्रतिक्रिया = अनुरोध। क्रेट रेस्पॉन्स (एचटीपीस्टैटस कोड। स्वीकृत, डिवाइस); \t \t \t प्रतिक्रिया। हेडर। हटाएं ("सामग्री-प्रकार"); \t \t \t प्रतिक्रिया। हेडर। जोड़ें ("सामग्री-प्रकार", "एप्लिकेशन/xml; charset = utf-8"); \t \t \t वापसी प्रतिक्रिया; मुझे सामग्री प्रॉपर्टी सेट करने के साथ आपको यह तरीका करना था। धन्यवाद!! –

+0

प्रश्न का पालन करें। क्या फ़ाइल नाम को फ़ॉर्मेटर के भीतर से बदलना संभव है, ताकि फ़ाइल नाम प्रत्येक अनुरोध के लिए विशिष्ट हो, बजाय आम तौर पर "ebook.mobi" पर सेट किया जा सके? –