2009-10-13 7 views
27

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

सत्यापन पर हर किसी की सिफारिश क्या है? डेटा एनोटेशन सत्यापन पर्याप्त है? या यह सुनिश्चित करने के लिए सत्यापन को दोहराया जाना चाहिए कि सभी परिस्थितियों में सत्यापन ट्रिगर हो जाए?

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

मैं एक अलग प्रश्न के रूप में इस अनुवर्ती टिप्पणी पोस्ट करने, के रूप में यह मूल की जगह किसी दूसरे प्रश्न बन गया है जा रहा हूँ।

+0

Koritnik की प्रतिक्रिया अपने अनुवर्ती प्रश्न के जवाब। मैं अपनी प्रतिक्रिया उसके द्वारा पोस्ट की गई प्रतिक्रिया के समान करता हूं। सर्वर और क्लाइंट सत्यापन दोनों के लिए समान डेटाअनोटेशन परिभाषा का उपयोग किया जा सकता है। –

+1

डेटा एनोटेशन सत्यापन ठीक है अगर प्रदान किए गए सत्यापन गुण और फ्रेमवर्क स्वयं ही उपयुक्त है। सामुदायिक फीडबैक के कारण एएसपी.नेट एमवीसी 2 आरटीएम के लिए आवश्यक व्यवहार को बदल दिया गया था, इसलिए [आवश्यक] अब काम करता है जैसा आप उम्मीद करेंगे। ऑप्टिनली, जांचें: सत्यापन ब्लॉक (एंटरप्राइज़ लाइब्रेरी), xVal, NHibernate Validators (माना जाता है कि एनएचबीरनेट ओआरएम पर कोई निर्भरता नहीं है)। – miha

+0

'" मैं इस अनुवर्ती टिप्पणी को एक अलग प्रश्न के रूप में पोस्ट करने जा रहा हूं, क्योंकि यह मूल के मुकाबले एक अलग सवाल है। "इसका एक लिंक बुरा विचार नहीं होगा, आह? – Sinjai

उत्तर

18

को

// Only bind properties that are part of the request 
if (bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey)) { 

बदलें DataAnnotationsModelBinder.cs में इस लाइन मैं सतर्क विषय में सुरक्षा आप का चयन करना चाहिए होने के लिए लगता है कि लगता है आप सर्वर सत्यापन को प्राथमिकता देते हैं और सुनिश्चित करते हैं कि यह हमेशा आपकी फॉलबैक है। आपके सर्वर सत्यापन क्लाइंट सत्यापन के बिना काम करना चाहिए। क्लाइंट सत्यापन यूएक्स के लिए अधिक है और यह आपके डिजाइन के लिए सर्वोपरि है, यह सुरक्षा के लिए माध्यमिक है। इस बात को ध्यान में रखते हुए आप अपने सत्यापन को दोहराएंगे। एक लक्ष्य अक्सर आपके ऐप को डिज़ाइन करने का प्रयास कर रहा है ताकि सर्वर और क्लाइंट सत्यापन को सर्वर और क्लाइंट पर सत्यापित करने के लिए आवश्यक कार्य को कम करने के लिए जितना संभव हो सके एकीकृत किया जा सके। लेकिन आश्वस्त रहें कि आपको दोनों को करना होगा।

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

आपके द्वारा वर्णित परिदृश्य के साथ, डेटाअनोटेशन विशेषताएँ विधि पर्याप्त होनी चाहिए। ऐसा लगता है कि फ़ॉर्म को सबमिट करते समय आपके सर्वर सत्यापन को भी लागू करने के लिए आपको कुछ कोड परिवर्तन करने की आवश्यकता है।

2

डेटाअनोटेशन निश्चित रूप से पर्याप्त नहीं है। मैं बेहतर त्रुटि रिपोर्टिंग प्राप्त करने और जितनी जल्दी हो सके विफल होने के लिए डोमेन मॉडल पर अपनी कॉल को पूर्व-मान्य करने के लिए इसे व्यापक रूप से उपयोग करता हूं।

हालांकि आप [आवश्यक] वाले गुणों को सुनिश्चित करने के लिए डेटा एन्नोटेशन मॉडल को स्वयं ट्विक कर सकते हैं। (आज बाद में कोड के साथ पालन करेंगे)।

अद्यतन DataAnnotations मॉडल बाइंडर के लिए स्रोत जाओ और यह

// Only bind properties that are part of the request 
bool contextHasKey = bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey); 
bool isRequired = GetValidationAttributes(propertyDescriptor).OfType<RequiredAttribute>().Count() > 0; 
if (contextHasKey || (!contextHasKey && isRequired)) { 
+0

धन्यवाद मार्टिजन। मैं आपका कोड देखने के लिए तत्पर हूं। –

+0

निश्चित रूप से, मैंने इसे काम पर जाने के पहले (अभी भी काम पर) पोस्ट करने के लिए पोस्ट किया है, इसलिए कोड करने का कोई समय नहीं है :(मैंने थोड़ा पहले बाइंडर को संशोधित किया क्योंकि उसने नेस्टेड ऑब्जेक्ट्स की जांच नहीं की थी और अमान्य गुणों को रीसेट करने के लिए रीसेट कर दिया था, जिसे मैं देखकर असहमत था http://stackoverflow.com/questions/820468/how-does-dataannotationsmodelbinder-work-with-custom-viewmodels/864541#864541 मैंने तब से आवश्यक चेक भी जोड़े हैं, लेकिन जब मैं घर जाता हूं तो उन्हें परीक्षण करना चाहता हूं उन्हें पोस्ट करना। –

+0

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

7

मैंने डेटा एन्नोटेशन के साथ xVal जोड़ा और अपना स्वयं का एक्शन फ़िल्टर लिखा है जो सत्यापन उद्देश्यों के लिए किसी भी इकाई प्रकार पैरामीटर की जांच करता है। तो यदि पोस्टबैक में कुछ फ़ील्ड गुम है, तो यह वैधकर्ता मॉडलस्टेट शब्दकोश भर देगा, इसलिए मॉडल अमान्य है।

आवश्यक:

  • मेरी इकाई/मॉडल सभी IObjectValidator इंटरफ़ेस जो Validate() विधि वाणी को लागू वस्तुओं।
  • मेरी विशेषता वर्ग ValidateBusinessObjectAttribute
  • कहा जाता है xVal मान्यता पुस्तकालय

कार्रवाई फिल्टर कोड:

public void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    IEnumerable<KeyValuePair<string, object>> parameters = filterContext.ActionParameters.Where<KeyValuePair<string, object>>(p => p.Value.GetType().Equals(this.ObjectType ?? p.Value.GetType()) && p.Value is IObjectValidator); 
    foreach (KeyValuePair<string, object> param in parameters) 
    { 
     object value; 
     if ((value = param.Value) != null) 
     { 
      IEnumerable<ErrorInfo> errors = ((IObjectValidator)value).Validate(); 
      if (errors.Any()) 
      { 
       new RulesException(errors).AddModelStateErrors(filterContext.Controller.ViewData.ModelState, param.Key); 
      } 
     } 
    } 
} 

मेरे नियंत्रक कार्रवाई तो इस तरह परिभाषित किया गया है:

[ValidateBusinessObject] 
public ActionResult Register(User user, Company company, RegistrationData registrationData) 
{ 
    if (!this.ModelState.IsValid) 
    { 
     return View(); 
    } 
    ... 
} 
+0

क्या आपके पास इस या डाउनलोड करने योग्य प्रोजेक्ट का उपयोग करने के तरीके पर अधिक विस्तृत उदाहरण है, शायद –

+0

@geocine: समस्या कहां प्रतीत होती है? क्या आप एमवीसी 1 का उपयोग कर रहे हैं? नए संस्करणों को ऐसा करने की आवश्यकता नहीं है, क्योंकि वे मजबूत प्रकार पैरामीटर को स्वत: मान्य करते हैं ... लेकिन यह उदाहरण यहां वास्तविकता के रूप में विस्तृत है। तो समस्या कहां लगती है? –

+0

मैं बस पास गया और मैं सत्यापन मुद्दों के बारे में aspmvc पढ़ने के लिए नया हूँ। मैं भूल गया कि मैं एमवीसी 2 का उपयोग कर रहा था। मेरा बुरा। –

2

मैंने लिखा दोनों एक्सवी से पैटर्न कॉपी करके एमवीसी 1.0 के लिए मेरी खुद की प्रमाणीकरण सेवा अल के डेटाएनोटेशंसरूलेप्रोवाइडर और माइक्रोसॉफ्ट के डेटा एन्नोटेशन मॉडेलबिन्डर (और मार्टिजन की टिप्पणियां)। सेवा इंटरफ़ेस के नीचे है:

public interface IValidationService 
{ 
    void Validate(object instance); 

    IEnumerable<ErrorInfo> GetErrors(object instance); 
} 

public abstract class BaseValidationService : IValidationService 
{ 
    public void Validate(object instance) 
    { 
     var errors = GetErrors(instance); 

     if (errors.Any()) 
      throw new RulesException(errors); 
    } 

    public abstract IEnumerable<ErrorInfo> GetErrors(object instance); 
} 

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

तब आप अपने नियंत्रक रख सकते हैं, व्यवसाय तर्क सेवाएं स्पष्ट रूप से सत्यापन का आह्वान करते हैं सत्यापन के लिए मॉडल बाइंडर पर विशेष रूप से निर्भर होने के बजाय आप तैयार हैं। डेटा में एनोटेशन वास्तव में किसी भी डेटा प्रकार सत्यापन नहीं करता है

  • डिफ़ॉल्ट DataTypeAttribute है, तो आप की आवश्यकता होगी लिखने के लिए:

    वहाँ है कि आप के बारे में पता होना चाहिए अन्य नुकसान के एक जोड़े हैं वास्तव में xVal नियमित अभिव्यक्तियों (या कुछ और) पर सर्वर-साइड डेटा प्रकार सत्यापन का उपयोग करता है।

  • xVal क्लाइंट साइड मान्यता बनाने के लिए गुण चलना नहीं है, इसलिए आप वहाँ कुछ परिवर्तन और अधिक मजबूत क्लाइंट साइड मान्यता प्राप्त करने के लिए बनाने के लिए कर सकते हैं।

यदि मुझे अनुमति है और समय है, तो मैं अधिक स्रोत उपलब्ध कराने की कोशिश करूंगा ...

1

codeproject देखें Server-side Input Validation using Data Annotations

इनपुट सत्यापन ASP.NET MVC में क्लाइंट की तरफ स्वचालित रूप से किया जा सकता है या स्पष्ट रूप से नियमों के विरुद्ध मॉडल को मान्य। यह टिप वर्णन करेगा कि यह एएसपी.NET अनुप्रयोगों के सर्वर-साइड पर या WPF अनुप्रयोगों के भंडार कोड के भीतर मैन्युअल रूप से कैसे किया जा सकता है।

 // Use the ValidationContext to validate the Product model against the product data annotations 
     // before saving it to the database 
     var validationContext = new ValidationContext(productViewModel, serviceProvider: null, items:null); 
     var validationResults = new List<ValidationResult>(); 

     var isValid = Validator.TryValidateObject(productViewModel, validationContext,validationResults, true); 
संबंधित मुद्दे