Nonaktifkan atribut validasi yang diperlukan dalam keadaan tertentu

138

Saya bertanya-tanya apakah mungkin untuk menonaktifkan atribut validasi yang diperlukan dalam tindakan pengontrol tertentu. Saya bertanya-tanya ini karena pada salah satu formulir edit saya, saya tidak mengharuskan pengguna memasukkan nilai untuk bidang yang telah mereka tentukan sebelumnya. Namun saya kemudian mengimplementasikan logika yang ketika mereka memasukkan nilai itu menggunakan beberapa logika khusus untuk memperbarui model, seperti hashing nilai dll.

Adakah saran tentang cara mengatasi masalah ini?

EDIT:
Dan ya, validasi klien adalah masalah di sini, karena tidak memungkinkan mereka untuk mengirimkan formulir tanpa memasukkan nilai.

Alex Hope O'Connor
sumber
3
+1 bagus Q. Akan lebih baik untuk menyebutkan validasi klien di sini. Salah satu opsinya adalah menghapus RequiredAttrseluruhnya dan melakukan pemeriksaan sisi server bila Anda perlu. Tetapi ini akan menjadi rumit pada klien
gideon
4
Poin untuk siapa saja yang juga mencakup menonaktifkan bidang tertentu dari validasi klien (tidak menghapus referensi ke validasi jquery)
gideon
Mungkin saya kehilangan maksud Anda, tetapi jika pengguna telah menentukan nilai sebelumnya, maka nilai-nilai tersebut sudah ada, dan dengan demikian akan lolos validasi yang diperlukan. Apakah maksud Anda sesuatu yang lain?
Erik Funkenbusch
Karena nilai-nilai ini telah di-hash, seperti kata sandi dan jawaban keamanan, jadi jika mereka memasukkan nilai baru pada formulir edit, saya ingin melakukan hash ulang nilai baru sebelum penyisipan, tetapi saya juga ingin opsi untuk itu dikosongkan semacam itu.
Alex Hope O'Connor
1
@gideon: lihat jawaban Adrian Smith: stackoverflow.com/a/9781066/114029
Leniel Maccaferri

Jawaban:

78

Masalah ini dapat dengan mudah diselesaikan dengan menggunakan model tampilan. Model tampilan adalah kelas yang secara khusus disesuaikan dengan kebutuhan tampilan tertentu. Jadi misalnya dalam kasus Anda, Anda dapat memiliki model tampilan berikut:

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

    ... some other properties
}

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

    ... some other properties
}

yang akan digunakan dalam aksi pengontrol yang sesuai:

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

[HttpPost]
public ActionResult Insert(InsertViewModel model)
{
    ...
}
Darin Dimitrov
sumber
Tidak selalu benar jika Anda memiliki boolean / bit yang tidak dapat dinolkan. Tapi sebenarnya tidak ada bedanya karena akan berakhir benar atau salah. Saya memiliki css untuk menyorot bidang yang diperlukan dan itu salah menyorot item Kotak centang. Solusi saya: $ ("# IsValueTrue"). RemoveAttr ("data-val-required");
Robert Koch
Dalam pembaruan kami biasanya memiliki (koleksi FormCollection). bisakah Anda menjelaskan bagaimana Anda menggunakan model sebagai parameter
Raj Kumar
4
Tidak, biasanya kami tidak punya Update(FormCollection collection), setidaknya saya tidak pernah melakukannya. Saya selalu menentukan dan menggunakan tampilan model spesifik: Update(UpdateViewView model).
Darin Dimitrov
Metode overloading dengan tindakan HTTP yang sama tidak diperbolehkan, jadi bagi saya sepertinya ini tidak akan berhasil. Apakah saya melewatkan sesuatu?
e11s
@edgi, tidak, Anda tidak melewatkan apa pun. Itu adalah kesalahan dalam postingan saya. Metode tindakan kedua jelas harus dipanggil Insert. Terima kasih telah menunjukkan hal ini.
Darin Dimitrov
55

Jika Anda hanya ingin menonaktifkan validasi untuk satu bidang di sisi klien, Anda dapat mengganti atribut validasi sebagai berikut:

@Html.TextBoxFor(model => model.SomeValue, 
                new Dictionary<string, object> { { "data-val", false }})
Adrian Smith
sumber
21
Apa yang berhasil untuk saya melalui jQuery: $ ("# SomeValue"). RemoveAttr ("data-val-required");
Robert Koch
7
Saya suka pendekatan ini tetapi saya perlu mengurai ulang atribut validasi formulir menggunakan: $ ('form'). RemoveData ('unobtrusiveValidation'); $ ('form'). removeData ('validator'); $ .validator.unobtrusive.parse ('selector for your form');
Yannick Smits
15
@Html.TexBoxFor(model => model.SomeValue, new { data_val = false })- lebih mudah membaca IMO.
eth0
Saya menyukai sebagian besar pendekatan ini agar saya memberikan kontrol yang baik untuk setiap bidang, tetapi Anda dapat menambahkan untuk membatalkan ModelState.IsValid saat mengirim data untuk disimpan dengan POST. Mungkin menimbulkan risiko?
Felipe FMMobile
4
Jika Anda ingin menonaktifkannya melalui jQuery:$(".search select").attr('data-val', false);
Leniel Maccaferri
41

Saya tahu pertanyaan ini telah dijawab sejak lama dan jawaban yang diterima benar-benar akan berhasil. Tetapi ada satu hal yang mengganggu saya: harus menyalin 2 model hanya untuk menonaktifkan validasi.

Inilah saran saya:

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; }
    }
}

Dengan cara ini, Anda tidak perlu repot dengan validasi sisi klien / server, kerangka kerja akan berperilaku sebagaimana mestinya. Selain itu, jika Anda mendefinisikan [Display]atribut di kelas dasar, Anda tidak perlu mendefinisikannya kembali di UpdateModel.

Dan Anda masih dapat menggunakan kelas-kelas ini dengan cara yang sama:

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

[HttpPost]
public ActionResult Insert(InsertModel model)
{
    ...
}
PhilDulac
sumber
Saya lebih menyukai pendekatan ini, terutama jika Anda memiliki daftar panjang atribut validasi. Dalam contoh Anda, Anda dapat menambahkan lebih banyak atribut di kelas dasar agar manfaatnya lebih jelas. Satu-satunya kelemahan yang dapat saya lihat adalah tidak ada cara mewarisi properti untuk menimpa atribut. Misalnya, jika Anda memiliki properti [Wajib] di kelas dasar, properti warisan dipaksa menjadi [Wajib] juga, kecuali Anda memiliki atribut khusus [Opsional].
Yorro
Saya memikirkan sesuatu seperti ini juga, meskipun saya memiliki viewModel yang memiliki objek 'Proyek' yang memiliki beberapa atribut dan saya hanya ingin salah satu atribut ini divalidasi dalam keadaan tertentu. Saya tidak berpikir saya bisa mengganti atribut suatu objek, kan? ada saran?
vincent de g
Anda tidak dapat mengganti atribut. Kelas dasar seharusnya hanya berisi atribut umum untuk semua sub kelas. Kemudian, sub kelas Anda harus menentukan atribut yang mereka butuhkan.
PhilDulac
1
Solusi paling elegan, dapat digunakan kembali, dan jelas. Replikasi itu buruk. Polimorfisme adalah caranya. +1
T-moty
dalam kasus saya kelas dasar memiliki atribut yang diperlukan dan saya ingin membuatnya tidak diperlukan di kelas induk saya. Apakah mungkin tanpa dua salinan model?
Alexey Strakh
29

Anda dapat menghapus semua validasi dari sebuah properti dengan mengikuti tindakan pengontrol Anda.

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

Komentar @ Ian tentang MVC5

Berikut ini masih memungkinkan

ModelState.Remove("PropertyNameInModel");

Agak mengganggu karena Anda kehilangan pengetikan statis dengan API yang diperbarui. Anda bisa mencapai sesuatu yang mirip dengan cara lama dengan membuat instance pembantu HTML dan menggunakan Metode NameExtensions .

jps
sumber
Kecuali ... tidak ada metode ModelStateyang cocok dengan tanda tangan itu. Tidak di MVC 5, setidaknya.
Ian Kemp
Pertanyaannya bukanlah bagaimana menghapus semua validasi. Itu adalah cara menghapus validasi bidang yang diperlukan. Anda mungkin ingin melakukan ini sambil membiarkan aturan validasi lainnya tetap berlaku.
Richard
Ini memang solusi terbaik dan yang berhasil untuk saya bahkan di .net core terima kasih @jps ModelState.Remove ("PropertyNameInModel");
rogue39nin
17

Sisi klien Untuk menonaktifkan validasi formulir, beberapa opsi berdasarkan penelitian saya diberikan di bawah ini. Salah satunya mudah-mudahan akan berhasil untuk Anda.

Pilihan 1

Saya lebih suka ini, dan ini bekerja dengan sempurna untuk saya.

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

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

dan memintanya seperti

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

pilihan 2

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

Pilihan 3

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

Pilihan 4

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

Pilihan 5

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

Sisi server

Buat atribut dan tandai metode tindakan Anda dengan atribut itu. Sesuaikan ini untuk menyesuaikan dengan kebutuhan spesifik Anda.

[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();
        }
    }
}

Pendekatan yang lebih baik telah dijelaskan di sini Mengaktifkan / Menonaktifkan validasi sisi server mvc secara dinamis

int-i
sumber
$ ('input selector'). each (function () {$ (this) .rules ('remove');}); membantu saya
Sachin Pakale
Pertanyaannya secara khusus tentang menghapus validasi bidang yang diperlukan, bukan tentang menghapus semua validasi. Jawaban Anda adalah tentang menghapus semua validasi.
Richard
14

Secara pribadi saya akan cenderung menggunakan pendekatan yang ditunjukkan Darin Dimitrov dalam solusinya. Ini membebaskan Anda untuk dapat menggunakan pendekatan anotasi data dengan validasi DAN memiliki atribut data terpisah pada setiap ViewModel yang sesuai dengan tugas yang sedang ditangani. Untuk meminimalkan jumlah pekerjaan untuk menyalin antara model dan viewmodel, Anda harus melihat AutoMapper atau ValueInjecter . Keduanya memiliki kelebihan masing-masing, jadi periksalah keduanya.

Pendekatan lain yang mungkin untuk Anda adalah mendapatkan viewmodel atau model dari IValidatableObject. Ini memberi Anda opsi untuk mengimplementasikan fungsi Validasi. Dalam validasi, Anda dapat mengembalikan elemen List of ValidationResult atau mengeluarkan hasil untuk setiap masalah yang Anda deteksi dalam validasi.

ValidationResult terdiri dari pesan kesalahan dan daftar string dengan nama bidang. Pesan kesalahan akan ditampilkan di lokasi dekat kolom input.

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;
}
nttakr
sumber
bisakah kita menghubungkan ini di sisi klien?
Muhammad Adeel Zahid
validasi sisi klien umumnya dilakukan hanya untuk bidang individu, melakukan umpan balik validasi interaktif bidang demi bidang, sebagai kenyamanan bagi pengguna. Karena langkah validasi objek umumnya melibatkan validasi dependen (beberapa bidang dan / atau kondisi yang berada di luar objek itu sendiri), langkah ini tidak dapat selalu dilakukan di sisi klien, meskipun Anda dapat mengompilasi kode ke JavaScript. Jika validasi kompleks / dependen di sisi klien menambah nilai dalam kasus Anda, Anda perlu menggunakan onsubmit-callback dan menggandakan logika validasi di sisi klien.
mindplay.dk
8

Cara terbersih di sini saya percaya akan menonaktifkan validasi sisi klien Anda dan di sisi server Anda perlu:

  1. ModelState ["SomeField"]. Errors.Clear (di pengontrol Anda atau buat filter tindakan untuk menghapus kesalahan sebelum kode pengontrol dijalankan)
  2. Tambahkan ModelState.AddModelError dari kode pengontrol Anda saat Anda mendeteksi pelanggaran pada masalah yang terdeteksi.

Tampaknya model tampilan kustom di sini tidak akan menyelesaikan masalah karena jumlah kolom 'yang dijawab sebelumnya' dapat bervariasi. Jika tidak, maka model tampilan kustom mungkin memang cara termudah, tetapi menggunakan teknik di atas, Anda dapat mengatasi masalah validasi Anda.

Adam Tuliper - MSFT
sumber
1
Inilah yang saya butuhkan. Saya memiliki satu tampilan dan tindakan yang berbeda terjadi dalam tampilan ini, jadi saya tidak dapat membuatnya dengan ViewModels yang berbeda. Ini bekerja seperti pesona
ggderas
6

ini adalah jawaban orang lain di komentar ... tetapi itu harus menjadi jawaban nyata:

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

diuji pada MVC 6 dengan bidang yang memiliki [Required]atribut

jawaban dicuri dari https://stackoverflow.com/users/73382/rob di atas

Mike_Matthews_II
sumber
1
Bagaimana dengan validasi sisi server?
T-moty
ModelState.Remove, bukan? Bagaimanapun, bagi saya, masalahnya adalah saya memiliki entitas kedua yang disertakan dalam model saya ... entitas utama yang ingin saya validasi, tetapi entitas sekunder tidak memerlukan validasi pada halaman itu ... jadi, dalam skenario ini , hanya JQuery yang diperlukan.
Mike_Matthews_II
Saya pikir tautannya rusak, jadi harap edit. Ini adalah sebagian jawaban
T-moty
Aneh rasanya Anda mengatakan ini berfungsi di MVC6 (saat ini saya tidak memiliki opsi untuk menguji MVC6) tetapi tidak berfungsi untuk saya di MVC4 yang saat ini saya gunakan.
eaglei22
Pertanyaannya adalah untuk MVC / C # - bukan JS, jawabannya tidak akan berfungsi di sisi server
mtbennett
2

Saya mengalami masalah ini saat membuat Tampilan Edit untuk Model saya dan saya hanya ingin memperbarui satu bidang.

Solusi saya untuk cara paling sederhana adalah meletakkan dua bidang menggunakan:

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

Komentar adalah bidang yang hanya saya perbarui di Tampilan Edit, yang tidak memiliki Atribut Wajib.

Entitas ASP.NET MVC 3

Felipe FMMobile
sumber
1

AFAIK Anda tidak dapat menghapus atribut saat runtime, tetapi hanya mengubah nilainya (yaitu: readonly true / false) lihat di sini untuk sesuatu yang serupa . Sebagai cara lain untuk melakukan apa yang Anda inginkan tanpa mengotak-atik atribut, saya akan menggunakan ViewModel untuk tindakan spesifik Anda sehingga Anda dapat memasukkan semua logika tanpa merusak logika yang dibutuhkan oleh pengontrol lain. Jika Anda mencoba mendapatkan semacam wizard (bentuk multi langkah), Anda dapat membuat serialisasi bidang yang sudah dikompilasi dan dengan TempData membawanya mengikuti langkah Anda. (untuk bantuan dalam serialisasi deserialize Anda dapat menggunakan MVC futures )

Iridio
sumber
1

Apa yang dikatakan @Darin adalah apa yang akan saya rekomendasikan juga. Namun saya akan menambahkannya (dan sebagai tanggapan atas salah satu komentar) bahwa Anda sebenarnya juga dapat menggunakan metode ini untuk tipe primitif seperti bit, bool, bahkan struktur seperti Guid dengan hanya membuatnya nullable. Setelah Anda melakukan ini, Requiredatribut berfungsi seperti yang diharapkan.

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
}
Nick Albrecht
sumber
1

Pada MVC 5 ini dapat dengan mudah dicapai dengan menambahkan ini di file global.asax.

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
Yom S.
sumber
1

Saya sedang mencari solusi di mana saya dapat menggunakan model yang sama untuk penyisipan dan pembaruan di api web. Dalam situasi saya, ini selalu merupakan konten tubuh. The [Requiered]atribut harus dilewati jika itu adalah metode update. Dalam solusi saya, Anda menempatkan atribut di [IgnoreRequiredValidations]atas metode. Ini adalah sebagai berikut:

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

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

    ...

Apa lagi yang perlu dilakukan? BodyModelValidator sendiri harus dibuat dan ditambahkan saat startup. Ini ada di HttpConfiguration dan terlihat seperti ini: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 saya sendiri berasal dari DefaultBodyModelValidator. Dan saya menemukan bahwa saya harus mengganti metode 'ShallowValidate'. Dalam penggantian ini saya memfilter validator model yang diminta. Dan sekarang kelas IgnoreRequiredOrDefaultBodyModelValidator dan kelas atribut 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
    {

    }
}

Sumber:

Roberto B
sumber
0

Jika Anda tidak ingin menggunakan ViewModel lain, Anda dapat menonaktifkan validasi klien pada tampilan dan juga menghapus validasi di server untuk properti yang ingin Anda abaikan. Silakan periksa jawaban ini untuk penjelasan lebih dalam https://stackoverflow.com/a/15248790/1128216

Jonathan Morales Vélez
sumber
0

Dalam kasus saya Model yang sama digunakan di banyak halaman untuk tujuan kegunaan kembali. Jadi apa yang saya lakukan adalah saya telah membuat atribut khusus yang memeriksa pengecualian

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);

        }
    }
}

dan di pengontrol Anda

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

            //do something           

    }

Katakanlah Modelnya

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; }
}
Beingnin
sumber
-1

Ya itu mungkin untuk menonaktifkan Atribut yang Diperlukan. Buat atribut kelas khusus Anda sendiri (kode contoh disebut ChangeableRequired) sejauh dari RequiredAtribute dan tambahkan Properti Dinonaktifkan dan timpa metode IsValid untuk memeriksa apakah itu disbaled. Gunakan refleksi untuk mengatur poperty yang dinonaktifkan, seperti:

Atribut Khusus:

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);
       }
    }
}

Perbarui properti Anda untuk menggunakan Atribut khusus baru Anda:

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

di mana Anda perlu menonaktifkan refleksi penggunaan properti untuk mengaturnya:

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;

Ini terasa bagus dan bersih?

NB: Validasi di atas akan dinonaktifkan saat instance objek Anda hidup \ aktif ...

Ernest Gunning
sumber
Setelah beberapa perdebatan tentang ini, saya ingin menyebutkan bahwa saya tidak merekomendasikan menonaktifkan validasi melainkan meninjau aturannya. Jika Anda menonaktifkannya, Anda membuat ketergantungan untuk mengaktifkan kembali aturan tersebut dan saya sarankan untuk meninjau aturan tersebut.
Ernest Gunning
Mengubah nilai statis untuk sepenuhnya menonaktifkan semua validasi bidang yang dijalankan dalam proses yang sama terdengar seperti ide yang buruk.
Jeremy Lakeman