ASP.NET MVC: DataAnnotation द्वारा कस्टम सत्यापन


110

मेरे पास 4 गुणों वाला एक मॉडल है जो टाइप स्ट्रिंग के हैं। मुझे पता है कि आप StringLength एनोटेशन का उपयोग करके किसी एकल संपत्ति की लंबाई को मान्य कर सकते हैं। हालाँकि मैं संयुक्त 4 संपत्तियों की लंबाई को मान्य करना चाहता हूं।

डेटा एनोटेशन के साथ ऐसा करने का MVC तरीका क्या है?

मैं यह पूछ रहा हूं क्योंकि मैं एमवीसी के लिए नया हूं और अपना समाधान करने से पहले इसे सही तरीके से करना चाहता हूं।


2
क्या आपने धाराप्रवाह सत्यापन देखा है? यह डेटा एनोटेशन की तुलना में जटिल परिदृश्यों को बहुत बेहतर तरीके से संभालता है
लेवलनिस

अत्यधिक की सिफारिश की समाधान पर एक नजर डालें .... dotnetcurry.com/ShowArticle.aspx?ID=776
Niks

जवाब के लिए धन्यवाद। मैं धाराप्रवाह सत्यापन की जाँच करूँगा, इसके बारे में कभी नहीं सुना। और निक्स, डारिन ने मूल रूप से लिखा था कि आपके द्वारा पोस्ट किए गए लिंक पर लेख ने क्या समझाया। तो, धन्यवाद ... बहुत बढ़िया सामान!
डैनी वैन डेर क्रान

जवाबों:


177

आप एक कस्टम सत्यापन विशेषता लिख ​​सकते हैं:

public class CombinedMinLengthAttribute: ValidationAttribute
{
    public CombinedMinLengthAttribute(int minLength, params string[] propertyNames)
    {
        this.PropertyNames = propertyNames;
        this.MinLength = minLength;
    }

    public string[] PropertyNames { get; private set; }
    public int MinLength { get; private set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var properties = this.PropertyNames.Select(validationContext.ObjectType.GetProperty);
        var values = properties.Select(p => p.GetValue(validationContext.ObjectInstance, null)).OfType<string>();
        var totalLength = values.Sum(x => x.Length) + Convert.ToString(value).Length;
        if (totalLength < this.MinLength)
        {
            return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }
        return null;
    }
}

और फिर आपके पास एक दृश्य मॉडल हो सकता है और इसके गुणों में से एक को इसके साथ सजा सकते हैं:

public class MyViewModel
{
    [CombinedMinLength(20, "Bar", "Baz", ErrorMessage = "The combined minimum length of the Foo, Bar and Baz properties should be longer than 20")]
    public string Foo { get; set; }
    public string Bar { get; set; }
    public string Baz { get; set; }
}

4
उत्तर देने के लिए धन्यवाद, मैंने आपका उत्तर स्वीकार कर लिया। वास्तव में थोड़ा शर्मिंदा महसूस करें। आपने पूरा समाधान लिख दिया! हेहे। अधिकतम लंबाई की जाँच के लिए केवल IsValid फ़ंक्शन को बदलना पड़ा। तो क्या इस प्रकार की समस्याओं के लिए स्वीकृत एमवीसी समाधान है?
डैनी वैन डेर क्रान

7
@DannyvanderKraan, हाँ, यह स्वीकृत तरीका है। बेशक यह इतनी बुरी तरह से बेकार है कि मैं इसका इस्तेमाल कभी नहीं करता हूं और सत्यापन करने के बजाय फ्लुएंविलेजेशन नेट का उपयोग करता हूं।
डारिन दिमित्रोव

11
यहां: fluentvalidation.codeplex.com । आप बस उस दृश्य मॉडल के लिए एक साधारण सत्यापनकर्ता लिख ​​सकते थे जो इस तरह दिख सकता था (कोड की एक पंक्ति) this.RuleFor(x => x.Foo).Must((x, foo) => x.Foo.Length + x.Bar.Length + x.Baz.Length < 20).WithMessage("The combined minimum length of the Foo, Bar and Baz properties should be longer than 20");:। अब मेरे उत्तर के कोड को देखें जिसे आपको डेटा एनोटेशन के साथ लिखना होगा और मुझे बताना होगा कि आप किसे पसंद करते हैं। अनिवार्य मॉडल की तुलना में घोषणात्मक सत्यापन मॉडल बहुत खराब है।
डारिन दिमित्रोव

1
यह थोड़ी देर हो चुकी है, लेकिन क्या किसी को पता है कि कोई अलग सेटिंग है जिसे आपको कस्टम डेटा अनाउंसमेंट की अनुमति देने के लिए "चालू करना" है? मैं web.config फ़ाइल पर unobstrusive js के लिए एक नाम स्थान जोड़ने के बारे में जानता हूं, लेकिन कहीं और?
जोस

1
मैं यह सब सुबह के लिए देख रहा हूँ ! मैंने इसे लागू किया है, और दुर्भाग्य से जब इसे अशक्त IsValidकहा जाता validationContextहै। किसी भी विचार मैंने क्या गलत किया? :-(
ग्रिम द ओपिनर

95

स्व मान्य मॉडल

आपके मॉडल को एक इंटरफ़ेस लागू करना चाहिए IValidatableObjectValidateविधि में अपना सत्यापन कोड डालें :

public class MyModel : IValidatableObject
{
    public string Title { get; set; }
    public string Description { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Title == null)
            yield return new ValidationResult("*", new [] { nameof(Title) });

        if (Description == null)
            yield return new ValidationResult("*", new [] { nameof(Description) });
    }
}

कृपया ध्यान दें: यह एक सर्वर-साइड सत्यापन है। यह क्लाइंट-साइड पर काम नहीं करता है। आपको फॉर्म सबमिट करने के बाद ही सत्यापन किया जाएगा।


आंद्रेई का जवाब देने के लिए धन्यवाद। जबकि आपका समाधान भी काम करेगा मैं डारिन को चुनता हूं क्योंकि यह अधिक पुन: प्रयोज्य है।
डैनी वैन डेर क्रान

6
पैदावार नई वैलिडेशनResult ("शीर्षक अनिवार्य है।", "शीर्षक"); यदि आवश्यक हो तो संपत्ति का नाम, सत्यापन त्रुटियों को समूहीकृत करने में उपयोगी होगा।
माइक किंग्सकोट

5
ध्यान दें कि इस सत्यापन विधि को केवल सभी सत्यापन विशेषताओं के सत्यापन के बाद कहा जाता है।
पेड्रो

3
यह मेरे लिए अच्छा था क्योंकि मेरी मान्यता बहुत विशिष्ट थी। कस्टम विशेषता जोड़ना मेरे लिए ओवरकिल हो गया होगा क्योंकि सत्यापन फिर से उपयोग नहीं किया जा रहा था।
स्टीव एस

यही है जिसकी मेरे द्वारा तलाश की जा रही है। धन्यवाद!
अमोल जाधव

27

ExpressiveAnnotations आपको ऐसी संभावना देता है:

[Required]
[AssertThat("Length(FieldA) + Length(FieldB) + Length(FieldC) + Length(FieldD) > 50")]
public string FieldA { get; set; }

ये जबरदस्त है! मेरी प्रार्थना का उत्तर मिला :)
कोरायेम

बस यह जवाब मिला और यह सिर्फ समय का भार बचा रहा है। ExpressiveAnnotations शानदार हैं!
ब्रैड

10

डारिन के उत्तर को बेहतर बनाने के लिए, इसे थोड़ा छोटा किया जा सकता है:

public class UniqueFileName : ValidationAttribute
{
    private readonly NewsService _newsService = new NewsService();

    public override bool IsValid(object value)
    {
        if (value == null) { return false; }

        var file = (HttpPostedFile) value;

        return _newsService.IsFileNameUnique(file.FileName);
    }
}

नमूना:

[UniqueFileName(ErrorMessage = "This file name is not unique.")]

ध्यान दें कि त्रुटि संदेश की आवश्यकता है, अन्यथा त्रुटि खाली होगी।


8

पृष्ठभूमि:

मॉडल सत्यापन यह सुनिश्चित करने के लिए आवश्यक है कि हमें प्राप्त डेटा वैध और सही है ताकि हम इस डेटा के साथ आगे की प्रक्रिया कर सकें। हम एक मॉडल को एक क्रिया विधि में मान्य कर सकते हैं। अंतर्निहित सत्यापन विशेषताओं की तुलना, रेंज, रेग्युलर एक्सप्रेशन, आवश्यक, स्ट्रिंग लैंथ से की जाती है। हालाँकि हमारे पास ऐसे परिदृश्य हो सकते हैं जिनमें हमें अंतर्निहित विशेषताओं के अलावा अन्य सत्यापन विशेषताओं की आवश्यकता होती है।

कस्टम सत्यापन विशेषताएँ

public class EmployeeModel 
{
    [Required]
    [UniqueEmailAddress]
    public string EmailAddress {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public int OrganizationId {get;set;}
}

एक कस्टम सत्यापन विशेषता बनाने के लिए, आपको इस श्रेणी को ValidationAttribute से प्राप्त करना होगा।

public class UniqueEmailAddress : ValidationAttribute
{
    private IEmployeeRepository _employeeRepository;
    [Inject]
    public IEmployeeRepository EmployeeRepository
    {
        get { return _employeeRepository; }
        set
        {
            _employeeRepository = value;
        }
    }
    protected override ValidationResult IsValid(object value,
                        ValidationContext validationContext)
    {
        var model = (EmployeeModel)validationContext.ObjectInstance;
        if(model.Field1 == null){
            return new ValidationResult("Field1 is null");
        }
        if(model.Field2 == null){
            return new ValidationResult("Field2 is null");
        }
        if(model.Field3 == null){
            return new ValidationResult("Field3 is null");
        }
        return ValidationResult.Success;
    }
}

उम्मीद है की यह मदद करेगा। चियर्स!

संदर्भ


1

जवाब देने में थोड़ा देर हो गई, लेकिन कौन खोज रहा है। आप डेटा एनोटेशन के साथ एक अतिरिक्त संपत्ति का उपयोग करके आसानी से कर सकते हैं:

public string foo { get; set; }
public string bar { get; set; }

[MinLength(20, ErrorMessage = "too short")]
public string foobar 
{ 
    get
    {
        return foo + bar;
    }
}

बस इतना ही यह वास्तव में है। यदि आप वास्तव में सत्यापन त्रुटि के साथ एक विशिष्ट स्थान पर प्रदर्शित करना चाहते हैं, तो आप इसे अपने विचार में जोड़ सकते हैं:

@Html.ValidationMessage("foobar", "your combined text is too short")

यदि आप स्थानीयकरण करना चाहते हैं तो दृश्य में ऐसा करने से काम आ सकता है।

उम्मीद है की यह मदद करेगा!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.