Conception Globale
Pour commencer, je crois que vous auriez à suivre en quelque sorte, si l'utilisateur choisit de les ignorer. Un simple et transparente façon de le faire est d'avoir un Ignorer les Avertissements case, l'utilisateur qui aura à vérifier avant de soumettre. Une autre option est un ont leur soumettre le formulaire à deux reprises et d'ignorer les mises en garde sur la deuxième soumettre; puis vous auriez probablement besoin d'une IgnoreWarnings champ caché. Il pourrait y avoir d'autres motifs, mais par souci de simplicité, je vais aller avec la première option.
En bref, l'approche est de créer
- Une coutume annotation de données d'attribut pour tous les modèles de vue de soutenir l'avertissement type de validation;
- Connu de la classe de base dont le point de vue des modèles va hériter d';
- Nous allons dupliquer le logique en JavaScript pour chaque attribut personnalisé.
Veuillez noter que le code ci-dessous illustre la démarche et je suppose beaucoup de choses sans en connaître le contexte.
Modèle De Vue
Dans ce scénario, il est préférable de se séparer d'un modèle de vue à partir d'un modèle réel qui est une bonne idée de toute façon. Une approche possible est d'avoir une classe de base pour tous les modèles de vue qui soutien mises en garde:
public abstract class BaseViewModel
{
public bool IgnoreWarnings { get; set; }
}
La clé raison pour laquelle un modèle doit être distincte est qu'il n'y a que peu de sens dans le stockage de l' IgnoreWarnings
propriété dans votre base de données.
Votre dérivé du modèle de vue seront ensuite comme suit:
public class YourViewModel : BaseViewModel
{
[Required]
[StringLengthWarning(MaximumLength = 5, ErrorMessage = "Your Warning Message")]
public string YourProperty { get; set; }
}
StringLengthWarning
est une coutume annotation de données d'attribut pour le serveur et la validation côté client. Il soutient tout le maximum de longueur et peut être facilement étendue à toutes les autres propriétés.
Annotation De Données De L'Attribut
Le noyau de l'attribut est - IsValid(value, validationContext
méthode.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class StringLengthWarningAttribute : ValidationAttribute, IClientValidatable
{
public int MaximumLength { get; set; }
public override bool IsValid(object value)
{
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = validationContext.ObjectInstance as BaseViewModel;
var str = value as string;
if (!model.IgnoreWarnings && (string.IsNullOrWhiteSpace(str) || str.Length > MaximumLength))
return new ValidationResult(ErrorMessage);
return base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new StringLengthWarningValidationRule(MaximumLength, ErrorMessage);
}
}
L'attribut implémente IClientValidatable
et utilise un client personnalisé règle de validation:
public class StringLengthWarningValidationRule : ModelClientValidationRule
{
public StringLengthWarningValidationRule(int maximumLength, string errorMessage)
{
ErrorMessage = errorMessage;
ValidationType = "stringlengthwarning";
ValidationParameters.Add("maximumlength", maximumLength);
ValidationParameters.Add("ignorewarningsfield", "IgnoreWarnings");
}
}
JavaScript côté Client
Enfin, pour le faire fonctionner, vous aurez besoin de JavaScript référencé à partir de votre point de vue:
$(function () {
$.validator.addMethod('stringlengthwarning', function (value, element, params) {
var maximumlength = params['maximumlength'];
var ignorewarningsfield = params['ignorewarningsfield'];
var ctl = $("#" + ignorewarningsfield);
if (ctl == null || ctl.is(':checked'))
return true;
return value.length <= maximumlength;
});
$.validator.unobtrusive.adapters.add("stringlengthwarning", ["maximumlength", "ignorewarningsfield"], function (options) {
var value = {
maximumlength: options.params.maximumlength,
ignorewarningsfield: options.params.ignorewarningsfield
};
options.rules["stringlengthwarning"] = value;
if (options.message) {
options.messages["stringlengthwarning"] = options.message;
}
});
}(jQuery));
Le JavaScript fait quelques hypothèses que vous souhaiterez revoir (la case nom, etc).
Mise à JOUR: HTML Helpers
Pour afficher les messages de validation séparément pour les erreurs et les avertissements, un couple d'assistants seront nécessaires. La classe suivante fournit un exemple:
public static class MessageHelpers
{
public static MvcHtmlString WarningMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] != null)
return htmlHelper.ValidationMessageFor(expression);
return MvcHtmlString.Empty;
}
public static MvcHtmlString ErrorMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] == null)
return htmlHelper.ValidationMessageFor(expression);
return MvcHtmlString.Empty;
}
}
Dans la vue, ils peuvent être utilisés comme d'habitude:
@Html.EditorFor(model => model.YourProperty)
@Html.ErrorMessageFor(model => model.YourProperty)
@Html.WarningMessageFor(model => model.YourProperty)