2013-07-02 10 views
12

में सार्वजनिक गैर-क्रिया विधियों का उद्देश्य मैंने अभी एमवीसी में काम करना शुरू कर दिया है और मुझे एक संदेह है।एमवीसी

Nonaction विधि के बजाय, हम नियंत्रक में निजी विधि बना सकते हैं या हम मॉडल में विधि भी लिख सकते हैं और नियंत्रक से कॉल कर सकते हैं।

तो, एमवीसी में सार्वजनिक NonAction विधि का उपयोग करने का वास्तविक उद्देश्य क्या है?

+0

यह सुनिश्चित नहीं है कि आप क्या खोज रहे हैं - यदि आपके पास ऐसी कोई विधि है जो किसी कारण से सार्वजनिक होने की आवश्यकता है, लेकिन कोई कार्रवाई नहीं होनी चाहिए तो आप इसे इस तरह से चिह्नित करें ... या आपका प्रश्न यह है कि "लोग सार्वजनिक तरीकों का उपयोग क्यों करते हैं"? –

+1

@AlexeiLevenkov: हाँ मेरा सवाल यह है कि लोग सार्वजनिक गैर-व्यवहार विधि का उपयोग क्यों करते हैं। वे निजी विधि का भी उपयोग कर सकते हैं। – ChandniShah

उत्तर

6

मुझे लगता है, विशेषता यहां केवल बेहतर लचीलेपन के लिए है (मैं इस सवाल का जवाब बेहतर पता करने के लिए टिप्पणी में सवाल का पुनर्गठन)। एक ढांचा डिजाइनर के रूप में, कोई भी अंतिम उपयोगकर्ता को यथासंभव कोडिंग बाधाओं को आराम करना चाहता है। सार्वजनिक गैर-कार्यवाही न होने की आवश्यकता सामान्य रूप से अच्छी लग सकती है लेकिन कुछ परियोजनाओं के लिए बहुत ही सीमित हो सकती है।[NonAction] जोड़ना उनकी समस्या हल करता है (हालांकि उनके खराब डिजाइन द्वारा पेश किया गया है) - और जाहिर है कि आपको विशेषता का उपयोग करने के लिए मजबूर नहीं किया गया है, इसलिए यह एक फ्रेमवर्क डिजाइनर परिप्रेक्ष्य से जीत-जीत है।

एक अन्य कारण विरासत हो सकता है - पहले एमवीसी संस्करणों में केवल [Action] के साथ चिह्नित विधियों को क्रियाओं के रूप में माना जाता है। इसलिए जब उन्होंने आवश्यकता को आराम दिया (और सभी सार्वजनिक तरीकों को क्रियाओं के रूप में माना गया) उन्होंने [NonAction] रखा ताकि डेवलपर बहुत भ्रमित न हों।


सामान्य तौर पर, NonAction का उपयोग कर एक बुरी बात है - वास्तव में कारणों से आप ने कहा के लिए। अगर कुछ कार्रवाई नहीं होनी चाहिए, तो यह पहले स्थान पर public नहीं होना चाहिए।

public class MyController : IController 
{ 
    public ActionResult Foo(long orderId) 
    { 
     var order = new OrdersController().GetOrder(orderId); //GetOrder is public 
     ... 
    } 
} 

की तुलना के साथ:

नियंत्रक पर सार्वजनिक गैर कार्रवाई के तरीकों के साथ समस्या यह है कि वे अपने नियंत्रक का दृष्टांत और विधि कॉल करने के लिए परीक्षा लोगों को, आम तर्क को अलग करने के बजाय है

public class MyController : IController 
{ 
    public ActionResult Foo(long orderId) 
    { 
     var order = _orderService.GetOrder(orderId); 
     ... 
    } 
} 

पहला दृष्टिकोण क्रियाओं में नियंत्रकों और गैर-सीधा कोड के बीच युग्मन बढ़ाने की ओर जाता है। कोड का पालन करना और रिफैक्टर करना मुश्किल हो जाता है, और नकली/परीक्षण करने के लिए बोझिल हो जाता है।

बढ़ते युग्मन के अलावा, कोई भी सार्वजनिक गैर-क्रिया विधि एक सुरक्षा छेद है - यदि आप [NonAction] (या बेहतर, जनता से दूर) के साथ इसे चिह्नित करना भूल जाते हैं - क्योंकि इसे सामान्य कार्रवाई के रूप में माना जाता है और इसे बाहरी रूप से बुलाया जा सकता है। मुझे मूल प्रश्न पता है कि आप निश्चित रूप से आवश्यक होने पर विशेषता को अटैच करना कभी नहीं भूलेंगे, लेकिन यह समझना भी महत्वपूर्ण है कि क्या होगा यदि आप क्या कर सकते हैं;) ओह ठीक है, और जैसा कि हम इस पर हैं, ऐसा लगता है कि "विशेषता को भूलना" अधिक सैद्धांतिक रूप से संभावित है, "विधि को निजी बनाने के लिए भूलना" की तुलना में।


कभी कभी लोगों का कहना है public गैर कार्रवाई होने इकाई परीक्षण के लिए आवश्यक है, लेकिन फिर, जब कुछ एक कार्रवाई यह सबसे अधिक संभावना एक अलग वर्ग में अलग किया जा सकता है और अलग से जांच नहीं की है। इसके अलावा, यहां तक ​​कि यदि किसी भी कारण से संभव नहीं है, तो publicपरीक्षण उद्देश्यों के लिए केवल एक खराब आदत है - internal और InternalsVisibleTo का अनुशंसित तरीका है।

+0

गैर क्रिया विधि के बजाय इसे निजी अनुशंसा करने के लिए अच्छा है क्योंकि इसे फ़ंक्शन कॉलिंग जैसे क्रिया विधियों के मध्यवर्ती संचालन में उपयोग किया जा सकता है। अब, उन्हें उस नियंत्रक के बाहर नहीं बुलाया जा सकता है। अब तक बहुत अच्छा है। प्रश्न - मुझे 'गैर-क्रिया' विधि का उपयोग क्यों करना चाहिए? क्या आप इसके उपयोग के महत्व को बता सकते हैं? –

+0

_ "मुझे '[NonAction]' _ _ का उपयोग क्यों करना चाहिए - आपको इसका उपयोग करने की आवश्यकता नहीं है। मेरा लेना यह है कि विशेषता मौजूद है क्योंकि एएसपी.नेट एमवीसी बनाने वाले लोग खराब डिजाइन किए गए परियोजनाओं के लिए ढांचा उपलब्ध करना चाहते थे। – andreister

+0

ठीक है धन्यवाद। लेकिन 'गैर क्रिया' विधि का उपयोग करते समय उन बुरी आदतों को क्या शामिल किया गया है? –

1

इस तरह की स्थिति कुछ परीक्षण ढांचे की आवश्यकता के कारण हो सकती है जैसे कि आपको उस विधि पर यूनिट परीक्षण करने की आवश्यकता है, फिर आप इसे बेनकाब करने के लिए प्रयास करें, हालांकि यह एक खराब डिज़ाइन है लेकिन इन्हें बदलना नहीं है।

डिफ़ॉल्ट रूप से, एमवीसी ढांचा एक नियंत्रक वर्ग के सभी सार्वजनिक तरीकों को क्रिया विधियों के रूप में मानता है। यदि आपके नियंत्रक वर्ग में एक सार्वजनिक विधि है और आप यह नहीं चाहते हैं कि यह एक क्रिया विधि हो, तो आपको उस विधि को NonActionAttribute विशेषता के साथ चिह्नित करना होगा।

रियल उद्देश्य सार्वजनिक NonAction

उपयोग करने के लिए MVC रूपरेखा है कि दिए गए नियंत्रक विधि कार्रवाई नहीं है सूचित करने के लिए गैर कार्रवाई विधि के लिए उपयोग को प्रतिबंधित करने के।

जब आप URL पर NonAction विशेषता के साथ कोई विधि चलाने का प्रयास करते हैं तो आपको अनुरोध के जवाब के रूप में त्रुटि 404 मिलती है।

रेफरी: http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx

विस्तार के लिए: http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx

+1

मुझे पता है कि NonActionAttribute का उपयोग कैसे करें। मेरा असली सवाल यह है कि नोनेक्शन विधि का उपयोग करने का वास्तविक कारण क्या है। – ChandniShah

+0

@ChandniShah, जब आप URL पर 'NonAction' विशेषता' के साथ कोई विधि चलाने का प्रयास करते हैं तो आपको अनुरोध के जवाब के रूप में त्रुटि 404 मिलती है। – Satpal

+0

लेकिन सार्वजनिक गैर क्रिया विधि के स्थान पर, मैं निजी विधि का भी उपयोग कर सकता हूं। उस मामले में भी मुझे त्रुटि मिलेगी। तो मुझे पबल गैर क्रिया विधि का उपयोग करने की आवश्यकता क्यों है? – ChandniShah

0

जब यूआरएल केस संवेदी नहीं हैं यह फायदेमंद है। इसलिए उदाहरण के लिए यदि आप अनुरोध होम/हमारे बारे में इस HomeController और कार्रवाई बारे में है, साथ ही घर/के बारे में एक ही नियंत्रक और एक ही कार्रवाई विधि जा रहा है के लिए चला जाता है।

नीचे

public class HomeController:Controller 
{ 
.... 
    public ViewResult About() 
    { 
     return View(); 
    } 

    public ViewResult aBOut() 
    { 
     return View(); 
    } 
} 

ढांचे की तरह निर्धारित कर सकते हैं नहीं जो about समारोह कॉल करने के लिए, और कह रही है कि कॉल अस्पष्ट है अपवाद फेंकता है।

enter image description here

बेशक

एक तरह से इस समस्या को दूर करने के लिए कार्रवाई का नाम बदलने के लिए है।

यदि किसी कारण से आप कार्रवाई का नाम बदलना नहीं चाहते हैं, और इनमें से एक कार्य एक क्रिया नहीं है, तो आप इस गैर क्रिया विधि को गैर-क्रिया विशेषता के साथ सजाने के लिए तैयार कर सकते हैं। उदाहरण:

[NonAction] 
public ActionResult aBOut() 
{ 
    return View(); 
} 
0

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

[NonAction] 
publi int GetOrder() 

: तो फिर हम जैसे सार्वजनिक तरीकों का उपयोग कर रहे हैं।

तो आपको नियंत्रक के बारे में सोचने के लिए खुद को बाध्य नहीं करना चाहिए बल्कि अनुरोधों को संभालने का एक तरीका है, बल्कि पेज को प्रतिपादित करने के लिए अपने कस्टम ढांचे को बनाने के लिए एक उपकरण के रूप में भी। इस तरह हम अपने नियंत्रकों को बिल्कुल एक कार्य के लिए ज़िम्मेदार रखते हैं और हम डोमेन चिंताओं को अलग कर रहे हैं।

0

डिफ़ॉल्ट रूप से, एमवीसी ढांचा एक नियंत्रक वर्ग के सभी सार्वजनिक तरीकों को क्रिया विधियों के रूप में मानता है।यदि आपके नियंत्रक वर्ग में एक सार्वजनिक विधि है और आप यह नहीं चाहते हैं कि यह एक क्रिया विधि हो, तो आपको उस विधि को NonActionAttribute विशेषता के साथ चिह्नित करना होगा।

+0

तो, नियंत्रक में गैर क्रिया का उपयोग करने का क्या फायदा है? –

+0

आप लंबे समय से चलने वाले, गैर-CPU बाध्य अनुरोधों के लिए गैर क्रिया विधियों का उपयोग कर सकते हैं। अनुरोध के संसाधित होने पर वेब सर्वर को काम करने से अवरुद्ध करने से बचा जाता है। – Duk

0

एएसपी.नेट अत्यधिक अनुकूलन योग्य है। मान लीजिए कि आप एमवीसी HTTP हैंडलर को ओवरराइड करके ढांचे के डिफ़ॉल्ट व्यवहार को बदलने जा रहे हैं। हो सकता है कि आप नियंत्रक के आधार पर लॉगिंग तर्क को कस्टमाइज़ करना चाहते हैं, जिसका उपयोग किया जाता है। कुछ नियंत्रक विधि IControllerLogger GetLogger() के साथ आपके ILoggingController इंटरफ़ेस को लागू करते हैं। इस विधि के लिए आपको एक सार्वजनिक गैर-क्रिया विधि लिखनी होगी।