2013-01-23 8 views
18

में एक छवि हैंडलर बनाने के लिए कैसे मैं एक वेब आउटपुट स्ट्रीम में नैन्सीएफएक्स में अपने डेटाबेस से बाइट [] से एक छवि आउटपुट करने के लिए संघर्ष कर रहा हूं। मेरे पास इस बिंदु पर दिखाने के लिए पर्याप्त नमूना कोड पर्याप्त नहीं है। मैं सोच रहा था कि किसी ने इस समस्या का सामना किया है और एक स्निपेट पोस्ट कर सकता है? मैं मूल रूप से बस अपने डेटाबेस में संग्रहीत एक बाइट सरणी से छवि/जेपीईजी वापस करना चाहता हूं और इसे भौतिक फ़ाइल की बजाय वेब पर डाल देना चाहता हूं।नैन्सीएफएक्स

उत्तर

27

के लिए एक अलग निर्माता प्रदान करता है बस @ TheCodeJunkie के जवाब पर बनाने के लिए, आप कर सकते हैं एक "बाइट सरणी प्रतिक्रिया" का निर्माण बहुत आसानी से करें:

public class ByteArrayResponse : Response 
{ 
    /// <summary> 
    /// Byte array response 
    /// </summary> 
    /// <param name="body">Byte array to be the body of the response</param> 
    /// <param name="contentType">Content type to use</param> 
    public ByteArrayResponse(byte[] body, string contentType = null) 
    { 
     this.ContentType = contentType ?? "application/octet-stream"; 

     this.Contents = stream => 
      { 
       using (var writer = new BinaryWriter(stream)) 
       { 
        writer.Write(body); 
       } 
      }; 
    } 
} 

तो फिर तुम उपयोग करने के लिए Response.AsX वाक्यविन्यास यह शीर्ष पर एक सरल विस्तार विधि है चाहते हैं:

public static class Extensions 
{ 
    public static Response FromByteArray(this IResponseFormatter formatter, byte[] body, string contentType = null) 
    { 
     return new ByteArrayResponse(body, contentType); 
    } 
} 

फिर अपने मार्ग में तुम सिर्फ उपयोग कर सकते हैं:

Response.FromByteArray(myImageByteArray, "image/jpeg"); 

आप सामग्री वार्ता के साथ बाइट सरणी का उपयोग करने के लिए एक प्रोसेसर भी जोड़ सकता है, मैंने इसका त्वरित नमूना this gist

+0

समाधान पर विस्तार के लिए बहुत बहुत धन्यवाद, यह वही है जो मुझे चाहिए था। – sethxian

+0

क्या ब्राउजर कैश को अनुरोध के बाइट सरणी प्रतिक्रिया को कैश करने का कोई तरीका है? ताकि हैंडलर एक ही यूआरएल के लिए फिर से काम नहीं करेगा? – Azadrum

+1

यह भयानक है, कि कैश मेमोरी में बाइट्स है। क्या आप सीधे स्ट्रीम नहीं कर सकते (न्यूनतम स्मृति का उपयोग कर)? – Todd

8

नैन्सी से आप एक नया Response ऑब्जेक्ट वापस कर सकते हैं। यह Content संपत्ति प्रकार Action<Stream> की है, ताकि आप केवल एक प्रतिनिधि है कि उस धारा को अपने बाइट सरणी लिखते हैं बना सकते हैं

var r = new Response(); 
r.Content = s => { 
    //write to s 
}; 

मत भूलना, ContentType संपत्ति (आप MimeTypes.GetMimeType इस्तेमाल कर सकते हैं की स्थापना की और यह नाम पारित करने के लिए सहित विस्तार) वहाँ भी है एक StreamResponse, कि Response से विरासत और (थोड़ा अच्छे वाक्य रचना करते समय अपने मार्ग में return Response.AsStream(..) उपयोग कर सकते हैं .. बस वाक्य रचना कैंडी)

+0

मदद के लिए धन्यवाद, मुझे आपके द्वारा प्रस्तुत वैकल्पिक समाधान पसंद हैं। – sethxian

+0

ऐसा लगता है कि संपत्ति का नाम बदलकर 'सामग्री 'हो गया है। – TrueWill

11

में जोड़ा है आपका नियंत्रक, प्रतिक्रिया प्रतिक्रिया। छवि के बाइट्स की धारा के साथ फ्रॉमस्ट्रीम। इसे नॅन्सी के पुराने संस्करणों में एस्स्ट्रीम कहा जाता था।

Get["/Image/{ImageID}"] = parameters => 
{ 
    string ContentType = "image/jpg"; 
    Stream stream = // get a stream from the image. 

    return Response.FromStream(stream, ContentType); 
}; 
+0

आप इस एपीआई के साथ स्रोत स्ट्रीम को कैसे बंद करना चाहते हैं? भयानक। – Todd

+2

स्रोत स्ट्रीम को स्वचालित रूप से बाद में डिस्पोजेक्ट किया जाता है -https: //github.com/NancyFx/Nancy/issues/786 – Todd

+1

आपको यह सुनिश्चित करना होगा कि स्ट्रीम स्थिति स्ट्रीम की शुरुआत में सेट हो: 'stream.Seek (0, SeekOrigin.Begin) ', क्योंकि' FromStream 'आपके लिए यह नहीं करेगा। –