我应该用微软的CreditCardAttribute来验证信用卡号码吗?

[Required, CreditCard]
public string CreditCardNumber { get; set; }

或者我应该让支付网关处理它,还是做其他事情?我是在发现一些客户无法提交信用卡信息付款后问这个问题的。幸运的是,我与其中一位客户合作,发现他们的visa卡在移除CreditCardAttribute后处理没有问题。
在某种程度上,这个问题是反问性的,但我希望从其他开发人员的想法和经验中获益,并通过提问让其他开发人员意识到使用CreditCardAttribute的风险。

最佳答案

我认为最好的办法就是简单地测试一下:

using System;
using System.Linq;
using System.Text;
using System.IO;

namespace SO
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] cards = new string[] {
                //http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
                "378282246310005",  // American Express
                "4012888888881881", // Visa
                "6011111111111117", // Discover
                "4222222222222", // Visa
                "76009244561", // Dankort (PBS)
                "5019717010103742", // Dakort (PBS)
                "6331101999990016", // Switch/Solo (Paymentech)
                "30569309025904", // Diners Club
                //http://www.getcreditcardnumbers.com/
                "5147004213414803", // Mastercard
                "6011491706918120", // Discover
                "379616680189541", // American Express
                "4916111026621797", // Visa
            };

            foreach (string card in cards)
            {
                Console.WriteLine(IsValid(card));
            }

            Console.ReadLine();
        }

        public static 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;
        }
    }
}

isValid方法来自原始cCreditCardAttribute类。
12个号码中有1个失败:
        True
        True
        True
        True
        False //"76009244561", // Dankort (PBS)
        True
        True
        True
        True
        True
        True
        True

那么,你应该用它吗?不,很明显它没有检测到所有的数字。尽管你可以拿走他们的代码并改进它!

关于c# - 我应该使用CreditCardAttribute来验证信用卡号吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29899715/

10-09 17:20