कुछ परिस्थितियों में आवश्यक सत्यापन विशेषता अक्षम करें


138

मैं सोच रहा था कि क्या कुछ नियंत्रक क्रियाओं में आवश्यक सत्यापन विशेषता को अक्षम करना संभव है। मैं यह सोच रहा हूं क्योंकि मेरे एक संपादन फॉर्म पर मुझे उपयोगकर्ता को उन क्षेत्रों के लिए मान दर्ज करने की आवश्यकता नहीं है जो वे पहले ही निर्दिष्ट कर चुके हैं। हालाँकि मैं तब तर्क को लागू करता हूं कि जब वे एक मूल्य दर्ज करते हैं तो यह मॉडल को अपडेट करने के लिए कुछ विशेष तर्क का उपयोग करता है, जैसे हैशिंग मान आदि।

कैसे इस समस्या के आसपास पाने के लिए पर कोई sugestions?

संपादित करें:
और हाँ ग्राहक सत्यापन यहाँ एक समस्या है, क्योंकि यह उन्हें मूल्य दर्ज किए बिना फॉर्म जमा करने की अनुमति नहीं देगा।


3
+1 अच्छा Q. ग्राहक सत्यापन का उल्लेख करना यहाँ अच्छा होगा। एक विकल्प यह है कि RequiredAttrपूरी तरह से हटा दें और जब आपको आवश्यकता हो तो सर्वर साइड जांच करें। लेकिन यह क्लाइंट पर मुश्किल होगा
गिदोन

4
ग्राहक सत्यापन से कुछ क्षेत्रों को अक्षम करने वाले किसी भी व्यक्ति के लिए अंक (jquery सत्यापन के संदर्भों को नहीं हटाते)
गिदोन

हो सकता है कि मुझे आपकी बात याद आ रही हो, लेकिन यदि उपयोगकर्ता ने पहले से ही मानों को पहले ही निर्दिष्ट कर दिया है, तो वे मान पहले से ही मौजूद हैं, और इस प्रकार आवश्यक सत्यापन पारित हो जाएगा। क्या आपका मतलब कुछ और था?
एरिक फनकेनबश

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

1
@ गिदोन: एड्रियन स्मिथ का जवाब देखें: stackoverflow.com/a/9781066/114029
लेनियल मैककैफर्री

जवाबों:


76

व्यू मॉडल का उपयोग करके इस समस्या को आसानी से हल किया जा सकता है। दृश्य मॉडल वे कक्षाएं हैं जो विशेष रूप से किसी दिए गए दृश्य की आवश्यकताओं के अनुरूप होती हैं। इसलिए उदाहरण के लिए आपके मामले में आपके पास निम्नलिखित दृश्य मॉडल हो सकते हैं:

public UpdateViewView
{
    [Required]
    public string Id { get; set; }

    ... some other properties
}

public class InsertViewModel
{
    public string Id { get; set; }

    ... some other properties
}

जिसका उपयोग उनके संबंधित नियंत्रक कार्यों में किया जाएगा:

[HttpPost]
public ActionResult Update(UpdateViewView model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertViewModel model)
{
    ...
}

हमेशा सच नहीं है अगर आपके पास एक बूलियन / बिट है जो अशक्त नहीं है। लेकिन वास्तव में इससे कोई फर्क नहीं पड़ता क्योंकि यह सही या गलत होने जा रहा है। मेरे पास आवश्यक क्षेत्रों को उजागर करने के लिए सीएसएस था और इसने चेकबॉक्सफॉर आइटम को झूठा उजागर किया। मेरा समाधान: $ ("# IsValueTrue")। removeAttr ("डेटा-वैल-आवश्यक");
राबर्ट कोच

अपडेट में हमारे पास आम तौर पर (फॉर्म कलेक्शन संग्रह) होता है। क्या आप कृपया बता सकते हैं कि आप किस तरह से मॉडल का उपयोग कर रहे हैं
राज कुमार

4
नहीं, हमारे पास आमतौर पर नहीं है Update(FormCollection collection), कम से कम मैं कभी नहीं करता। मैं हमेशा एक विशिष्ट दृश्य मॉडल को परिभाषित और उपयोग करता हूं Update(UpdateViewView model):।
डारिन दिमित्रोव

उसी HTTP कार्रवाई के साथ ओवरलोडिंग विधियों की अनुमति नहीं है, इसलिए मुझे ऐसा लगता है कि यह काम नहीं करेगा। क्या मैं कुछ भूल रहा हूँ?
e11s

@ हेड्गी, नहीं, आप कुछ भी याद नहीं कर रहे हैं। यह मेरी पोस्ट में एक गलती है। दूसरी क्रिया विधि को स्पष्ट रूप से कहा जाना चाहिए Insert। इस पर ध्यान दिलाने के लिए धन्यवाद।
डारिन दिमित्रोव

55

यदि आप ग्राहक पक्ष में किसी एक क्षेत्र के लिए सत्यापन को निष्क्रिय करना चाहते हैं तो आप सत्यापन विशेषताओं को इस प्रकार से ओवरराइड कर सकते हैं:

@Html.TexBoxFor(model => model.SomeValue, 
                new Dictionary<string, object> { { "data-val", false }})

20
JQuery के माध्यम से मेरे लिए क्या काम किया: $ ("# SomeValue")। removeAttr ("डेटा-वैल-आवश्यक");
रॉबर्ट कोच

6
मुझे यह तरीका पसंद है लेकिन मुझे फॉर्म सत्यापन विशेषताओं को फिर से पार्स करने की जरूरत है: $ ('फॉर्म')। removeData ('unobtrusiveValidation'); $ ( 'फॉर्म') removeData ( 'सत्यापनकर्ता')। $ .validator.unobtrusive.parse ('आपके फॉर्म के लिए चयनकर्ता');
यानिक

15
@Html.TexBoxFor(model => model.SomeValue, new { data_val = false })- IMO पढ़ने में आसान।
eth0

मुझे यह पसंद आया कि मुझे प्रत्येक क्षेत्र में एक अच्छा नियंत्रण देने के लिए छोड़ दिया जाए, लेकिन जब आप POST से बचाने के लिए डेटा भेजते हैं तो आप ModelState.IsValid को रद्द कर सकते हैं। शायद कुछ जोखिम का कारण?
फेलिप FMMobile

4
यदि आप इसे jQuery के माध्यम से अक्षम करना चाहते हैं:$(".search select").attr('data-val', false);
लेनियल मैकाफेर्री

40

मुझे पता है कि इस सवाल का जवाब बहुत पहले दिया गया है और स्वीकृत जवाब वास्तव में काम करेगा। लेकिन एक बात है जो मुझे परेशान करती है: एक सत्यापन को अक्षम करने के लिए केवल 2 मॉडल की प्रतिलिपि बनाना।

यहाँ मेरा सुझाव है:

public class InsertModel
{
    [Display(...)]
    public virtual string ID { get; set; }

    ...Other properties
}

public class UpdateModel : InsertModel
{
    [Required]
    public override string ID
    {
        get { return base.ID; }
        set { base.ID = value; }
    }
}

इस तरह, आपको क्लाइंट / सर्वर साइड सत्यापन के साथ परेशान नहीं होना है, फ्रेमवर्क उस तरीके का व्यवहार करेगा जो इसे माना जाता है। इसके अलावा, यदि आप [Display]बेस क्लास पर एक विशेषता परिभाषित करते हैं, तो आपको इसे अपने में फिर से परिभाषित करने की आवश्यकता नहीं है UpdateModel

और आप अभी भी इन वर्गों का उसी तरह उपयोग कर सकते हैं:

[HttpPost]
public ActionResult Update(UpdateModel model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertModel model)
{
    ...
}

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

मैंने कुछ इस तरह से भी सोचा, हालाँकि मेरे पास एक दृश्यमॉडल है जिसमें एक ऑब्जेक्ट 'प्रोजेक्ट' है जिसमें कई गुण हैं और मैं केवल कुछ विशेषताओं के तहत इनमें से एक विशेषता को मान्य करना चाहता हूं। मुझे नहीं लगता कि मैं सिर्फ एक वस्तु की विशेषता को ओवरराइड कर सकता हूं? कोई सलाह?
विंसेंट डी जी

आप विशेषता को ओवरराइड नहीं कर सकते। बेस क्लास में सभी उप वर्गों के लिए केवल सामान्य विशेषताएँ होनी चाहिए। फिर, आपके उप-वर्गों को उन विशेषताओं को परिभाषित करना चाहिए जिनकी उन्हें आवश्यकता है।
फिल्डकुलैक

1
सबसे सुरुचिपूर्ण, पुन: प्रयोज्य, स्पष्ट समाधान। प्रतिकृति खराब हैं। बहुरूपता रास्ता है। +1
T-moty

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

27

आप अपने नियंत्रक कार्रवाई में निम्नलिखित के साथ एक संपत्ति से सभी सत्यापन को हटा सकते हैं।

ModelState.Remove<ViewModel>(x => x.SomeProperty);

@ MVC5 के बारे में इयान की टिप्पणी

निम्नलिखित अभी भी संभव है

ModelState.Remove("PropertyNameInModel");

बिट कष्टप्रद है कि आप अपडेट किए गए एपीआई के साथ स्थिर टाइपिंग खो देते हैं। आप HTML सहायक की आवृत्ति बनाकर और NameExtensions Methods का उपयोग करके पुराने तरीके के समान कुछ हासिल कर सकते हैं ।


सिवाय ... ModelStateउस हस्ताक्षर से मेल खाता कोई विधि नहीं है । एमवीसी 5 में नहीं, कम से कम।
इयान केम्प

सवाल यह नहीं था कि सभी सत्यापन को कैसे हटाया जाए। यह आवश्यक फ़ील्ड सत्यापन को हटाने का तरीका था। आप अन्य सत्यापन नियमों को छोड़ते हुए ऐसा करना चाह सकते हैं।
रिचर्ड

15

ग्राहक पक्ष किसी प्रपत्र के लिए सत्यापन अक्षम करने के लिए, मेरे शोध पर आधारित कई विकल्प नीचे दिए गए हैं। उनमें से एक उम्मीद है कि आप के लिए काम करेंगे।

विकल्प 1

मैं इसे पसंद करता हूं, और यह मेरे लिए पूरी तरह से काम करता है।

(function ($) {
    $.fn.turnOffValidation = function (form) {
        var settings = form.validate().settings;

        for (var ruleIndex in settings.rules) {
            delete settings.rules[ruleIndex];
        }
    };
})(jQuery); 

और इसे लागू करना

$('#btn').click(function () {
    $(this).turnOffValidation(jQuery('#myForm'));
});

विकल्प 2

$('your selector here').data('val', false);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

विकल्प 3

var settings = $.data($('#myForm').get(0), 'validator').settings;
settings.ignore = ".input";

विकल्प 4

 $("form").get(0).submit();
 jQuery('#createForm').unbind('submit').submit();

विकल्प 5

$('input selector').each(function () {
    $(this).rules('remove');
});

सर्वर साइड

एक विशेषता बनाएं और उस विशेषता के साथ अपनी क्रिया विधि चिह्नित करें। अपनी विशिष्ट आवश्यकताओं के अनुकूल इसे अनुकूलित करें।

[AttributeUsage(AttributeTargets.All)]
public class IgnoreValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var modelState = filterContext.Controller.ViewData.ModelState;

        foreach (var modelValue in modelState.Values)
        {
            modelValue.Errors.Clear();
        }
    }
}

एक बेहतर दृष्टिकोण का वर्णन यहां किया गया है सक्षम करें / निष्क्रिय करें mvc सर्वर साइड को गतिशील रूप से अक्षम करें


$ ('इनपुट चयनकर्ता')। प्रत्येक (फ़ंक्शन () {$ (यह) .rules ('निकालें';})); मेरी मदद की
सचिन पकाले

सवाल विशेष रूप से आवश्यक क्षेत्र सत्यापन को हटाने के बारे में था, सभी सत्यापन को हटाने के बारे में नहीं। आपका उत्तर सभी सत्यापन को हटाने के बारे में है।
रिचर्ड

14

व्यक्तिगत रूप से मैं डारिन दिमित्रोव को अपने समाधान में दिखाए गए दृष्टिकोण का उपयोग करना चाहूंगा। यह आपको सत्यापन के साथ डेटा एनोटेशन दृष्टिकोण का उपयोग करने में सक्षम बनाता है और प्रत्येक ViewModel पर अलग-अलग डेटा विशेषताएँ हाथ में कार्य के अनुरूप है। मॉडल और viewmodel आप AutoMapper या पर गौर करना चाहिए के बीच कॉपी के लिए काम करते की मात्रा को कम करने के लिए ValueInjecter । दोनों के पास अपने व्यक्तिगत मजबूत बिंदु हैं, इसलिए उन दोनों की जांच करें।

आपके लिए एक और संभावित तरीका यह होगा कि आप अपने दृश्यमॉडल या मॉडल को IValidatableObject से प्राप्त करें। यह आपको एक फ़ंक्शन Validate को लागू करने का विकल्प देता है। मान्य में आप सत्यापन की सूची या तो तत्वों को वापस कर सकते हैं या सत्यापन में पता लगाने वाली प्रत्येक समस्या के लिए उपज रिटर्न जारी कर सकते हैं।

ValidationResult में एक त्रुटि संदेश और फ़ील्डनाम के साथ तार की एक सूची होती है। त्रुटि संदेशों को इनपुट फ़ील्ड (एस) के पास एक स्थान पर दिखाया जाएगा।

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
  if( NumberField < 0 )
  {
    yield return new ValidationResult( 
        "Don't input a negative number", 
        new[] { "NumberField" } );
  }

  if( NumberField > 100 )
  {
    yield return new ValidationResult( 
        "Don't input a number > 100", 
        new[] { "NumberField" } );
  }

  yield break;
}

क्या हम इसे क्लाइंट पक्ष पर हुक कर सकते हैं?
मुहम्मद अदील जाहिद

क्लाइंट-साइड सत्यापन आम तौर पर व्यक्तिगत क्षेत्रों के लिए किया जाता है, उपयोगकर्ता के लिए एक सुविधा के रूप में, इंटरैक्टिव, फील्ड-बाय-फील्ड सत्यापन प्रतिक्रिया का प्रदर्शन करता है। चूंकि ऑब्जेक्ट-वैलिडेशन स्टेप में आम तौर पर निर्भर सत्यापन (कई फ़ील्ड और / या स्थितियाँ जो ऑब्जेक्ट के लिए बाहरी हैं) शामिल हैं, यह आवश्यक रूप से क्लाइंट-साइड पर नहीं किया जा सकता है, भले ही आप जावास्क्रिप्ट को कोड संकलित कर सकें। यदि क्लाइंट-साइड पर जटिल / निर्भर सत्यापन आपके मामले में मूल्य जोड़ता है, तो आपको ऑन-साइट-कॉलबैक का उपयोग करने और क्लाइंट-साइड पर सत्यापन तर्क की नकल करने की आवश्यकता होगी।
mindplay.dk

7

यहां सबसे साफ तरीका है कि मेरा मानना ​​है कि आपके ग्राहक पक्ष सत्यापन को अक्षम करने जा रहा है और सर्वर साइड पर आपको निम्न की आवश्यकता होगी:

  1. ModelState ["SomeField"]। त्रुटियां। (अपने नियंत्रक में या नियंत्रक कोड निष्पादित होने से पहले त्रुटियों को दूर करने के लिए एक एक्शन फ़िल्टर बनाएं)
  2. जब आप अपने पहचाने गए मुद्दों का उल्लंघन करते हैं तो अपने नियंत्रक कोड से ModelState.AddModelError जोड़ें।

यहां तक ​​कि एक कस्टम व्यू मॉडल भी समस्या को हल नहीं करता है क्योंकि उन 'पूर्व उत्तर दिए गए' फ़ील्ड की संख्या भिन्न हो सकती है। यदि वे नहीं तो एक कस्टम दृश्य मॉडल वास्तव में सबसे आसान तरीका हो सकता है, लेकिन उपरोक्त तकनीक का उपयोग करके आप अपने सत्यापन मुद्दों के आसपास प्राप्त कर सकते हैं।


1
यही वह चीज है जिसकी मुझे जरूरत थी। मेरे पास इस दृश्य में एक दृश्य और अलग-अलग क्रियाएं होती हैं, इसलिए मैं इसे अलग-अलग ViewModels के साथ नहीं बना सका। यह एक आकर्षण की तरह काम करता है
ggderas

6

यह टिप्पणियों में किसी और का उत्तर था ... लेकिन यह एक वास्तविक उत्तर होना चाहिए:

$("#SomeValue").removeAttr("data-val-required")

MVC 6 पर एक क्षेत्र के साथ परीक्षण किया गया [Required]विशेषता

https://stackoverflow.com/users/73382/rob ऊपर से चोरी जवाब


1
सर्वर साइड सत्यापन के बारे में क्या?
T- मोटिवेशनल

ModelState.Remove, है ना? किसी भी दर पर, मेरे लिए, मुद्दा यह था कि मेरे मॉडल में एक दूसरी संस्था को शामिल किया जा रहा था ... जिस प्राथमिक पर मुझे सत्यापन चाहिए था, लेकिन माध्यमिक को उस पृष्ठ पर सत्यापन की आवश्यकता नहीं थी ... इसलिए, इस परिदृश्य के तहत , केवल JQuery आवश्यक था।
माइक_मैथ्यूज_II

मुझे लगता है कि लिंक टूट गया है, इसलिए कृपया संपादित करें। यह आंशिक उत्तर है
T-moty

यह अजीब है कि आप कहते हैं कि यह एमवीसी 6 में काम करता है (मेरे पास वर्तमान में एमवीसी 6 पर परीक्षण करने का विकल्प नहीं है) लेकिन मेरे लिए एमवीसी 4 पर काम नहीं करता है जिसका मैं वर्तमान में उपयोग कर रहा हूं।
eaglei22

सवाल MVC / C # के लिए है - JS नहीं, जवाब सर्वर की तरफ से काम नहीं करेगा
mtbennett

2

जब मैं अपने मॉडल के लिए एक एडिट व्यू बना रहा था तो मुझे यह समस्या आ रही थी और मैं सिर्फ एक फील्ड को अपडेट करना चाहता हूं।

एक सरल तरीके से मेरे समाधान का उपयोग करके दो क्षेत्र डाल दिए गए हैं:

 <%: Html.HiddenFor(model => model.ID) %>
 <%: Html.HiddenFor(model => model.Name)%>
 <%: Html.HiddenFor(model => model.Content)%>
 <%: Html.TextAreaFor(model => model.Comments)%>

टिप्पणियां वह क्षेत्र है जिसे मैं केवल संपादन दृश्य में अपडेट करता हूं, जिसमें आवश्यक विशेषता नहीं है।

ASP.NET MVC 3 इकाई


1

AFAIK आप रनटाइम पर विशेषता नहीं हटा सकते हैं, लेकिन केवल उनके मूल्यों को बदल सकते हैं (जैसे: आसानी से सच / गलत) कुछ समान के लिए यहां देखें । जैसा कि आप विशेषताओं के साथ खिलवाड़ किए बिना क्या करना चाहते हैं के एक अन्य तरीके के रूप में मैं आपके विशिष्ट कार्रवाई के लिए एक ViewModel के साथ जाऊंगा ताकि आप अन्य नियंत्रकों द्वारा आवश्यक तर्क को तोड़ने के बिना सभी तर्क सम्मिलित कर सकें। यदि आप कुछ प्रकार के विज़ार्ड (एक मल्टी स्टेप फॉर्म) प्राप्त करने की कोशिश करते हैं, तो आप इसके बजाय पहले से संकलित फ़ील्ड को क्रमबद्ध कर सकते हैं और TempData के साथ उन्हें अपने चरणों में ला सकते हैं। (क्रमबद्ध रूप से मदद के लिए आप MVC वायदा का उपयोग कर सकते हैं )


1

@ डारिन ने जो कहा वह मैं भी सुझाऊँगी। हालाँकि, मैं इसे (और टिप्पणियों में से एक के जवाब में) जोड़ूंगा कि आप वास्तव में बिट, बूल, यहां तक ​​कि संरचनाओं जैसे आदिम प्रकारों के लिए इस पद्धति का उपयोग कर सकते हैं, जैसे कि गाइड द्वारा उन्हें केवल अशक्त बनाकर। एक बार जब आप ऐसा करते हैं, तो Requiredविशेषता अपेक्षित रूप से कार्य करती है।

public UpdateViewView
{
    [Required]
    public Guid? Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public int? Age { get; set; }
    [Required]
    public bool? IsApproved { get; set; }
    //... some other properties
}

1

MVC 5 के रूप में इसे आसानी से अपने में जोड़कर प्राप्त किया जा सकता है global.asax

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

1

मैं एक ऐसे समाधान की तलाश में था जहाँ मैं एक ही मॉडल को वेब एप में डालने और अपडेट के लिए उपयोग कर सकूं। मेरी स्थिति में यह हमेशा एक शरीर सामग्री है। [Requiered]अगर यह एक अद्यतन विधि है विशेषताओं को छोड़ दिया जाना चाहिए। मेरे समाधान में, आप [IgnoreRequiredValidations]विधि के ऊपर एक विशेषता रखते हैं । यह इस प्रकार है:

public class WebServiceController : ApiController
{
    [HttpPost]
    public IHttpActionResult Insert(SameModel model)
    {
        ...
    }

    [HttpPut]
    [IgnoreRequiredValidations]
    public IHttpActionResult Update(SameModel model)
    {
        ...
    }

    ...

और क्या करने की जरूरत है? एक खुद का BodyModelValidator शुरू किया जाना चाहिए और स्टार्टअप में जोड़ा जाना चाहिए। यह HttpConfiguration में है और इस तरह दिखता है:config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());

using Owin;
using your_namespace.Web.Http.Validation;

[assembly: OwinStartup(typeof(your_namespace.Startup))]

namespace your_namespace
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            Configuration(app, new HttpConfiguration());
        }

        public void Configuration(IAppBuilder app, HttpConfiguration config)
        {
            config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());
        }

        ...

मेरा अपना BodyModelValidator DefaultBodyModelValidator से लिया गया है। और मुझे पता है कि मुझे 'ShallowValidate' मेथोड को ओवरराइड करना था। इस ओवरराइड में मैं अपेक्षित मॉडल सत्यापनकर्ताओं को फ़िल्टर करता हूं। और अब IgnoreRequiredOrDefaultBodyModelValidator वर्ग और IgnoreRequiredValidations एंटाइटेल क्लास:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Metadata;
using System.Web.Http.Validation;

namespace your_namespace.Web.Http.Validation
{
    public class IgnoreRequiredOrDefaultBodyModelValidator : DefaultBodyModelValidator
    {
        private static ConcurrentDictionary<HttpActionBinding, bool> _ignoreRequiredValidationByActionBindingCache;

        static IgnoreRequiredOrDefaultBodyModelValidator()
        {
            _ignoreRequiredValidationByActionBindingCache = new ConcurrentDictionary<HttpActionBinding, bool>();
        }

        protected override bool ShallowValidate(ModelMetadata metadata, BodyModelValidatorContext validationContext, object container, IEnumerable<ModelValidator> validators)
        {
            var actionContext = validationContext.ActionContext;

            if (RequiredValidationsIsIgnored(actionContext.ActionDescriptor.ActionBinding))
                validators = validators.Where(v => !v.IsRequired);          

            return base.ShallowValidate(metadata, validationContext, container, validators);
        }

        #region RequiredValidationsIsIgnored
        private bool RequiredValidationsIsIgnored(HttpActionBinding actionBinding)
        {
            bool ignore;

            if (!_ignoreRequiredValidationByActionBindingCache.TryGetValue(actionBinding, out ignore))
                _ignoreRequiredValidationByActionBindingCache.TryAdd(actionBinding, ignore = RequiredValidationsIsIgnored(actionBinding.ActionDescriptor as ReflectedHttpActionDescriptor));

            return ignore;
        }

        private bool RequiredValidationsIsIgnored(ReflectedHttpActionDescriptor actionDescriptor)
        {
            if (actionDescriptor == null)
                return false;

            return actionDescriptor.MethodInfo.GetCustomAttribute<IgnoreRequiredValidationsAttribute>(false) != null;
        } 
        #endregion
    }

    [AttributeUsage(AttributeTargets.Method, Inherited = true)]
    public class IgnoreRequiredValidationsAttribute : Attribute
    {

    }
}

सूत्रों का कहना है:


0

यदि आप किसी अन्य ViewModel का उपयोग नहीं करना चाहते हैं तो आप दृश्य पर क्लाइंट सत्यापन को अक्षम कर सकते हैं और उन गुणों के लिए सर्वर पर मान्यताओं को भी हटा सकते हैं जिन्हें आप अनदेखा करना चाहते हैं। कृपया इस उत्तर की गहन व्याख्या के लिए https://stackoverflow.com/a/15248790/1128216 देखें


0

मेरे मामले में उसी मॉडल का उपयोग कई पृष्ठों में पुन: प्रयोज्य उद्देश्यों के लिए किया गया था। तो मैंने क्या किया मैं एक कस्टम विशेषता बनाया है जो बहिष्करण के लिए जाँच करता है

public class ValidateAttribute : ActionFilterAttribute
{
    public string Exclude { get; set; }
    public string Base { get; set; }
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!string.IsNullOrWhiteSpace(this.Exclude))
        {
            string[] excludes = this.Exclude.Split(',');
            foreach (var exclude in excludes)
            {
                actionContext.ModelState.Remove(Base + "." + exclude);
            }
        }
        if (actionContext.ModelState.IsValid == false)
        {
            var mediaType = new MediaTypeHeaderValue("application/json");
            var error = actionContext.ModelState;

            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, error.Keys, mediaType);

        }
    }
}

और अपने नियंत्रक में

[Validate(Base= "person",Exclude ="Age,Name")]
    public async Task<IHttpActionResult> Save(User person)
    {

            //do something           

    }

कहो मॉडल है

public class User
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Range(18,99)]
    public string Age { get; set; }
    [MaxLength(250)]
    public string Address { get; set; }
}

-1

हाँ, आवश्यक विशेषता को निष्क्रिय करना संभव है। RequiredAtribute से सीमा तक अपनी स्वयं की कस्टम क्लास विशेषता (चेंजेबिल रेयर नामक नमूना कोड) बनाएं और एक अक्षम संपत्ति जोड़ें और यह जांचने के लिए IsValid विधि को ओवरराइड करें कि क्या यह असंतुलित है। अक्षम लोगों की तरह सेट करने के लिए प्रतिबिंब का उपयोग करें, जैसे:

कस्टम विशेषता:

namespace System.ComponentModel.DataAnnotations
{
    public class ChangeableRequired : RequiredAttribute
    {
       public bool Disabled { get; set; }

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

          return base.IsValid(value);
       }
    }
}

अपने नए कस्टम विशेषता का उपयोग करने के लिए आपको संपत्ति अपडेट करें:

 class Forex
 {
 ....
    [ChangeableRequired]
    public decimal? ExchangeRate {get;set;}
 ....
 }

जहां आपको इसे सेट करने के लिए प्रॉपर्टी उपयोग प्रतिबिंब को अक्षम करने की आवश्यकता है:

Forex forex = new Forex();
// Get Property Descriptor from instance with the Property name
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(forex.GetType())["ExchangeRate"];
//Search for Attribute
ChangeableRequired attrib =  (ChangeableRequired)descriptor.Attributes[typeof(ChangeableRequired)];

// Set Attribute to true to Disable
attrib.Disabled = true;

यह अच्छा और साफ लगता है?

नायब: ऊपर सत्यापन को निष्क्रिय कर दिया जाएगा, जबकि आपकी वस्तु आवृत्ति जीवित है ...


इस पर कुछ बहस के बाद मैं यह उल्लेख करना चाहूंगा कि मैं सत्यापन को अक्षम करने की अनुशंसा नहीं करता, बल्कि नियम की समीक्षा करता हूं। यदि आप इसे अक्षम करते हैं, तो आप नियम को फिर से सक्षम करने के लिए एक निर्भरता बना रहे हैं और मैं सुझाव दूंगा कि नियम की समीक्षा करें।
अर्नेस्ट गनिंग

उसी प्रक्रिया के भीतर निष्पादित उस क्षेत्र के सभी सत्यापन को पूरी तरह से अक्षम करने के लिए एक स्थिर मूल्य बदलना एक भयानक विचार जैसा लगता है।
जेरेमी लक्ष्मण
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.