2010-07-08 8 views
51

क्या किसी विशिष्ट नाम वाले ब्राउज़र के भीतर ASP.NET MVC FileContentResult का उपयोग कर फ़ाइल स्ट्रीम करने का कोई तरीका है?किसी नाम के साथ ब्राउज़र में ASP.NET MVC FileContentResult का उपयोग कर स्ट्रीम फ़ाइल?

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

मैं इस परिदृश्य है:

byte[] contents = DocumentServiceInstance.CreateDocument(orderId, EPrintTypes.Quote); 
result = File(contents, "application/pdf", String.Format("Quote{0}.pdf", orderId)); 

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

यदि मैं सिर्फ फ़ाइलपैथआरसल्ट का उपयोग करता हूं, तो यह फ़ाइल को ब्राउज़र विंडो में दिखाता है, लेकिन फिर जब मैं फ़ाइल को पीडीएफ में सहेजने के लिए "सहेजें" बटन पर क्लिक करता हूं, तो यह मुझे फ़ाइल का नाम के रूप में एक्शन नाम दिखाता है।

क्या किसी को इसका सामना करना पड़ा है?

उत्तर

11

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

आप इस URL पर आगे पढ़ सकते हैं: Securly download file inside browser with correct filename

यह मैं एक विचार दिया था, मैं बस अपना यूआरएल मार्ग है जो URL बदलने और फ़ाइल के नाम से यह खत्म हो जाएगा बनाया मैं फ़ाइल देना चाहता था । तो उदाहरण के लिए मेरे मूल नियंत्रक कॉल में मुद्रित होने के आदेश के ऑर्डर आईडी को पास करने का समावेश था। मैं फ़ाइल नाम प्रारूप {0} .pdf का होना चाहता था जहां {0} ऑर्डर आईडी है। इसी तरह उद्धरण के लिए, मैं उद्धरण {0} .pdf चाहता था।

मेरे नियंत्रक में, मैं बस आगे बढ़ गया और फ़ाइल नाम को स्वीकार करने के लिए एक अतिरिक्त पैरामीटर जोड़ा। मैंने URL नाम में पैरामीटर के रूप में फ़ाइल नाम पारित किया। क्रिया विधि। http://localhost/ShoppingCart/PrintQuote/1054/Quote1054.pdf

 

routes.MapRoute("", "{controller}/{action}/{orderId}/{fileName}", 
       new { controller = "ShoppingCart", action = "PrintQuote" } 
       , new string[] { "x.x.x.Controllers" } 
      ); 
 

यह काफी हल मेरी समस्या:

मैं तो एक नया मार्ग है कि प्रारूप करने के लिए है कि यूआरएल को मैप होगा बनाया। उम्मीद है कि यह किसी की मदद करता है!

Cheerz, अनूप

+0

एक हैक, लेकिन एक बहुत ही प्रभावी हैक! धन्यवाद! –

+0

दुर्भाग्यवश, अभी भी IE के साथ आवश्यक है 11. क्रोम और फ़ायरफ़ॉक्स के साथ आवश्यक नहीं है। –

79
public ActionResult Index() 
{ 
    byte[] contents = FetchPdfBytes(); 
    return File(contents, "application/pdf", "test.pdf"); 
} 

और ब्राउज़र आप Content-Disposition हेडर सेट करना होगा अंदर पीडीएफ खोलने के लिए:

public ActionResult Index() 
{ 
    byte[] contents = FetchPdfBytes(); 
    Response.AddHeader("Content-Disposition", "inline; filename=test.pdf"); 
    return File(contents, "application/pdf"); 
} 
+0

हैलो डारिन, यह मेरे द्वारा उल्लेखित एक खुला/बचा संवाद खोलता है। मैं चाहता हूं कि यह ब्राउज़र के अंदर एक फाइल खोलें। –

+1

@Anup, कृपया मेरा अपडेट देखें। –

+0

क्या हमारे पास "एप्लिकेशन/पीडीएफ" की बजाय सामान्य मूल्य हो सकता है? जैसे कि मुझे यकीन है कि फ़ाइल का प्रकार नहीं है। यह वह उपयोगकर्ता है जिसने इसे अपलोड किया पहला स्थान – neebz

38

वास्तव में, पूरी तरह से सबसे आसान तरीका निम्न करने के लिए है ...

byte[] content = your_byte[]; 

FileContentResult result = new FileContentResult(content, "application/octet-stream") 
       { 
        FileDownloadName = "your_file_name" 
       }; 

return result; 
+1

नाह! .. मेरा जवाब सबसे आसान है, http://stackoverflow.com/a/29392930/193634 –

+2

मैं सहमत होगा कि मूल प्रश्न में बाइट सरणी शामिल नहीं है। – azarc3

0
public FileContentResult GetImage(int productId) { 
    Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId); 
    if (prod != null) { 
     return File(prod.ImageData, prod.ImageMimeType); 
     } else { 
     return null; 
    } 
} 
5

पिछला उत्तर सही हैं: लाइन जोड़ने ...

Response.AddHeader("Content-Disposition", "inline; filename=[filename]"); 

... ब्राउज़र पर कई सामग्री-विस्थापन शीर्षलेख भेजे जाएंगे।ऐसा होता है यदि आप इसे फ़ाइल नाम से आपूर्ति करते हैं तो बी/सी FileContentResult आंतरिक रूप से हेडर लागू होता है। एक वैकल्पिक, और बहुत सरल, समाधान केवल FileContentResult का उप-वर्ग बनाना है और इसकी ExecuteResult() विधि ओवरराइड करना है। यहाँ एक उदाहरण है कि System.Net.Mime.ContentDisposition वर्ग (एक ही आंतरिक FileContentResult कार्यान्वयन में इस्तेमाल वस्तु) का एक उदाहरण को दर्शाता है और नया वर्ग में यह गुजरता है:

public class FileContentResultWithContentDisposition : FileContentResult 
{ 
    private const string ContentDispositionHeaderName = "Content-Disposition"; 

    public FileContentResultWithContentDisposition(byte[] fileContents, string contentType, ContentDisposition contentDisposition) 
     : base(fileContents, contentType) 
    { 
     // check for null or invalid ctor arguments 
     ContentDisposition = contentDisposition; 
    } 

    public ContentDisposition ContentDisposition { get; private set; } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     // check for null or invalid method argument 
     ContentDisposition.FileName = ContentDisposition.FileName ?? FileDownloadName; 
     var response = context.HttpContext.Response; 
     response.ContentType = ContentType; 
     response.AddHeader(ContentDispositionHeaderName, ContentDisposition.ToString()); 
     WriteFile(response); 
    } 
} 

अपने Controller में, या एक आधार Controller में, आप लिख सकते हैं एक सरल सहायक एक FileContentResultWithContentDisposition का दृष्टांत और फिर, अपनी कार्रवाई विधि से इसे कहते तो जैसे करने के लिए:

protected virtual FileContentResult File(byte[] fileContents, string contentType, ContentDisposition contentDisposition) 
{ 
    var result = new FileContentResultWithContentDisposition(fileContents, contentType, contentDisposition); 
    return result; 
} 

public ActionResult Report() 
{ 
    // get a reference to your document or file 
    // in this example the report exposes properties for 
    // the byte[] data and content-type of the document 
    var report = ... 
    return File(report.Data, report.ContentType, new ContentDisposition { 
     Inline = true, 
     FileName = report.FileName 
    }); 
} 

अब फ़ाइल फ़ाइल नाम के साथ ब्राउज़र को चुनने के लिए और का सामग्री-स्वभाव हेडर के साथ भेजा जाएगा " इनलाइन; फ़ाइल नाम = [फाइलनाम] "।

मुझे उम्मीद है कि इससे मदद मिलती है!

+0

मैं पहले 'कंटेंट डिस्पोजिशन' सहायक वर्ग के रास्ते पर गया हूं, यह समझने के लिए कि एमवीसी आंतरिक रूप से इसका उपयोग कर रहा था, लेकिन कुछ हैक के साथ utf-8 फ़ाइल नाम को सही तरीके से संभालने के लिए। 'ContentDisposition' सहायक वर्ग यह गलत करता है जब इसे utf-8 मानों को एन्कोड करना होता है। अधिक जानकारी के लिए, [मेरी टिप्पणी यहां] देखें (/ प्रश्न/1012437/सामग्री-विवाद-इन-ए-एचटी-प्रतिक्रिया-हेडर/22221217 # टिप्पणी 57484455_22221217)। –

4

ASP.NET MVC का उपयोग कर ब्राउज़र में एक फ़ाइल स्ट्रीम करने के लिए पूर्ण सबसे आसान तरीका यह है:

public ActionResult DownloadFile() { 
    return File(@"c:\path\to\somefile.pdf", "application/pdf", "Your Filename.pdf"); 
} 

इस विधि @ azarc3 ने सुझाव दिया की तुलना में आसान है क्योंकि आप भी बाइट्स पढ़ने की जरूरत नहीं है ।

क्रेडिट को जाता है: http://prideparrot.com/blog/archive/2012/8/uploading_and_returning_files#how_to_return_a_file_as_response

** संपादित करें **

जाहिर है मेरी 'जवाब' ओ पी के सवाल के समान है। लेकिन मुझे उस समस्या का सामना नहीं करना पड़ रहा है जो उसके पास है। शायद यह एएसपी.नेट एमवीसी के पुराने संस्करण के साथ एक मुद्दा था?

+0

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

संबंधित मुद्दे