J'utilise ASP.NET MVC et j'aimerais que tous les champs de chaîne saisis par l'utilisateur soient coupés avant d'être insérés dans la base de données. Et comme j'ai de nombreux formulaires de saisie de données, je recherche un moyen élégant de couper toutes les chaînes au lieu de couper explicitement chaque valeur de chaîne fournie par l'utilisateur. Je suis intéressé de savoir comment et quand les gens coupent les chaînes.
J'ai pensé à peut-être créer un classeur de modèle personnalisé et couper les valeurs de chaîne là-bas ... de cette façon, toute ma logique de coupe est contenue au même endroit. Est-ce une bonne approche? Existe-t-il des exemples de code qui font cela?
asp.net
asp.net-mvc
model-binders
Johnny Oshika
la source
la source
type="password"
entrées intactes?C'est @takepara la même résolution mais comme IModelBinder au lieu de DefaultModelBinder de sorte que l'ajout du modelbinder dans global.asax se fasse
La classe:
basé sur @haacked post: http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx
la source
return
instructions et en annulant la condition:if (valueResult == null || string.IsNullOrEmpty(valueResult.AttemptedValue)) return null;
[AllowHtml]
attribut sur les propriétés du modèle (avec le[ValidateInput(false)]
codeGrue mentionné ci-dessusUne amélioration de la réponse @takepara.
Certains étaient en projet:
Dans le changement de classe TrimModelBinder
à
et vous pouvez marquer les propriétés à exclure du découpage avec l'attribut [NoTrim].
la source
.Cast<object>().Any(a => a.GetType() == typeof(NoTrimAttribute))
par.OfType<NoTrimAttribute>().Any()
. Juste un peu plus propre.Avec les améliorations apportées à C # 6, vous pouvez désormais écrire un classeur de modèles très compact qui réduira toutes les entrées de chaîne:
Vous devez inclure cette ligne quelque part dans
Application_Start()
votreGlobal.asax.cs
fichier pour utiliser le classeur de modèle lors de la liaison destring
s:Je trouve qu'il est préférable d'utiliser un classeur de modèle comme celui-ci, plutôt que de remplacer le classeur de modèle par défaut, car il sera alors utilisé chaque fois que vous liez a
string
, que ce soit directement comme argument de méthode ou comme propriété sur une classe de modèle. Cependant, si vous remplacez le classeur de modèle par défaut comme le suggèrent d'autres réponses ici, cela ne fonctionnera que lors de la liaison de propriétés sur des modèles, pas lorsque vous avez unstring
comme argument à une méthode d'actionEdit: un commentateur a demandé comment gérer la situation où un champ ne devrait pas être validé. Ma réponse initiale a été réduite pour ne traiter que de la question posée par l'OP, mais pour ceux qui sont intéressés, vous pouvez gérer la validation en utilisant le classeur de modèles étendu suivant:
la source
Dans ASP.Net Core 2, cela a fonctionné pour moi. J'utilise l'
[FromBody]
attribut dans mes contrôleurs et l'entrée JSON. Pour remplacer la gestion des chaînes dans la désérialisation JSON, j'ai enregistré mon propre JsonConverter:Et voici le convertisseur:
la source
Une autre variante de la réponse de @ takepara mais avec une tournure différente:
1) Je préfère le mécanisme d'attribut opt-in "StringTrim" (plutôt que l'exemple opt-out "NoTrim" de @Anton).
2) Un appel supplémentaire à SetModelValue est nécessaire pour s'assurer que ModelState est correctement rempli et que le modèle de validation / acceptation / rejet par défaut peut être utilisé normalement, c'est-à-dire TryUpdateModel (modèle) pour appliquer et ModelState.Clear () pour accepter toutes les modifications.
Mettez ceci dans votre entité / bibliothèque partagée:
Puis ceci dans votre application / bibliothèque MVC:
Si vous ne définissez pas la valeur de la propriété dans le classeur, même si vous ne voulez rien changer, vous bloquerez complètement cette propriété de ModelState! C'est parce que vous êtes enregistré comme liant tous les types de chaînes, il semble donc (dans mes tests) que le classeur par défaut ne le fera pas pour vous alors.
la source
Informations supplémentaires pour toute personne cherchant comment faire cela dans ASP.NET Core 1.0. La logique a beaucoup changé.
J'ai écrit un article de blog sur la façon de le faire , il explique les choses un peu plus en détail
Donc, solution ASP.NET Core 1.0:
Reliure modèle pour effectuer la coupe proprement dite
Vous avez également besoin de Model Binder Provider dans la dernière version, cela indique que si ce classeur doit être utilisé pour ce modèle
Ensuite, il doit être enregistré dans Startup.cs
la source
En lisant les excellentes réponses et commentaires ci-dessus, et devenant de plus en plus confus, j'ai soudainement pensé, hé, je me demande s'il existe une solution jQuery. Donc, pour ceux qui, comme moi, trouvent ModelBinders un peu déroutant, je propose l'extrait de code jQuery suivant qui rogne les champs de saisie avant que le formulaire ne soit soumis.
la source
Dans le cas de MVC Core
Classeur:
Fournisseur:
Fonction d'enregistrement:
S'inscrire:
la source
SimpleTypeModelBinderProvider
en conservant le même index.À la fin de la partie, mais ce qui suit est un résumé des ajustements requis pour MVC 5.2.3 si vous devez gérer l'
skipValidation
exigence de l'accumulation dans les fournisseurs de valeur.Global.asax
la source
Je ne suis pas d'accord avec la solution. Vous devez remplacer GetPropertyValue car les données de SetProperty peuvent également être remplies par ModelState. Pour capturer les données brutes des éléments d'entrée, écrivez ceci:
Filtrez par propertyDescriptor PropertyType si vous n'êtes vraiment intéressé que par les valeurs de chaîne, mais cela ne devrait pas avoir d'importance car tout ce qui entre est essentiellement une chaîne.
la source
Pour ASP.NET Core , remplacez le
ComplexTypeModelBinderProvider
par un fournisseur qui coupe les chaînes.Dans votre
ConfigureServices
méthode de code de démarrage , ajoutez ceci:Définissez
TrimmingModelBinderProvider
comme ceci:La partie laide de ceci est le copier-coller de la
GetBinder
logique deComplexTypeModelBinderProvider
, mais il ne semble pas y avoir de crochet pour vous permettre d'éviter cela.la source
J'ai créé des fournisseurs de valeur pour réduire les valeurs des paramètres de la chaîne de requête et les valeurs du formulaire. Cela a été testé avec ASP.NET Core 3 et fonctionne parfaitement.
Enregistrez ensuite les fabriques de fournisseurs de valeur dans la
ConfigureServices()
fonction dans Startup.csla source
Il y a eu de nombreux articles suggérant une approche attributaire. Voici un package qui a déjà un attribut trim et bien d'autres: Dado.ComponentModel.Mutations ou NuGet
Après l'appel à Mutate (), user.UserName sera muté en
m@x_speed.01!
.Cet exemple réduira les espaces et mettra la chaîne en minuscules. Il n'introduit pas de validation, mais
System.ComponentModel.Annotations
peut être utilisé à côtéDado.ComponentModel.Mutations
.la source
J'ai posté ceci dans un autre fil. Dans asp.net core 2, je suis allé dans une direction différente. J'ai utilisé un filtre d'action à la place. Dans ce cas, le développeur peut soit le définir globalement, soit l'utiliser comme attribut pour les actions qu'il / elle souhaite appliquer le découpage de chaîne. Ce code s'exécute après la liaison de modèle et peut mettre à jour les valeurs dans l'objet de modèle.
Voici mon code, créez d'abord un filtre d'action:
Pour l'utiliser, enregistrez-vous en tant que filtre global ou décorez vos actions avec l'attribut TrimInputStrings.
la source