2009-03-02 9 views
13

आपको बता दें कि हम एक नए ActionResult ASP.NET MVC के RC1 संस्करण में FileResult कहा जाता है मिल गया है।कैसे ASP.NET MVC RC1 में FileResult साथ 304 स्थिति लौटाने

इसका उपयोग करके, आपकी क्रिया विधियां गतिशील रूप से ब्राउज़र पर छवि वापस कर सकती हैं। कुछ इस तरह:

public ActionResult DisplayPhoto(int id) 
{ 
    Photo photo = GetPhotoFromDatabase(id); 
    return File(photo.Content, photo.ContentType); 
} 

एचटीएमएल कोड में, हम कुछ इस तरह उपयोग कर सकते हैं:

<img src="http://mysite.com/controller/DisplayPhoto/657"> 

चूंकि छवि गतिशील रूप से दिया जाता है, हम वापस आ धारा कैश करने के लिए कोई तरीका होना चाहिए ताकि हम डॉन डेटाबेस से फिर से छवि को पढ़ने की जरूरत नहीं है। मुझे लगता है कि हम कुछ इस तरह से यह कर सकते हैं, मुझे यकीन है कि नहीं कर रहा हूँ:

Response.StatusCode = 304; 

यह ब्राउज़र आप पहले से ही अपने कैश में छवि है कि बताता है। मुझे नहीं पता कि स्टेटसकोड को 304 पर सेट करने के बाद मेरी एक्शन विधि में क्या लौटना है। क्या मुझे शून्य या कुछ वापस करना चाहिए?

उत्तर

8

FileResult के साथ 304 का उपयोग न करें। the spec से:

304 प्रतिक्रिया एक संदेश-शरीर शामिल नहीं करना चाहिए, और इस तरह हमेशा पहले खाली पंक्ति हेडर फील्ड के बाद इन्हें समाप्त है।

यह स्पष्ट नहीं है कि आप अपने प्रश्न से क्या करने की कोशिश कर रहे हैं। सर्वर को पता नहीं है कि ब्राउजर के कैश में क्या है। ब्राउजर इसका फैसला करता है। यदि आप ब्राउजर को यह बताने की कोशिश कर रहे हैं कि छवि को दोबारा लाने के लिए फिर से प्राप्त न करें, अगर इसकी पहले से कोई प्रतिलिपि है, तो प्रतिक्रिया Cache-Control header सेट करें।

यदि आपको 304 वापस करने की आवश्यकता है, तो इसके बजाय EmptyResult का उपयोग करें।

+0

पहले अनुरोध में, मैं इस तरह ETag गुण सेट: HttpContext.Current.Response.Cache.SetETag (someUniqueValue); बाद के अनुरोधों में, ईटीएजी पढ़कर मुझे पता है कि छवि ब्राउज़र के कैश में है और इसलिए मुझे 304 – Meysam

+0

वापस लौटना होगा, 304 लौटने पर फ़ाइल रीसेट का उपयोग करें। –

25

इस ब्लॉग ने मेरे लिए सवाल का जवाब दिया; http://weblogs.asp.net/jeff/archive/2009/07/01/304-your-images-from-a-database.aspx

असल में, आपको अनुरोध शीर्षलेख पढ़ने की आवश्यकता है, अंतिम संशोधित तिथियों की तुलना करें और यदि वे मेल खाते हैं तो 304 लौटाएं, अन्यथा छवि (200 स्थिति के साथ) वापस करें और कैश हेडर उचित रूप से सेट करें। ब्लॉग से

कोड स्निपेट:

public ActionResult Image(int id) 
{ 
    var image = _imageRepository.Get(id); 
    if (image == null) 
     throw new HttpException(404, "Image not found"); 
    if (!String.IsNullOrEmpty(Request.Headers["If-Modified-Since"])) 
    { 
     CultureInfo provider = CultureInfo.InvariantCulture; 
     var lastMod = DateTime.ParseExact(Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime(); 
     if (lastMod == image.TimeStamp.AddMilliseconds(-image.TimeStamp.Millisecond)) 
     { 
      Response.StatusCode = 304; 
      Response.StatusDescription = "Not Modified"; 
      return Content(String.Empty); 
     } 
    } 
    var stream = new MemoryStream(image.GetImage()); 
    Response.Cache.SetCacheability(HttpCacheability.Public); 
    Response.Cache.SetLastModified(image.TimeStamp); 
    return File(stream, image.MimeType); 
} 
+0

बहुत बढ़िया है! मैंने इसे बदल दिया, हालांकि, 'ToLocalTime()' नहीं करने के बाद से क्योंकि मैं पहले से ही यूटीसी में कैश की तारीख संग्रहीत करता हूं। मैं भी 'नया खाली रिटर्न() 'वापस लौटाता हूं। 'Var adjustedTime = DateTime.SpecifyKind (image.TimeStamp, DateKind.Utc) भी करने के लिए याद रखें, यदि आप ब्लॉग पोस्ट के अनुसार यूटीसी तिथियां संग्रहीत करते हैं। – kamranicus

+0

मुझे यह पसंद है, यह वास्तव में उपयोगी है –

+0

जब मैं इस तरह उपयोग कर रहा हूं और यदि छवि बदलती है तो यह अभी भी ब्राउज़र कैश से लेती है और यह जांचने के लिए सर्वर को मार नहीं देती है। इस पर कोई विचार है? कृप्या –

0

MVC के नए संस्करण में आप HttpStatusCodeResult एक लौटने बेहतर होगा। इस तरह आपको Response.StatusCode या किसी अन्य चीज़ के साथ गड़बड़ सेट करने की आवश्यकता नहीं है।

public ActionResult DisplayPhoto(int id) 
{ 
    //Your code to check your cache and get the image goes here 
    //... 
    if (isChanged) 
    { 
     return File(photo.Content, photo.ContentType); 
    } 
    return new HttpStatusCodeResult(HttpStatusCode.NotModified); 
}