2014-12-25 11 views
9

एएसपी.नेट वेब एपीआई (4.0.30506) में कुछ अजीब व्यवहार प्रतीत होता है जिसे मैंने पहले नहीं देखा है।एएसपी.नेट वेब एपीआई कैश एक्शन फ़िल्टर एट्रिब्यूट्स अनुरोधों पर

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

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

मैंने जो किया वह विजुअल स्टूडियो 2012 एएसपी.नेट एमवीसी 4 वेब अनुप्रयोग प्रोजेक्ट "वेब एपीआई" टेम्पलेट के साथ एक नई खाली परियोजना बना रहा था। यह वेब एपीआई 4.0.20710.0 NuGet पैकेज के साथ आता है। उसके बाद मैं निम्न विशेषता कहा:

[DebuggerDisplay("{id}")] 
public class TestFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute { 
    private static readonly List<int> used = new List<int>(); 

    private static int counter; 
    private readonly int id; 

    public TestFilterAttribute() { 
     this.id = Interlocked.Increment(ref counter); 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) { 
     // Just for testing: I would expect this line never to throw, but it does. 
     if (used.Contains(this.id)) throw new Exception("WAT?"); 
     used.Add(this.id); 
     base.OnActionExecuting(actionContext); 
    } 
} 

और मैं ValuesController (डिफ़ॉल्ट टेम्पलेट का हिस्सा) को यह विशेषता जोड़ें:

public class ValuesController : ApiController { 
    // GET api/values 
    [TestFilterAttribute] 
    public IEnumerable<string> Get() { 
     return new string[] { "value1", "value2" }; 
    } 

    // ... 
} 

अब जब मैं परियोजना शुरू,/api के लिए जाना/ब्राउज़र में मूल्य और उस पृष्ठ को कुछ बार रीफ्रेश करें, "WAT?" अपवाद फेंक दिया गया है।

क्या वेब एपीआई का यह सामान्य व्यवहार है और यदि हां, तो इसके बारे में क्या तर्क है? या क्या मुझे इस बदलाव के बारे में कुछ ज्ञापन याद आया? क्या यह निर्भरता इंजेक्शन करने के लिए वेब एपीआई विशेषताओं को अतिरिक्त अनुपयुक्त बनाता है? या मैं कुछ गलत कर रहा हूँ?

+2

जहां तक ​​मुझे याद है, एएसपीनेट एमवीसी 2.0 से 3.0 - http://stackoverflow.com/a/8937793/1679310 से आने पर मेरे लिए यह बड़ा बदलाव था। और मैं कहूंगा कि एपीआई पर बाद में भी यही लागू होता है ... –

उत्तर

12

वेब एपीआईके शीर्ष MVC पर बनाया गया है, इस प्रकार यह का उपयोग करता है यह बहुत सुविधा है।

विशेषता उदाहरण पुनः उपयोगिता एमवीसी 3 द्वारा शुरू आक्रामक कैशिंग का हिस्सा है। इसका मतलब है कि उसी Attribute इंस्टेंस का उपयोग सभी Actions के साथ किया जाएगा, जिस पर इसे लागू किया जाता है। एमवीसी पाइपलाइन Singleton जैसे Attribute कक्षा का इलाज करने की कोशिश कर रही है।

क्योंकि एक ही Attributeउदाहरण पुन: उपयोग किया जाता है, यह निर्माता नहीं बुलाया जाता है और id वृद्धि नहीं कर रहा है। यदि, उदाहरण के लिए, आप OnActionExecuting के अंदर id बढ़ाते हैं, तो सभी अच्छी तरह से काम करेंगे।

आप अभी भी अपने Attribute के साथ जो कुछ भी चाहते हैं वह कर सकते हैं। आपको केवल यह ध्यान रखना होगा कि आपको हमेशा एक नया उदाहरण बनाया गया है। कन्स्ट्रक्टर में शुरुआती प्रारंभिक लेकिन कुछ भी नहीं होना चाहिए।

public TestFilterAttribute() { 
    // Instance will be reused thus this will not be called for each Action 
} 

public override void OnActionExecuting(HttpActionContext actionContext) { 
    // Called on each Action 
} 
+3

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

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