2011-12-23 14 views
10

हमारे पास एसक्यूएल डेटाबेस में संग्रहीत कुछ फ़ाइलें हैं। एएसपी.नेट एमवीसी 3 फॉर्म पर, हम 2 लिंक प्रदर्शित करते हैं:एमवीसी 3 FileContentResult के साथ डुप्लिकेट सामग्री-स्वभाव हेडर से कैसे बचें?

इस फ़ाइल को देखें | इस फ़ाइल को डाउनलोड करें

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

[ActionName("display-file")] 
public virtual ActionResult DisplayFile (Guid fileId, string fileName) 
{ 
    var file = _repos.GetFileInfo(fileId); 
    if (file != null) 
    { 
     Response.AddHeader("Content-Disposition", 
      string.Format("inline; filename={0}", file.Name)); 
     return File(file.Content, file.MimeType, file.Name); 
    } 
} 

[ActionName("download-file")] 
public virtual ActionResult DownloadFile (Guid fileId, string fileName) 
{ 
    var file = _repos.GetFileInfo(fileId); 
    if (file != null) 
    { 
     return File(file.Content, file.MimeType, file.Name); 
    } 
} 

यहाँ प्रदर्शन कार्रवाई के लिए ब्राउज़र को भेज दिया 2 हेडर हैं:

Content-Disposition: inline; filename=name-of-my-file.pdf 
Content-Disposition: attachment; filename="name-of-my-file.pdf" 

मैं अपने कस्टम सामग्री-स्वभाव हैडर को बदलने की कोशिश की दोहरे उद्धरण में फ़ाइल नाम रैप करने के लिए, लेकिन यह अभी भी भेजा ब्राउज़र में 2 हेडर। मैंने कस्टम जोड़ने से पहले सामग्री-डिस्पोजिशन हेडर को हटाने का भी प्रयास किया, लेकिन ऐसा लगता है कि FileContentResult लौटाए जाने के बाद अनुलग्नक हेडर जोड़ा जा रहा है।

यह कोड काम करने के लिए उपयोग किया जाता है। मैंने कल सिर्फ एक परीक्षण चलाया और देखा कि यह अब क्रोम या फ़ायरफ़ॉक्स में काम नहीं कर रहा है। यह ब्राउज़र में अपडेट के कारण हो सकता है। आईई 8 और सफारी अभी भी फाइल को सही तरीके से खोलें।

अद्यतन

धन्यवाद फिर से डैरिन, आप सही हैं। हमने वास्तव में another question you answered की वजह से इस दृष्टिकोण का उपयोग किया।

context.MapRoute(null, 
    "path/to/display-file-attachment/{fileId}/{fileName}", 
    new 
    { 
     area = "AreaName", 
     controller = "ControllerName", 
     action = "DisplayFile", 
    } 
); 

पृष्ठ पर हाइपरलिंक के माध्यम से कार्रवाई विधि करने के लिए फ़ाइल नाम से गुजरता है:

कैसे यह अंततः हमारी ओर से हल किया गया था के बारे में एक छोटे से अधिक जानकारी है, हम प्रदर्शन फ़ाइल लिंक के लिए एक कस्टम मार्ग है मार्ग पैरामीटर, इसलिए यह पहले ही यूआरएल का हिस्सा है। इस प्रकार, जब फ़ाइल उपयोगकर्ता इसे डाउनलोड करने का निर्णय लेता है (ब्राउजर पीडीएफ व्यूअर में सेव आइकन पर क्लिक करके) फ़ाइल नाम सिस्टम से मेल खाता है, तो हमें कस्टम सामग्री-स्वभाव शीर्षलेख जोड़ने की आवश्यकता नहीं थी। तो हम बस यह प्रयोग किया है:

[ActionName("display-file")] 
public virtual ActionResult DisplayFile (Guid fileId, string fileName) 
{ 
    var file = _repos.GetFileInfo(fileId); 
    if (file != null) 
    { 
     // no custom content-disposition header, and no 3rd fileName argument 
     return File(file.Content, file.MimeType); 
    } 
} 
+0

फ़ायरफ़ॉक्स और क्रोम वास्तव में सामग्री-विन्यास शीर्षलेख के अपने को संभालने में सख्त हो गए हैं। –

+0

@ जुलियन रेस्के, क्या आप गैर-ASCII वर्णों पर विस्तृत जानकारी देंगे? हमने अभी तक फ़ाइल नामों में यूनिकोड वर्णों के साथ इसका परीक्षण नहीं किया है। – danludwig

+0

गैर-ASCII के लिए सभी ब्राउज़रों में सी-डी में "कार्य" में फ़ाइल नामों में, सर्वर को वर्तमान में उपयोगकर्ता-एजेंट स्नीफिंग करने की आवश्यकता है। Http://greenbytes.de/tech/tc2231/ और http://greenbytes.de/tech/webdav/rfc6266.html देखें। मुझे संदेह है कि एएसपीनेट को यह अधिकार मिलता है, लेकिन मुझे अन्यथा पता लगाना अच्छा लगेगा। –

उत्तर

24

जब आप अधिभार File(byte[] contents, string mimeType, string fileName) एक Content-Disposition हैडर स्वचालित रूप से, attachment साथ प्रतिक्रिया में जोड़ा जाता है, तो आप इसे दूसरी बार जोड़ने की जरूरत नहीं है का उपयोग करें। inline के लिए आप निम्नलिखित अधिभार File(byte[] contents, string mimeType) इस्तेमाल कर सकते हैं और मैन्युअल रूप से Content-Disposition शीर्ष लेख:

[ActionName("display-file")] 
public virtual ActionResult DisplayFile(Guid fileId) 
{ 
    var file = _repos.GetFileInfo(fileId); 
    var cd = new ContentDisposition 
    { 
     Inline = true, 
     FileName = file.Name 
    }; 
    Response.AddHeader("Content-Disposition", cd.ToString()); 
    return File(file.Content, file.MimeType); 
} 

[ActionName("download-file")] 
public virtual ActionResult DownloadFile(Guid fileId) 
{ 
    var file = _repos.GetFileInfo(fileId); 
    return File(file.Content, file.MimeType, file.Name); 
} 
+0

आपने मुझे इसे हरा दिया, मैं एक समान उत्तर पोस्ट करने वाला था। तीसरी फ़ाइल नामकरण तर्क तर्क काम करता है। हालांकि, हमारे मामले में सामग्री-स्वभाव को जोड़ने की आवश्यकता नहीं है। बस 'वापसी फ़ाइल (फ़ाइल। सामग्री, फ़ाइल। माइम टाइप);' काम करता है, क्योंकि फ़ाइल नाम कस्टम मार्ग से लिया गया है। – danludwig

+0

खैर, उम्मीद है कि ढांचा गैर-ASCII वर्णों के संबंध में सही काम करता है ... –

+0

@ जुलिएन रेस्के, गैर-ASCII वर्ण क्या हैं? ढांचा उनके बारे में कुछ भी नहीं करता है। यह आप पर निर्भर करता है। यदि आप फ़ाइल नामों में गैर-ASCII वर्णों के बारे में बात कर रहे हैं, तो हाँ, यह भयानक पिटा है। लेकिन यह ऐसा कुछ नहीं है जिसे आप ढांचे की मदद करने के लिए उम्मीद कर सकते हैं। यह सिर्फ कुछ ऐसा है जो अलग-अलग ब्राउज़रों द्वारा अलग-अलग लागू किया जाता है। संक्षेप में यह कुछ ऐसा नहीं है जिसका उपयोग नहीं किया जाना चाहिए :-) –