Używam ASP.NET MVC i chciałbym, aby wszystkie pola ciągów wprowadzone przez użytkownika zostały przycięte, zanim zostaną wstawione do bazy danych. A ponieważ mam wiele formularzy wprowadzania danych, szukam eleganckiego sposobu na przycięcie wszystkich ciągów zamiast jawnego przycinania każdej wartości ciągu dostarczonej przez użytkownika. Interesuje mnie, jak i kiedy ludzie przycinają sznurki.
Pomyślałem o stworzeniu spoiwa modelu niestandardowego i przycięciu tam dowolnych wartości ciągów ... w ten sposób cała moja logika przycinania jest zawarta w jednym miejscu. Czy to dobre podejście? Czy są jakieś próbki kodu, które to robią?
asp.net
asp.net-mvc
model-binders
Johnny Oshika
źródło
źródło
type="password"
dane wejściowe nietknięte?To jest ta sama rozdzielczość @takepara, ale jako IModelBinder zamiast DefaultModelBinder, więc dodanie modelbinder w global.asax jest zakończone
Klasa:
na podstawie posta @haacked: http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx
źródło
return
instrukcji i negując warunek:if (valueResult == null || string.IsNullOrEmpty(valueResult.AttemptedValue)) return null;
[AllowHtml]
atrybutu we właściwościach modelu (wraz z[ValidateInput(false)]
wyżej wymienionym kodem CodeGrueJedno ulepszenie odpowiedzi @takepara.
Gdzieś w projekcie:
W TrimModelBinder zmiana klasy
do
i możesz oznaczyć właściwości, które mają być wykluczone z przycinania za pomocą atrybutu [NoTrim].
źródło
.Cast<object>().Any(a => a.GetType() == typeof(NoTrimAttribute))
ze.OfType<NoTrimAttribute>().Any()
. Tylko trochę czystszy.Dzięki ulepszeniom w C # 6 możesz teraz napisać bardzo kompaktowy spinacz modelu, który będzie przycinał wszystkie dane wejściowe ciągu:
Trzeba to gdzieś w tej linii
Application_Start()
wGlobal.asax.cs
pliku, aby użyć spinacza modelu podczas wiązaniastring
s:Uważam, że lepiej jest użyć spinacza modelu, takiego jak ten, zamiast nadpisywać domyślny spinacz modelu, ponieważ będzie on używany zawsze, gdy będziesz wiązać a
string
, niezależnie od tego, czy jest to bezpośrednio jako argument metody, czy jako właściwość w klasie modelu. Jeśli jednak zastąpisz domyślny spinacz modelu, jak sugerują inne odpowiedzi tutaj, będzie to działać tylko w przypadku wiązania właściwości w modelach, a nie wtedy, gdy maszstring
argument do metody akcjiEdycja: komentator zapytany o rozwiązanie sytuacji, w której pole nie powinno być walidowane. Moja pierwotna odpowiedź została ograniczona tylko do pytania zadanego przez OP, ale dla zainteresowanych możesz poradzić sobie z walidacją, używając następującego rozszerzonego segregatora:
źródło
W ASP.Net Core 2 to zadziałało. Używam
[FromBody]
atrybutu w moich kontrolerach i danych wejściowych JSON. Aby przesłonić obsługę ciągów w deserializacji JSON, zarejestrowałem własny JsonConverter:A to jest konwerter:
źródło
Kolejny wariant odpowiedzi @ takepara, ale z innym akcentem:
1) Wolę mechanizm atrybutu opt-in „StringTrim” (zamiast przykładowego atrybutu @Anton „NoTrim” rezygnacji).
2) Wymagane jest dodatkowe wywołanie SetModelValue, aby upewnić się, że ModelState jest poprawnie wypełniony, a domyślny wzorzec walidacji / akceptacji / odrzucania może być używany normalnie, tj. TryUpdateModel (model) do zastosowania i ModelState.Clear () do akceptowania wszystkich zmian.
Umieść to w swojej encji / udostępnianej bibliotece:
Następnie w Twojej aplikacji / bibliotece MVC:
Jeśli nie ustawisz wartości właściwości w segregatorze, nawet jeśli nie chcesz niczego zmieniać, całkowicie zablokujesz tę właściwość przed ModelState! Dzieje się tak, ponieważ jesteś zarejestrowany jako wiążący wszystkie typy ciągów, więc wydaje się (w moich testach), że domyślny spinacz nie zrobi tego za Ciebie.
źródło
Dodatkowe informacje dla każdego, kto szuka, jak to zrobić w ASP.NET Core 1.0. Logika bardzo się zmieniła.
Napisałem post na blogu o tym, jak to zrobić , wyjaśnia to nieco bardziej szczegółowo
Więc rozwiązanie ASP.NET Core 1.0:
Modelowy segregator do faktycznego przycinania
Potrzebujesz również Model Binder Provider w najnowszej wersji, to mówi, że ten segregator powinien być używany dla tego modelu
Następnie należy go zarejestrować w Startup.cs
źródło
Czytając doskonałe odpowiedzi i komentarze powyżej i coraz bardziej zdezorientowany, nagle pomyślałem: hej, zastanawiam się, czy istnieje rozwiązanie jQuery. Dlatego dla innych, którzy, tak jak ja, uważają ModelBinders za nieco oszałamiające, oferuję następujący fragment kodu jQuery, który przycina pola wejściowe przed przesłaniem formularza.
źródło
W przypadku MVC Core
Spoiwo:
Dostawca:
Funkcja rejestracji:
Zarejestrować:
źródło
SimpleTypeModelBinderProvider
przez utrzymanie tego samego indeksu.Spóźniłem się na imprezę, ale poniżej znajduje się podsumowanie korekt wymaganych dla MVC 5.2.3, jeśli masz sprostać
skipValidation
wymaganiom wbudowanych dostawców wartości.Global.asax
źródło
Nie zgadzam się z rozwiązaniem. Należy zastąpić GetPropertyValue, ponieważ dane dla SetProperty mogą być również wypełnione przez ModelState. Aby złapać surowe dane z elementów wejściowych, napisz to:
Filtruj według propertyDescriptor PropertyType, jeśli naprawdę interesują Cię tylko wartości ciągów, ale nie powinno to mieć znaczenia, ponieważ wszystko, co pojawia się, jest w zasadzie ciągiem.
źródło
W przypadku ASP.NET Core Zastąp
ComplexTypeModelBinderProvider
dostawcę, który przycina ciągi.W
ConfigureServices
metodzie kodu startowego dodaj to:Zdefiniuj w
TrimmingModelBinderProvider
ten sposób:Brzydką częścią tego jest kopiowanie i wklejanie
GetBinder
logiki zComplexTypeModelBinderProvider
, ale wydaje się, że nie ma żadnego haka, który pozwoliłby ci tego uniknąć.źródło
Utworzyłem dostawców wartości, aby przyciąć wartości parametrów ciągu zapytania i wartości formularza. Zostało to przetestowane z ASP.NET Core 3 i działa doskonale.
Następnie zarejestruj fabryki dostawców wartości w
ConfigureServices()
funkcji w Startup.csźródło
Pojawiło się wiele postów sugerujących podejście do atrybutów. Oto pakiet, który ma już atrybut trim i wiele innych: Dado.ComponentModel.Mutations lub NuGet
Po wywołaniu Mutate () użytkownik.UserName zostanie zmieniony na
m@x_speed.01!
.Ten przykład spowoduje obcięcie białych znaków i małych liter w ciągu. Nie wprowadza walidacji, ale
System.ComponentModel.Annotations
może być używany razem zDado.ComponentModel.Mutations
.źródło
Opublikowałem to w innym wątku. W asp.net core 2 poszedłem w innym kierunku. Zamiast tego użyłem filtra akcji. W takim przypadku programista może ustawić go globalnie lub użyć jako atrybutu dla działań, które chce przyciąć ciąg. Ten kod jest uruchamiany po utworzeniu powiązania modelu i może aktualizować wartości w obiekcie modelu.
Oto mój kod, najpierw utwórz filtr akcji:
Aby go użyć, zarejestruj się jako filtr globalny lub udekoruj swoje akcje atrybutem TrimInputStrings.
źródło