Désactiver l’atsortingbut de validation requirejs dans certaines circonstances

Je me demandais s’il était possible de désactiver l’atsortingbut de validation requirejs dans certaines actions du contrôleur. Je me demande cela car sur l’un de mes formulaires d’édition, je n’ai pas besoin que l’utilisateur saisisse des valeurs pour les champs déjà spécifiés. Cependant, je mets alors en œuvre la logique voulant que, lorsqu’ils entrent une valeur, ils utilisent une logique spéciale pour mettre à jour le modèle, par exemple en hachant une valeur, etc.

Des suggestions sur la façon de contourner ce problème?

MODIFIER:
Et oui, la validation client est un problème ici, car cela ne leur permettra pas de soumettre le formulaire sans entrer de valeur.

Ce problème peut être facilement résolu en utilisant des modèles de vue. Les modèles de vue sont des classes spécifiquement adaptées aux besoins d’une vue donnée. Ainsi, par exemple, dans votre cas, vous pourriez avoir les modèles de vue suivants:

 public UpdateViewView { [Required] public ssortingng Id { get; set; } ... some other properties } public class InsertViewModel { public ssortingng Id { get; set; } ... some other properties } 

qui sera utilisé dans leurs actions de contrôleur correspondantes:

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

Si vous souhaitez simplement désactiver la validation pour un seul champ du côté client, vous pouvez remplacer les atsortingbuts de validation comme suit:

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

Je sais que cette question a reçu une réponse il y a longtemps et que la réponse acceptée fera le travail. Mais il y a une chose qui me dérange: devoir copier 2 modèles uniquement pour désactiver une validation.

Voici ma suggestion:

 public class InsertModel { [Display(...)] public virtual ssortingng ID { get; set; } ...Other properties } public class UpdateModel : InsertModel { [Required] public override ssortingng ID { get { return base.ID; } set { base.ID = value; } } } 

De cette façon, vous n’avez pas à vous soucier des validations côté client / serveur, la structure se comportera comme prévu. De plus, si vous définissez un atsortingbut [Display] sur la classe de base, vous n’avez pas à le redéfinir dans votre UpdateModel .

Et vous pouvez toujours utiliser ces classes de la même manière:

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

Personnellement, j’aurais tendance à utiliser l’approche de Darin Dimitrov dans sa solution. Cela vous permet d’utiliser l’approche des annotations de données avec validation ET d’avoir des atsortingbuts de données distincts sur chaque ViewModel correspondant à la tâche en cours. Pour minimiser le travail de copie entre le modèle et le modèle de vue, vous devriez regarder AutoMapper ou ValueInjecter . Les deux ont leurs points forts individuels, alors vérifiez les deux.

Une autre approche possible pour vous serait de dériver votre modèle de vue ou modèle de IValidatableObject. Cela vous donne la possibilité d’implémenter une fonction Valider. Dans validate, vous pouvez renvoyer une liste d’éléments ValidationResult ou émettre un rendement pour chaque problème détecté lors de la validation.

Le ValidationResult se compose d’un message d’erreur et d’une liste de chaînes contenant les noms de champs. Les messages d’erreur seront affichés à un endroit proche du ou des champs de saisie.

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

Côté client Pour désactiver la validation d’un formulaire, vous trouverez ci-dessous plusieurs options basées sur mes recherches. On espère que l’un d’entre eux travaillerait pour vous.

Option 1

Je préfère cela, et cela fonctionne parfaitement pour moi.

 (function ($) { $.fn.turnOffValidation = function (form) { var settings = form.validate().settings; for (var ruleIndex in settings.rules) { delete settings.rules[ruleIndex]; } }; })(jQuery); 

et l’invoquer comme

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

Option 2

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

Option 3

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

Option 4

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

Option 5

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

Du côté serveur

Créez un atsortingbut et marquez votre méthode d’action avec cet atsortingbut. Personnalisez ceci pour s’adapter à vos besoins spécifiques.

 [AtsortingbuteUsage(AtsortingbuteTargets.All)] public class IgnoreValidationAtsortingbute : ActionFilterAtsortingbute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var modelState = filterContext.Controller.ViewData.ModelState; foreach (var modelValue in modelState.Values) { modelValue.Errors.Clear(); } } } 

Une meilleure approche a été décrite ici Activer / désactiver dynamicment la validation côté serveur mvc

Vous pouvez supprimer toute validation d’une propriété avec les éléments suivants dans votre action de contrôleur.

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

@ Commentaire de Ian concernant MVC5

Ce qui suit est encore possible

 ModelState.Remove("PropertyNameInModel"); 

Peu gênant que vous perdiez le typage statique avec l’API mise à jour. Vous pouvez réaliser quelque chose de similaire à l’ancienne en créant une instance d’assistance HTML et en utilisant les méthodes NameExtensions .

Je crois que le moyen le plus propre est de désactiver la validation côté client et, du côté du serveur, vous devrez:

  1. ModelState [“SomeField”]. Errors.Clear (dans votre contrôleur ou créez un filtre d’action pour supprimer les erreurs avant l’exécution du code du contrôleur)
  2. Ajoutez ModelState.AddModelError à partir de votre code de contrôleur lorsque vous détectez une violation de vos problèmes détectés.

Semble même un modèle de vue personnalisé ici ne résoudra pas le problème, car le nombre de ces champs «pré-répondus» peut varier. S’ils ne le font pas, un modèle de vue personnalisé peut être le moyen le plus simple, mais en utilisant la technique ci-dessus, vous pouvez contourner vos problèmes de validation.

c’était la réponse de quelqu’un d’autre dans les commentaires … mais ça devrait être une vraie réponse:

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

testé sur MVC 6 avec un champ ayant l’atsortingbut [Required]

réponse volée de https://stackoverflow.com/users/73382/rob ci-dessus

J’avais ce problème lorsque j’ai créé une vue d’édition pour mon modèle et que je veux mettre à jour un seul champ.

Ma solution pour une manière la plus simple est de mettre les deux champs en utilisant:

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

Commentaires est le champ que je ne mets à jour que dans la vue Modifier, sans atsortingbut obligatoire.

Entité ASP.NET MVC 3

AFAIK, vous ne pouvez pas supprimer l’atsortingbut à l’exécution, mais seulement modifier leurs valeurs (ex: readonly true / false) regardez ici quelque chose de similaire . Comme autre moyen de faire ce que vous voulez sans toucher aux atsortingbuts, je vais utiliser un ViewModel pour votre action spécifique afin que vous puissiez insérer toute la logique sans casser la logique nécessaire aux autres contrôleurs. Si vous essayez d’obtenir une sorte d’assistant (un formulaire en plusieurs étapes), vous pouvez au lieu de cela sérialiser les champs déjà compilés et avec TempData les accompagner dans vos démarches. (pour obtenir de l’aide sur la sérialisation, désérialiser, vous pouvez utiliser les contrats à terme de MVC )

Ce que @Darin a dit, c’est ce que je recommanderais aussi. Cependant, j’appendais (et en réponse à l’un des commentaires) que vous pouvez aussi utiliser cette méthode pour les types primitifs comme bit, bool, même les structures comme Guid en les rendant simplement nullables. Une fois que vous faites cela, l’atsortingbut Required fonctionne comme prévu.

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

A partir de MVC 5, cela peut être facilement réalisé en ajoutant ceci dans votre global.asax .

 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAtsortingbuteForValueTypes = false; 

Je cherchais une solution permettant d’utiliser le même modèle pour une insertion et une mise à jour dans Web Api. Dans ma situation est-ce toujours un contenu corporel. Les atsortingbuts [Requiered] doivent être ignorés s’il s’agit d’une méthode de mise à jour. Dans ma solution, vous placez un atsortingbut [IgnoreRequiredValidations] au-dessus de la méthode. Ceci est comme suit:

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

Que doit-on faire d’autre? Un BodyModelValidator propre doit être créé et ajouté au démarrage. Cela se trouve dans la configuration HTTP et ressemble à ceci: 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()); } ... 

Mon propre BodyModelValidator est dérivé de DefaultBodyModelValidator. Et je me suis rendu compte que je devais remplacer la méthode ‘ShallowValidate’. Dans cette substitution, je filtre les validateurs de modèle requirejs. Et maintenant la classe IgnoreRequiredOrDefaultBodyModelValidator et la classe atsortingbutte 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 _ignoreRequiredValidationByActionBindingCache; static IgnoreRequiredOrDefaultBodyModelValidator() { _ignoreRequiredValidationByActionBindingCache = new ConcurrentDictionary(); } protected override bool ShallowValidate(ModelMetadata metadata, BodyModelValidatorContext validationContext, object container, IEnumerable 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.GetCustomAtsortingbute(false) != null; } #endregion } [AtsortingbuteUsage(AtsortingbuteTargets.Method, Inherited = true)] public class IgnoreRequiredValidationsAtsortingbute : Atsortingbute { } } 

Sources:

Si vous ne souhaitez pas utiliser un autre ViewModel, vous pouvez désactiver les validations client sur la vue et également supprimer les validations sur le serveur pour les propriétés à ignorer. S’il vous plaît vérifier cette réponse pour une explication plus approfondie https://stackoverflow.com/a/15248790/1128216

Oui, il est possible de désactiver l’atsortingbut requirejs. Créez votre propre atsortingbut de classe personnalisé (exemple de code appelé ChangeableRequired) à étendre depuis RequiredAsortingbute et ajoutez une propriété désactivée et remplacez la méthode IsValid pour vérifier si elle est déséquilibrée. Utilisez la reflection pour définir la population handicapée, comme ceci:

Atsortingbut personnalisé:

 namespace System.ComponentModel.DataAnnotations { public class ChangeableRequired : RequiredAtsortingbute { public bool Disabled { get; set; } public override bool IsValid(object value) { if (Disabled) { return true; } return base.IsValid(value); } } } 

Mettez à jour votre propriété pour utiliser votre nouvel atsortingbut personnalisé:

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

où vous devez désactiver la reflection sur l’utilisation de la propriété pour la définir:

 Forex forex = new Forex(); // Get Property Descriptor from instance with the Property name PropertyDescriptor descriptor = TypeDescriptor.GetProperties(forex.GetType())["ExchangeRate"]; //Search for Atsortingbute ChangeableRequired atsortingb = (ChangeableRequired)descriptor.Atsortingbutes[typeof(ChangeableRequired)]; // Set Atsortingbute to true to Disable atsortingb.Disabled = true; 

Cela se sent bien et propre?

NB: La validation ci-dessus sera désactivée tant que votre instance d’object est active \ active …