2009-03-14 15 views
23

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

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

ऐसा करने का एक तरीका होना चाहिए (बहुत अधिक काम-आसपास कोड लिखने के बिना), लेकिन मुझे यह नहीं मिल रहा है। कोई मदद?

संपादित

इसके अलावा, मुझे लगता है कि यह भी अमान्य रूपांतरण, उदा के लिए एक मुद्दा होगा जन्मदिन = "हैलो"।

उत्तर

1

ModelState.AddError देखें।

+0

मुझे ModelState.AddModelError() के बारे में पता है, लेकिन UpdateModel() स्वचालित रूप से त्रुटि संग्रह में मान जोड़ता है। जब तक मैं आपके उत्तर को गलत समझ नहीं पा रहा हूं? –

+1

ठीक है जब आप मान्य करते हैं, मॉडलस्टेट में कुछ जोड़ें। यहां एक महान ट्यूटोरियल है। http://blog.maartenballiauw.be/post/2008/08/29/Form- validation-with-ASPNET-MVC-preview-5.aspx –

+0

मैं उम्मीद कर रहा था कि मुझे सबकुछ बांधना न पड़े, लेकिन हो सकता है कि एकमात्र तरीका अगर मैं अपने संदेश चाहता हूं? –

4

मैं भयानक xVal सत्यापन फ्रेमवर्क का उपयोग कर रहा हूं। यह मुझे मॉडल में मेरी सभी सत्यापन करने देता है (यहां तक ​​कि LINQ-SQL :))। यह क्लाइंट साइड सत्यापन के लिए आवश्यक जावास्क्रिप्ट को भी उत्सर्जित करता है।

संपादित करें: क्षमा बाहर छोड़ दिया कैसे LINQ-एसक्यूएल

बुनियादी कार्यप्रवाह कुछ इस तरह चला जाता है के लिए काम कर इसे पाने के लिए के लिए link

public partial class YourClass 
{ 
    [Required(ErrorMessage = "Property is required.")] 
    [StringLength(200)] 
    public string SomeProperty{ get; set; } 
} 

try 
{ 
    // Validate the instance of your object 
    var obj = new YourClass() { SomeProperty = "" } 
    var errors = DataAnnotationsValidationRunner.GetErrors(obj); 
    // Do some more stuff e.g. Insert into database 
} 
catch (RulesException ex) 
{ 
    // e.g. control name 'Prefix.Title' 
    ex.AddModelStateErrors(ModelState, "Prefix"); 
    ModelState.SetModelValue("Prefix.Title", new ValueProviderResult(ValueProvider["Prefix.Title"].AttemptedValue, collection["Prefix.Title"], System.Globalization.CultureInfo.CurrentCulture)); 

} 
+0

सिर्फ रिकॉर्ड के लिए, xVal को [xxval.codeplex.com/) को xVal टीम में बहिष्कृत किया गया है। वे केवल आपको एमवीसी 1.0 के साथ इसका उपयोग करने की सलाह देते हैं, और यह अब सक्रिय रूप से बनाए रखा या विकसित नहीं किया जा रहा है। –

6
DefaultModelBinder साथ

यह डिफ़ॉल्ट आवश्यक त्रुटि संदेश ओवरराइड करने के लिए संभव है लेकिन दुर्भाग्य से यह विश्व स्तर पर लागू होगा जो IMHO यह पूरी तरह से बेकार बना देता है। लेकिन मामले में आप यहां करने का फैसला किया है कैसे:

  1. अपने ASP.NET साइट के लिए App_GlobalResources फ़ोल्डर जोड़ें
  2. संसाधन फ़ाइल के अंदर Messages.resx
  3. नामक एक संसाधन फ़ाइल जोड़ें एक नया स्ट्रिंग संसाधन की घोषणा

    DefaultModelBinder.ResourceClassKey = "Messages"; 
    
: कुंजी PropertyValueRequired और कुछ मान के साथ
  • Application_Start निम्नलिखित पंक्ति जोड़ दें 0

    जैसा कि आप देख सकते हैं कि आप जिस मॉडल प्रॉपर्टी को सत्यापित कर रहे हैं और त्रुटि संदेश के बीच कोई लिंक नहीं है।

    निष्कर्ष में इस परिदृश्य को संभालने के लिए कस्टम सत्यापन तर्क लिखना बेहतर है।

    if (model.MyProperty == null || 
        /** Haven't tested if this condition is necessary **/ 
        !model.MyProperty.HasValue) 
    { 
        ModelState.AddModelError("MyProperty", "MyProperty is required"); 
    } 
    
  • +0

    क्या आप जानते हैं कि संसाधन क्लासकी व्यवहार हाल ही में बदल गया है या नहीं? यह एमवीसी 3 में टूटा हुआ लगता है। डॉक्टर ने यह भी कहा है कि इसे अमान्य वर्ग के लिए अपवाद फेंकना चाहिए, लेकिन यह नहीं होगा, भले ही मैं DefaultModelBinder.ResourceClassKey = "lkjhjkjdswqq" करता हूं। –

    +0

    कभी नहीं ... बस यह जवाब http://stackoverflow.com/questions/5395040/globally-localize-validation/5395297#5395297 पर ब्रैड के उद्धरण के साथ मिला है कि यह क्यों काम नहीं कर रहा है :) –

    3

    कैसे इस बारे में: एक तरह से एक नल प्रकार (System.Nullable <TValueType>) और फिर उपयोग करने के लिए हो सकता है?

    [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$", 
            ErrorMessage = "Characters are not allowed.")] 
    

    है कि आप विशिष्ट त्रुटि संदेश जो कुछ के लिए MVC सत्यापनकर्ताओं आप उपयोग करना चाहते के साथ गुण टैग करने के लिए अनुमति चाहिए ...

    2

    ASP.NET MVC 1 में, मैं इस समस्या को भी मुलाकात की।

    मेरी प्रोजेक्ट में, "एंट्री" नामक एक मॉडल या व्यावसायिक ऑब्जेक्ट है, और इसकी प्राथमिक कुंजी EntryId int है? टाइप करें, और EntryId का मान उपयोगकर्ताओं द्वारा इनपुट करने की अनुमति दी जा सकती है।

    तो समस्या यह है कि जब फ़ील्ड रिक्त या शून्य या कुछ पूर्णांक मान मौजूद है, तो कस्टम त्रुटि संदेश अच्छी तरह से दिखाए जा सकते हैं, लेकिन यदि मान "ए" जैसा कुछ गैर-पूर्णांक मान है, तो मैं कर सकता हूं "संदेश 'ए' अमान्य है" जैसे डिफ़ॉल्ट संदेश को प्रतिस्थापित करने के लिए कस्टम संदेश का उपयोग करने का कोई तरीका नहीं ढूंढें।

    जब मैं ModelState में त्रुटि संदेश को ट्रैक, मैंने पाया जब मान गैर-पूर्णांक है, वहाँ दो EntryId से संबंधित त्रुटियों हो जाएगा, और पहले आइटम के त्रुटि संदेश खाली मेरे पास है है ...

    अब समस्या को हैक करने के लिए ऐसे बदसूरत कोड का उपयोग करने के लिए।

    if (ModelState["EntryId"].Errors.Count > 1) 
    { 
        ModelState["EntryId"].Errors.Clear(); //should not use ModelState["EntryId"].remove(); 
        ModelState.AddModelError("EntryId", "必须为大于0的整数"); //必须为大于0的整数 means "it should be an integer value and great than 0" 
    } 
    

    लेकिन यह नियंत्रक वसा बनाता है, उम्मीद है कि इसे हल करने का एक वास्तविक समाधान है।

    0

    हाँ, वहाँ एक रास्ता है, तो आप System.ComponentModel.DataAnnotations संयोजन में xVal साथ उपयोग करना चाहिए और आप सत्यापन नियमों और संदेश सेट करने में सक्षम होने जा रहे हैं (यू भी स्थानीयकरण के लिए संसाधन फ़ाइलों का उपयोग कर सकते हैं) अपनी संपत्ति गुण
    का उपयोग कर से प्रत्येक के लिए इधर देखोhttp://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/

    19

    DefaultModelBinder बढ़ा कर अपनी खुद की ModelBinder करें:

    public class LocalizationModelBinder : DefaultModelBinder 
    

    अवहेलना SetProperty:

     base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value); 
    
         foreach (var error in bindingContext.ModelState[propertyDescriptor.Name].Errors. 
          Where(e => IsFormatException(e.Exception))) 
         { 
          if (propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)] != null) 
          { 
           string errorMessage = 
            ((TypeErrorMessageAttribute)propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)]).GetErrorMessage(); 
           bindingContext.ModelState[propertyDescriptor.Name].Errors.Remove(error); 
           bindingContext.ModelState[propertyDescriptor.Name].Errors.Add(errorMessage); 
           break; 
          } 
         } 
    

    जाँच करने के लिए समारोह bool IsFormatException(Exception e) जोड़ें यदि एक अपवाद एक FormatException है:

    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] 
    public class TypeErrorMessageAttribute : Attribute 
    { 
        public string ErrorMessage { get; set; } 
        public string ErrorMessageResourceName { get; set; } 
        public Type ErrorMessageResourceType { get; set; } 
    
        public TypeErrorMessageAttribute() 
        { 
        } 
    
        public string GetErrorMessage() 
        { 
         PropertyInfo prop = ErrorMessageResourceType.GetProperty(ErrorMessageResourceName); 
         return prop.GetValue(null, null).ToString(); 
        } 
    } 
    

    को विशेषता जोड़ें:

    if (e == null) 
          return false; 
         else if (e is FormatException) 
          return true; 
         else 
          return IsFormatException(e.InnerException); 
    

    एक गुण कक्षा बनाएं वह संपत्ति जिसे आप सत्यापित करना चाहते हैं:

    [TypeErrorMessage(ErrorMessageResourceName = "IsGoodType", ErrorMessageResourceType = typeof(AddLang))] 
        public bool IsGood { get; set; } 
    

    AddLang एक resx फ़ाइल है और IsGoodType संसाधन का नाम है।

    और अंत में Global.asax.cs Application_Start में जोड़ें:

    ModelBinders.Binders.DefaultBinder = new LocalizationModelBinder(); 
    

    चीयर्स!

    +4

    शानदार उत्तर है, लेकिन वहां एक जवाब है इसके साथ मुद्दा। 'propertyDescriptoy.Name' हमेशा 'ModelState' की कुंजी के रूप में उपयोग नहीं किया जाता है। कुंजी बनाने के लिए आपको विरासत में 'CreateSubPropertyName' विधि का उपयोग करना चाहिए, इस तरह:' ModelMetadata propertyMetadata = bindingContext.PropertyMetadata [propertyDescriptor.Name]; string propertyName = CreateSubPropertyName (bindingContext.ModelName, propertyMetadata.PropertyName); और फिर आप 'bindingContext.ModelState [propertyName]' का उपयोग कर सकते हैं। – Iravanchi

    +2

    ओउ, ... और विशेषता वर्ग में 'GetErrorMessage' को' खाली मैसेज 'वापस करना चाहिए यदि यह खाली नहीं है (या दूसरी तरफ)। यह इस मामले को ध्यान में रखता है कि विशेषता का उपयोगकर्ता त्रुटि संदेश इनलाइन निर्दिष्ट करता है (बिना किसी संसाधन के)। – Iravanchi

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