Sql server 电子邮件地址作为用户名错误

Sql server 电子邮件地址作为用户名错误,sql-server,asp.net-mvc,Sql Server,Asp.net Mvc,我正在开发一个带有SQL Server数据库的MVC4网站。我想用他们的电子邮件地址注册 但是,如果电子邮件地址包含字符i,WebSecurity.CreateUserAndAccount方法会抛出一个异常,说明: 身份验证提供程序返回了一个错误。请核实您的申请 输入并重试。如果问题仍然存在,请联系您的 系统管理员 我做了很多研究,找到了一些关于它的帖子,但没有解决办法 您的根本问题是,您试图输入非ASCII字符作为电子邮件地址 “ASCII字符集”将您限制为美英字母表,这恰好是拉丁字母表 我

我正在开发一个带有SQL Server数据库的MVC4网站。我想用他们的电子邮件地址注册

但是,如果电子邮件地址包含字符
i
WebSecurity.CreateUserAndAccount
方法会抛出一个异常,说明:

身份验证提供程序返回了一个错误。请核实您的申请 输入并重试。如果问题仍然存在,请联系您的 系统管理员

我做了很多研究,找到了一些关于它的帖子,但没有解决办法


您的根本问题是,您试图输入非ASCII字符作为电子邮件地址

“ASCII字符集”将您限制为美英字母表,这恰好是拉丁字母表

我不会说土耳其语,但正如在

在土耳其语中,“i”是小写字母,而“İ”是“i”的大写字母。
在你(和我)碰巧不知道的拉丁字母表中,“i”是小写字母,而“i”是i的大写字母

因此,您有一个字符不是EN-US ASCII字符集的成员。
因此,排序规则设置阻止您将非ASCII字符输入数据库,从而导致错误。
因此,您不应更改排序规则设置(这将允许使用无效的邮件地址)

正如所指出的,ToUpper(应该是ToUpper不变量)是罪魁祸首,因为它在幕后将“i”改为“İ”,这不是一个有效的ASCII字符

这是字符串/字符的ToUpper方法的常见问题。
例如,德语字母表包含字母ß(Unicode U+00DF),也称为“双s”,它首先没有对应的大写字符,因此,如果您尝试使用toUpper比较字符串,它将始终失败,这就是为什么您应该始终使用ToLower()来比较字符串-另一个Microsoft失败

图珀也发生了类似的事情

首先,您需要确保用户输入ASCII字符。
这是不可能的,因为他们有土耳其语键盘和语言环境,虽然小i看起来类似于ASCII小i,但它有不同的数字表示,因此有不同的大写字符(顺便说一句,也有小写字符)

因此,您需要做的是在调用成员方法之前将输入字符串“拉丁化/罗马化”

第三方提供的仅支持ASCII的软件也有类似的问题,在umlauts和法语重音字符上失败,我使用下面的方法解决了这个问题
您可能需要检查土耳其语的数字表示形式是否与我在这里使用的(瑞士)德语的数字表示形式不同。

有关风险和副作用,请阅读包装传单并咨询您的医生或药剂师

    // string str = ApertureSucks.Latinize("(æøå âôû?aè");
    public static string Latinize(string stIn)
    {
        // Special treatment for German Umlauts
        stIn = stIn.Replace("ä", "ae");
        stIn = stIn.Replace("ö", "oe");
        stIn = stIn.Replace("ü", "ue");

        stIn = stIn.Replace("Ä", "Ae");
        stIn = stIn.Replace("Ö", "Oe");
        stIn = stIn.Replace("Ü", "Ue");
        // End special treatment for German Umlauts

        string stFormD = stIn.Normalize(System.Text.NormalizationForm.FormD);
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        for (int ich = 0; ich < stFormD.Length; ich++)
        {
            System.Globalization.UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);

            if (uc != System.Globalization.UnicodeCategory.NonSpacingMark)
            {
                sb.Append(stFormD[ich]);
            } // End if (uc != System.Globalization.UnicodeCategory.NonSpacingMark)

        } // Next ich


        //return (sb.ToString().Normalize(System.Text.NormalizationForm.FormC));
        return (sb.ToString().Normalize(System.Text.NormalizationForm.FormKC));
    } // End Function Latinize
基于以下原因:

  • 问题1:字符串连接将使用户到角色的连接非常慢-非常慢 对性能不利
  • 问题2:varchar-应该是nvarchar,除非 你生活在一个只有英语的世界里
  • 问题3:字段长度 用户名和角色名必须符合最新活动的最低规格 目录,否则将出现与同步的问题 activedirectory。另外,Active directory允许使用unicode字符
  • 问题4:没有对用户和角色表的外键引用- 迟早(通常更早)会导致数据垃圾
  • 问题5:如果现在更改用户名或 groupname、UserInRoles将不会更新,并且用户的组 映射将是孤立的-以数据垃圾结束,左连接将带来空列,程序可能会因为未处理的NullReferenceException而崩溃
  • 问题6:因为外键引用是 缺少,可以更改用户名/组名
  • 问题7:报告/显示数据时,数据垃圾迟早会导致多行
  • 问题8:此处使用的主键应该是唯一约束
  • 问题9:有一个组名,但例如组“administrators”需要本地化为多种语言,而成员资格提供程序不支持这些语言。此外,groupname属于映射表,因为一个组可以有N种语言的N个名称,然后必须确保groupname在特定语言中是唯一的
  • 问题10:此处不可见,但用户表包含电子邮件字段。这是一个彻底的失败,因为一个用户可以有n个电子邮件地址,而智能成员资格提供商应该考虑到这一点,而不是愚蠢地将用户限制为一个电子邮件地址
  • 问题11:此外,提到的电子邮件字段限制为128个字符,这小于rfc允许的电子邮件地址中允许的最大字符数。失败-迟早有人将无法输入他的邮件地址-即使他只有一个
我相信微软提供的会员资格提供商的惨败会带来更多的问题。 例如,使用快速散列算法(MD5),这在本例中是一种反模式,因为它允许彩虹表攻击,特别是在散列未被腌制的情况下。
如果MS成员资格提供程序演示了一件事,那么这就是如何不设计成员资格提供程序。

是的,解决方案是在创建用户和帐户时使用ToUpperInvariant()WebSecurity.CreateUserAndAccount(model.UserName.ToUpperInvariant())
. 这将解决问题。值将以大写字母存储到表中(IIIIII@GMAIL.COM).

只要使用您自己的.NET会员资格提供商,我就告诉您创建和使用一个。。。然后,您可以添加任何需要的信息。@balexandre感谢您的回复。。似乎没有其他方式可能值得一提,这是在
CREATE TABLE [dbo].[UsersInRoles](
    [Username] [varchar](255) NOT NULL,
    [Rolename] [varchar](255) NOT NULL,
    [ApplicationName] [varchar](255) NOT NULL,
 CONSTRAINT [usersinroles_pkey] PRIMARY KEY CLUSTERED 
(
    [Username] ASC,
    [Rolename] ASC,
    [ApplicationName] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]