दिलचस्प पोस्ट
Z- सूचकांक सापेक्ष या पूर्ण? IOS8 इंटरएक्टिव सूचना को कैसे कार्यान्वित करें I डीडीडी में सभी स्तरों पर वर्तमान उपयोगकर्ता जानकारी कैसे पारित करें एक लूप के अंदर या बाहर चर को घोषित करना जावा: स्विंग पुस्तकालय और थ्रेड सुरक्षा java.rmi.NoSuchObjectException: तालिका में ऐसा कोई ऑब्जेक्ट नहीं है एंड्रॉइड – साझा वरीयताओं के साथ तारों को संग्रहित करना / पुनर्प्राप्त करना IIS में एक जावा वेब अनुप्रयोग चला रहा है मैं एक 2 डी स्ट्रिंग सरणी कैसे घोषित करूं? एनजी-क्लास का उपयोग कर अंगुल्यजेएस टॉगल क्लास Google मानचित्र एपीआई v3: मैं मार्कर आइकन कैसे गतिशील रूप से बदलूं? Lat / lon + किमी दूरी के साथ काम करने के लिए सरल गणना? जावास्क्रिप्ट चेतावनी फ़ायरफ़ॉक्स 6 में काम नहीं कर रहा है उत्तर के बजाय उत्तर के साथ उत्तर। क्या स्विफ्ट प्रोग्राम में ऑटोोरियलेपूल का उपयोग करना आवश्यक है?

ASP.NET वेब एपीआई में नियंत्रक से बाइनरी फ़ाइल रिटर्निंग

मैं एएसपी.नेट एमवीसी के नए वेबएपीआई का उपयोग करते हुए एक वेब सेवा पर काम कर रहा हूं जो कि बाइनरी फाइलों को पूरा करेगा, ज्यादातर .cab और .exe फ़ाइलें

निम्न नियंत्रक विधि काम करती है, जिसका अर्थ है कि यह एक फ़ाइल देता है, लेकिन यह सामग्री प्रकार को application/json :

 public HttpResponseMessage<Stream> Post(string version, string environment, string filetype) { var path = @"C:\Temp\test.exe"; var stream = new FileStream(path, FileMode.Open); return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream")); } 

क्या ऐसा करने के लिए इससे अच्छा तरीका है?

Solutions Collecting From Web of "ASP.NET वेब एपीआई में नियंत्रक से बाइनरी फ़ाइल रिटर्निंग"

एक सरल HttpResponseMessage का उपयोग करके इसकी Content प्रॉपर्टी को StreamContent सेट करें:

 // using System.IO; // using System.Net.Http; // using System.Net.Http.Headers; public HttpResponseMessage Post(string version, string environment, string filetype) { var path = @"C:\Temp\test.exe"; HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); var stream = new FileStream(path, FileMode.Open, FileAccess.Read); result.Content = new StreamContent(stream); result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return result; } 

उपयोग की गई stream बारे में ध्यान देने वाली कुछ चीजें:

  • आपको stream.Dispose() कॉल नहीं करना चाहिए। stream.Dispose() , क्योंकि वेब एपीआई अभी भी इसे एक्सेस करने में सक्षम होने की जरूरत है, जब वह ग्राहक को वापस डेटा भेजने के लिए नियंत्रक विधि के result को संसाधित करता है। इसलिए, का उपयोग नहीं using (var stream = …) ब्लॉक वेब एपीआई आपके लिए स्ट्रीम का निपटान करेगा

  • सुनिश्चित करें कि धारा की वर्तमान स्थिति 0 पर सेट है (अर्थात स्ट्रीम के डेटा की शुरुआत)। उपरोक्त उदाहरण में, यह दिया गया है क्योंकि आपने केवल फ़ाइल खोल दी है। हालांकि, अन्य परिदृश्यों में (जैसे जब आप पहले stream.Seek(0, SeekOrigin.Begin); को कुछ बाइनरी डेटा लिखते हैं), तो सुनिश्चित करें कि stream.Seek(0, SeekOrigin.Begin); या stream.Position = 0; सेट करें। stream.Position = 0;

  • फ़ाइल धाराओं के साथ, स्पष्ट रूप से FileAccess.Read निर्दिष्ट FileAccess.Read अनुमति FileAccess.Read वेब सर्वर पर एक्सेस राइट्स के मुद्दों को रोकने में मदद कर सकता है; IIS अनुप्रयोग पूल खातों को अक्सर wwwroot के लिए केवल पढ़ने / सूची / निष्पादन के अधिकार का अधिकार दिया जाता है।

वेब एपीआई 2 के लिए , आप IHttpActionResult को लागू कर सकते हैं। ये मेरा:

 class FileResult : IHttpActionResult { private readonly string _filePath; private readonly string _contentType; public FileResult(string filePath, string contentType = null) { if (filePath == null) throw new ArgumentNullException("filePath"); _filePath = filePath; _contentType = contentType; } public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead(_filePath)) }; var contentType = _contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(_filePath)); response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); return Task.FromResult(response); } } 

तो आपके नियंत्रक में ऐसा कुछ:

 [Route("Images/{*imagePath}")] public IHttpActionResult GetImage(string imagePath) { var serverPath = Path.Combine(_rootPath, imagePath); var fileInfo = new FileInfo(serverPath); return !fileInfo.Exists ? (IHttpActionResult) NotFound() : new FileResult(fileInfo.FullName); } 

और यहां एक तरीका है जिससे आप आईआईएस को विस्तार से अनुरोधों को अनदेखा करने के लिए कह सकते हैं ताकि अनुरोध को नियंत्रक के पास बनाया जा सके:

 <!-- web.config --> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> 

जबकि सुझाए गए समाधान ठीक काम करता है, नियंत्रक से एक बाइट सरणी वापस करने का एक और तरीका है, प्रतिक्रिया स्ट्रीम के साथ ठीक से स्वरूपित किया गया है:

  • अनुरोध में, शीर्षक "स्वीकार करें: आवेदन / ऑक्टेट-स्ट्रीम" सेट करें
  • सर्वर-साइड, इस माइम प्रकार का समर्थन करने के लिए एक मीडिया प्रकार फ़ॉर्मेटर जोड़ें।

दुर्भाग्य से, WebApi में "एप्लिकेशन / ओकटैट-स्ट्रीम" के लिए कोई फ़ॉर्मेटर शामिल नहीं है GitHub पर यहां कार्यान्वित किया गया है: BinaryMediaTypeFormatter (यह वेबपिया 2 के लिए काम करने के लिए छोटे बदलाव हैं, विधि हस्ताक्षर बदल गए हैं)

आप इस फ़ॉर्मेटर को अपनी वैश्विक कॉन्फ़िग में जोड़ सकते हैं:

 HttpConfiguration config; // ... config.Formatters.Add(new BinaryMediaTypeFormatter(false)); 

वेब एपीआई अब बाइनरीमाडियाटाइपफ़ॉर्मर का उपयोग कर सकती है यदि अनुरोध सही स्वीकार हेडर निर्दिष्ट करता है।

मैं इस समाधान को पसंद करता हूं क्योंकि एक एक्शन नियंत्रक लौटने वाले बाइट [] परीक्षण के लिए अधिक सहज है। यद्यपि, अन्य समाधान आपको अधिक नियंत्रण की अनुमति देता है यदि आप "एप्लिकेशन / ओकटेट-स्ट्रीम" (उदाहरण के लिए "छवि / जीआईएफ") की तुलना में अन्य सामग्री-प्रकार वापस करना चाहते हैं।

अधिभार जो आप उपयोग कर रहे हैं वह क्रमवारण स्वरूपण की गणना सेट करता है। आपको स्पष्ट रूप से सामग्री प्रकार निर्दिष्ट करने की आवश्यकता है:

 httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 

स्वीकृत उत्तर में विधि का उपयोग करके एक बड़ी फ़ाइल डाउनलोड करते समय एपीआई की समस्या को एक से अधिक बार बुलाया जा रहा है, कृपया सही सिस्टम पर प्रतिक्रिया बफरिंग सेट करें। Web.HttpContext.Current.Response.Buffer = true;

यह सुनिश्चित करता है कि क्लाइंट को भेजे जाने से पहले संपूर्ण द्विआधारी सामग्री को सर्वर साइड पर बफ़र दिया जाता है। अन्यथा आप देखेंगे कि कई अनुरोध नियंत्रक को भेजे जा रहे हैं और यदि आप इसे ठीक से नहीं संभालते हैं, तो फ़ाइल दूषित हो जाएगी।

तुम कोशिश कर सकते हो

 httpResponseMessage.Content.Headers.Add("Content-Type", "application/octet-stream");