|
namespace System.ComponentModel.DataAnnotations {
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Resources;
using System.Linq;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class CreditCardAttribute : DataTypeAttribute {
public CreditCardAttribute()
: base(DataType.CreditCard) {
// DevDiv 468241: set DefaultErrorMessage not ErrorMessage, allowing user to set
// ErrorMessageResourceType and ErrorMessageResourceName to use localized messages.
DefaultErrorMessage = DataAnnotationsResources.CreditCardAttribute_Invalid;
}
public override bool IsValid(object value) {
if (value == null) {
return true;
}
string ccValue = value as string;
if (ccValue == null) {
return false;
}
ccValue = ccValue.Replace("-", "");
ccValue = ccValue.Replace(" ", "");
int checksum = 0;
bool evenDigit = false;
// http://www.beachnet.com/~hstiles/cardtype.html
foreach (char digit in ccValue.Reverse()) {
if (digit < '0' || digit > '9') {
return false;
}
int digitValue = (digit - '0') * (evenDigit ? 2 : 1);
evenDigit = !evenDigit;
while (digitValue > 0) {
checksum += digitValue % 10;
digitValue /= 10;
}
}
return (checksum % 10) == 0;
}
}
}
|