2012-03-04 12 views
15

mam to w moim modelu widoku:Sprawdź poprawność wartości dziesiętnych do 2 miejsc po przecinku za pomocą adnotacji danych?

[Required(ErrorMessage = "Price is required")] 
[Range(0.01, 999999999, ErrorMessage = "Price must be greater than 0.00")] 
[DisplayName("Price ($)")] 
public decimal Price { get; set; } 

Chciałbym potwierdzić, że użytkownik nie wchodzi więcej niż 2 miejsca po przecinku. Więc chciałbym mieć

Prawidłowe wartości: 12, 12.3, 12.34

Nieprawidłowe wartości: 12., 12,345

Czy istnieje sposób, aby potwierdzić to z adnotacją danych?

Odpowiedz

19

Możesz użyć atrybutu RegularExpression z wyrażeniem pasującym do twoich kryteriów. Tutaj jest cała masa wyrażeń, które zawierają liczby, jestem pewien, że pasuje do rachunku. Oto link.

To będzie Ci zacząć, choć to może nie być tak inclusive jak chcesz (wymaga co najmniej jedną cyfrę wiodącą przecinek):

[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Invalid price")] 

Należy pamiętać, że jest to trudne do emitowania dokładny komunikat o błędzie ponieważ nie wiesz, która część wyrażeń regularnych nie pasuje (ciąg "z.22" ma poprawną liczbę miejsc dziesiętnych, na przykład, ale nie jest prawidłową ceną).

+1

Nie działa dla języków z separatorem dziesiętnym innym niż kropka (.), np. przecinek (14,6), ponieważ funkcja RegularExpression konwertuje znaki dziesiętne na ciągi przy użyciu aktualnej kultury. – jahav

+0

Co powiedzieliśmy na '^ \ d * (\. |, | (\. \ D {1,2}) | (, \ d {1,2}))? $', Który przyjmuje zarówno kropkę, jak i przecinek, również nie pozwala poprzedzające cyfry przed punktem lub bez cyfr po punkcie. – helrich

+0

Z jakiegoś powodu podane wyrażenie regularne pozwala mi wstawiać wiele miejsc po przecinku, np .: 1.22.3.44 – Storm

2

Możesz dokonać tej weryfikacji za pomocą wyrażenia regularnego i zastosować ją z atrybutem RegularExpression.

4
[RegularExpression(@"^\d+(\.\d)?$", ErrorMessage = "It cannot have more than one decimal point value")] 
[Range(0.1,100)] 
public double xyz{get;set;}   

To działa na mnie zapisu do jednej wartości dziesiętnych

18
[RegularExpression(@"^\d+.\d{0,2}$",ErrorMessage = "Price can't have more than 2 decimal places")] 
public decimal Price { get; set; } 

To będzie zaspokajać 0 do 2 miejsc po przecinku, lub wcale.

+0

Możesz chcieć uciec przed '.' (co oznacza "dowolny znak", jeśli nie został zmieniony), aby dać^\ d + \. \ d {0,5} $ – Appetere

+2

Ups, przepraszam, znaczy^\ d + \.? \ d {0,5} $ z "?" aby umożliwić tylko 0 lub 1 powtórzenia. – Appetere

+0

To w rzeczywistości nie zezwala na wartość bez miejsc dziesiętnych, tj. "10", ** Jednak **, nie dopuszcza miejsc dziesiętnych z kropką: "10." – mattytommo

4

Można również tworzyć własne atrybut walidacji dziesiętny, dziedziczenie z RegularExpressionAttribute:

public class DecimalAttribute : RegularExpressionAttribute 
{ 
    public int DecimalPlaces { get; set; } 
    public DecimalAttribute(int decimalPlaces) 
     : base(string.Format(@"^\d*\.?\d{{0,{0}}}$", decimalPlaces)) 
    { 
     DecimalPlaces = decimalPlaces; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format("This number can have maximum {0} decimal places", DecimalPlaces); 
    } 
} 

i zarejestrować ją w celu umożliwienia walidacji po stronie klienta w Application_Start():

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(DecimalAttribute), typeof(RegularExpressionAttributeAdapter)); 
0

miałem takie same Mimo to, podane odpowiedzi nie dają rozwiązania, które działa we wszystkich następujących przypadkach:

12, 12.3 and 12.34

Aby to zrobić, możemy użyć następującego wyrażenia regularnego:

[RegularExpression(@"^\d+(.\d{1,2})?$")] 
0

Podobne do mattytommo. Musisz uciec "." - w przeciwnym razie DOWOLNA litera zostanie zaakceptowana

[RegularExpression(@"^\d+(\.\d{1,2})?$")] 
Powiązane problemy