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





asp.net-web-api (6)


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

// 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 = …) ब्लॉक using (var stream = …) उपयोग न करें। वेब एपीआई आपके लिए धारा का निपटान करेगा।

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

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

मैं एएसपी.नेट एमवीसी की नई वेबएपीआई का उपयोग कर एक वेब सेवा पर काम कर रहा हूं जो बाइनरी फाइलों, ज्यादातर .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"));
}

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




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

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

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

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

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

यदि अनुरोध सही स्वीकृति शीर्षलेख निर्दिष्ट करता है तो WebApi को अब BinaryMediaTypeFormatter उपयोग करना चाहिए।

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




वेब एपीआई 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"/>



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

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




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

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



यदि आप सर्वर में अपने एपीआई को सर्वर फ़ैशन में सुरक्षित करना चाहते हैं (2 पैर वाले प्रमाणीकरण के लिए वेबसाइट पर कोई पुनर्निर्देशन नहीं)। आप OAuth2 क्लाइंट प्रमाण-पत्र अनुदान प्रोटोकॉल देख सकते हैं।

https://dev.twitter.com/docs/auth/application-only-auth

मैंने एक लाइब्रेरी विकसित की है जो आपको आसानी से इस तरह के समर्थन को आपके वेबएपीआई में जोड़ने में मदद कर सकती है। आप इसे NuGet पैकेज के रूप में स्थापित कर सकते हैं:

https://nuget.org/packages/OAuth2ClientCredentialsGrant/1.0.0.0

पुस्तकालय लक्ष्य .NET Framework 4.5।

एक बार जब आप अपनी परियोजना में पैकेज जोड़ते हैं, तो यह आपके प्रोजेक्ट की जड़ में एक रीडेमे फ़ाइल तैयार करेगा। आप इस पैकेज को कॉन्फ़िगर / उपयोग करने के तरीके को देखने के लिए उस रीडेमे फ़ाइल को देख सकते हैं।

चीयर्स!





asp.net asp.net-mvc asp.net-web-api