2012-11-10 5 views
46

कभी-कभी उपयोगकर्ता इनपुट सख्ती से अमान्य नहीं है लेकिन इसे समस्याग्रस्त माना जा सकता है।एएसपी.नेट एमवीसी में सत्यापन के दौरान चेतावनियां कैसे प्रदान करें?

उदाहरण के लिए:

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

इनमें से कुछ आसानी से क्लाइंट-साइड की जांच की जा सकती हैं, कुछ को सर्वर-साइड चेक की आवश्यकता होती है।

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

दिमाग में आने वाला सबसे व्यवहार्य समाधान CustomValidationAttribute के समान कुछ विशेषता बनाना है, जो एक AJAX कॉल कर सकता है और कुछ चेतावनी टेक्स्ट प्रदर्शित करेगा लेकिन ModelState को प्रभावित नहीं करता है।

[WarningOnFieldLength(MaxLength = 150)] 
[WarningOnPossibleDuplicate()] 
public string Name { get; set; } 

ध्यान में रखते हुए:

@Html.EditorFor(model => model.Name) 
@Html.WarningMessageFor(model => model.Name) 
@Html.ValidationMessageFor(model => model.Name) 

तो, किसी भी विचार का इरादा उपयोग है?

+0

मैं मान लीजिए कि आप एक विशेषता के रूप में '[चेतावनीऑनफिल्ल्ड लम्बाई (150)]' की तरह कुछ चाहते हैं? –

+0

@TiesonT। हाँ बिल्कुल। – Alex

+1

इस उत्तर की तरह कुछ आपको वहां भाग लेता है: http://stackoverflow.com/a/9652582/534109 - विशेषता का उपयोग विस्तार के लिए एक हुक उत्पन्न करने के लिए किया जा सकता है, मानते हुए कि आप दृढ़ता से प्रकार के हेल्पर्स का उपयोग करना चाहते हैं। मैं देखूंगा कि क्या मैं वास्तविक जवाब के लिए कुछ एक साथ स्क्रैप कर सकता हूं ... –

उत्तर

47

कुल मिलाकर डिजाइन

साथ, मेरा मानना ​​है कि आप अगर उपयोगकर्ता चेतावनी की अनदेखी करने के लिए चुन किसी भी तरह ट्रैक करने के लिए होता है शुरू करने के लिए। ऐसा करने के लिए एक सरल और पारदर्शी तरीका है चेतावनी अनदेखा करें चेक-बॉक्स, जिसे उपयोगकर्ता सबमिट करने से पहले जांचना होगा। एक और विकल्प यह है कि उन्होंने फॉर्म को दो बार सबमिट किया है और दूसरी सबमिट पर चेतावनियों को नजरअंदाज कर दिया है; तो आपको शायद IgnoreWarnings छिपे हुए फ़ील्ड की आवश्यकता होगी। अन्य डिज़ाइन हो सकते हैं, लेकिन सादगी के लिए मैं पहले विकल्प के साथ जाऊंगा।

संक्षेप में, दृष्टिकोण सत्यापन की चेतावनी प्रकार का समर्थन सभी दृश्य मॉडल के लिए

  • एक कस्टम डेटा एनोटेशन विशेषता बनाने के लिए है;
  • एक ज्ञात आधार वर्ग जो दिखाई देने वाले मॉडल से प्राप्त कर लेगा;
  • हम एक कस्टम विशेषता के लिए जावास्क्रिप्ट में तर्क नकल करना होगा।

कृपया ध्यान दें कि नीचे दिया गया कोड केवल दृष्टिकोण को दिखाता है और मुझे पूर्ण संदर्भ जानने के बिना बहुत सारी चीजें माननी हैं।

देखें मॉडल

इस परिदृश्य में यह एक वास्तविक मॉडल है जो एक अच्छा विचार वैसे भी है से एक दृश्य मॉडल अलग करने के लिए सबसे अच्छा है। एक संभव दृष्टिकोण है जो की चेतावनियों का समर्थन सभी दृश्य मॉडलों के लिए एक आधार वर्ग के लिए है:

public abstract class BaseViewModel 
{ 
    public bool IgnoreWarnings { get; set; } 
} 

प्रमुख कारण एक मॉडल अलग होने की जरूरत है अपने डेटाबेस में IgnoreWarnings संपत्ति भंडारण में थोड़ा समझ में नहीं है कि है।

आपका व्युत्पन्न दृश्य मॉडल तो के रूप में दिखाई देगा इस प्रकार है:

public class YourViewModel : BaseViewModel 
{ 
    [Required] 
    [StringLengthWarning(MaximumLength = 5, ErrorMessage = "Your Warning Message")] 
    public string YourProperty { get; set; } 
} 

StringLengthWarning सर्वर और क्लाइंट साइड सत्यापन के लिए एक कस्टम डेटा एनोटेशन विशेषता है। यह सिर्फ अधिकतम लंबाई का समर्थन करता है और आसानी से किसी भी अन्य आवश्यक गुणों के साथ बढ़ाया जा सकता है।

डाटा एनोटेशन गुण

विशेषता के मुख्य IsValid(value, validationContext तरीका है।

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] 
public class StringLengthWarningAttribute : ValidationAttribute, IClientValidatable 
{ 
    public int MaximumLength { get; set; } 

    public override bool IsValid(object value) 
    { 
     return true; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var model = validationContext.ObjectInstance as BaseViewModel; 
     var str = value as string; 
     if (!model.IgnoreWarnings && (string.IsNullOrWhiteSpace(str) || str.Length > MaximumLength)) 
      return new ValidationResult(ErrorMessage); 
     return base.IsValid(value, validationContext); 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     yield return new StringLengthWarningValidationRule(MaximumLength, ErrorMessage); 
    } 
} 

विशेषता IClientValidatable लागू करता है और एक कस्टम ग्राहक सत्यापन नियम का इस्तेमाल करता है:

public class StringLengthWarningValidationRule : ModelClientValidationRule 
{ 
    public StringLengthWarningValidationRule(int maximumLength, string errorMessage) 
    { 
     ErrorMessage = errorMessage; 
     ValidationType = "stringlengthwarning"; 
     ValidationParameters.Add("maximumlength", maximumLength); 
     ValidationParameters.Add("ignorewarningsfield", "IgnoreWarnings"); 
    } 
} 

क्लाइंट-साइड JavaScript

अंत में, यह काम करने के लिए, आप निम्न जावास्क्रिप्ट की आवश्यकता होगी

$(function() { 
    $.validator.addMethod('stringlengthwarning', function (value, element, params) { 
     var maximumlength = params['maximumlength']; 
     var ignorewarningsfield = params['ignorewarningsfield']; 

     var ctl = $("#" + ignorewarningsfield); 
     if (ctl == null || ctl.is(':checked')) 
      return true; 
     return value.length <= maximumlength; 
    }); 

    $.validator.unobtrusive.adapters.add("stringlengthwarning", ["maximumlength", "ignorewarningsfield"], function (options) { 
     var value = { 
      maximumlength: options.params.maximumlength, 
      ignorewarningsfield: options.params.ignorewarningsfield 
     }; 
     options.rules["stringlengthwarning"] = value; 
     if (options.message) { 
      options.messages["stringlengthwarning"] = options.message; 
     } 
    }); 

}(jQuery)); 
: आपके विचार से संदर्भित

जावास्क्रिप्ट कुछ मान्यताओं आप (चेक-बॉक्स नाम, आदि) को फिर से करना चाह सकते हैं बनाता है।

अद्यतन: HTML सहायकों

त्रुटियों और चेतावनियों के लिए अलग से सत्यापन संदेश प्रदर्शित करने के लिए सहायकों की एक जोड़ी के लिए आवश्यक हो जाएगा।

public static class MessageHelpers 
{ 
    public static MvcHtmlString WarningMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) 
    { 
     if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] != null) 
      return htmlHelper.ValidationMessageFor(expression); 
     return MvcHtmlString.Empty; 
    } 

    public static MvcHtmlString ErrorMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) 
    { 
     if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] == null) 
      return htmlHelper.ValidationMessageFor(expression); 
     return MvcHtmlString.Empty; 
    } 
} 

दृश्य वे सामान्य रूप से इस्तेमाल किया जा सकता है::

 @Html.EditorFor(model => model.YourProperty) 
     @Html.ErrorMessageFor(model => model.YourProperty) 
     @Html.WarningMessageFor(model => model.YourProperty) 
+0

ग्रेट उत्तर, धन्यवाद :) – Alex

+6

वास्तव में बहुत अच्छा, बहुत पूरा जवाब। आप इस बक्षीस के लायक हैं! –

+0

डेटा एनोटेशन का उपयोग न करने का शानदार उदाहरण। धन्यवाद! –

3

बस संभव पुन: सबमिट करें कार्यान्वयन आप का उल्लेख पर एक त्वरित टिप्पणी ...

"यदि आप ऐसा करना मतलब था?" के लिए सत्यापन के प्रकार, किसी उपयोगकर्ता के परिप्रेक्ष्य से, एक धारणा के आधार पर एक फॉर्म को दोबारा सबमिट करना पड़ता है कि उन्होंने गलती की है, वह बहुत परेशान हो सकता है। यदि आप सर्वर को हिट करना चाहते हैं तो मैं केवल जावास्क्रिप्ट के साथ क्लाइंट पक्ष पर 'छद्म-सत्यापन' लागू करता हूं और (उम्मीद है कि त्वरित) AJAX कॉल करता हूं।

मैं इनपुट के धुंध/परिवर्तन घटनाओं पर चेतावनियां प्रदर्शित करने का भी प्रयास करता हूं ताकि वे उपयोगकर्ता हिट सबमिट करने से पहले दिखा सकें। हो सकता है कि सभी स्थितियों में व्यावहारिक न हो, लेकिन मैंने सोचा कि मैं इसे वहां फेंक दूंगा।

4

आप अपने जीवन को आसान बनाने के jQuery सत्यापन के depends समारोह इस्तेमाल कर सकते हैं निम्नलिखित वर्ग एक नमूना प्रदान करता है।

पूर्व।

@Html.LabelFor(m => m.UserName) 
@Html.TextBoxFor(m => m.UserName) 
@Html.ValidationMessageFor(m => m.UserName) 

<label>Ignore Warnings</label> 
<input id="ignore-warnings" type="checkbox" /> 

<script> 
    $(function() { 
    $("#UserName").rules("add", { 
     minlength: { 
     param: 6, 
     depends: function (element) { 
      return !$("#ignore-warnings").attr('checked'); 
     } 
     }, 

     // server side remote validation for duplicate check 
     remote: { 
     param: '/account/duplicate', 
     depends: function (element) { 
      return !$("#ignore-warnings").attr('checked'); 
     } 
     } 
    }); 
    }); 
</script> 
1

यह एक संभावित समाधान का एक स्केच है। कस्टम विशेषताओं (ऊपर सहित) जोड़ने के कई उदाहरण हैं इसलिए मैं उस बिट को छोड़ दूंगा।

jQuery validator function में अनदेखा के उपयोग को जोड़ना संभव हो सकता है।

फिर

$("form").validate({ 
ignore: ".warning-only" 
}); 

का उपयोग करें और सत्यापनकर्ता के माध्यम से पहली बार एक पास के बाद 'चेतावनी केवल-' वर्ग को जोड़ने के लिए ग्राहक के पक्ष सत्यापनकर्ता का उपयोग करें। इसके बाद फ़ॉर्म को सर्वर पर भेजने की अनुमति देनी चाहिए।

जैसा कि मैंने कहा, बस एक स्केच, लेकिन यह कुछ है जो मैं फर्चर उपयोग के लिए शोध कर रहा हूं।

+0

@Alex मुझे लगता है कि एक ही समाधान ऊपर सुझाया गया है। इसे सर्ज बेलोव से उत्तर के साथ जोड़कर आपको वहां ले जाना चाहिए। –

0

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

<script type="text/javascript">  
$.validator.addMethod('isValidCustomMethod', function (value, element) { 
     if($(element).hasClass('ignore-validation')){ 
      return true; 
     } 
     var isValid = false; //your code to do validation would actually go here 
     return isValid; 
    }); 

$(document).ready(function() { 

    $('#IdOfInput').rules('add', { isValidCustomMethod: true, messages: { isValidCustomMethod: 'Your warning message here'} }); 

    $('form').submit(function() { 
        $(this).validate().invalidElements().each(function() { 
         if($(this).attr('id')=='IdOfInput'){ 
          $(this).addClass('ignore-validation'); 
         } 
        }); 
       }); 
     }); 
    </script> 
संबंधित मुद्दे