erg*_*ysr 12 sql-server asp.net-mvc
我正在开发一个带有SQL Server数据库的MVC4网站.我想用他们的电子邮件地址注册人.
但是,如果电子邮件地址包含该字符i,则WebSecurity.CreateUserAndAccount方法抛出一个异常说:
身份验证提供程序返回错误.请验证您的输入,然后重试.如果问题仍然存在,请与系统管理员联系.
我研究了很多并找到了一些关于它的帖子,但没有解决方案.
http://forums.asp.net/t/1862233.aspx/1?How+can+i+use+email+address+for+username+in+MVC4+Membership
您的根本问题是您尝试输入非 ASCII 字符作为电子邮件地址。
\n\n“ASCII 字符集”将您限制为美国英语字母表,而这恰好是拉丁字母表。
\n\n我不会说土耳其语,但正如http://aspnetwebstack.codeplex.com/workitem/714中指出的那样
\n\n在土耳其语中,\'i\' 是小写字母,而 \'\xc4\xb0\' 是“i”的大写字母。
\n在拉丁字母中,你(和我)碰巧没有 IT 知识,\'i\' 是小写字母,而 \'I\' 是 i 的大写字母。
所以你有一个不属于 EN-US ASCII 字符集的字符。
\n因此,排序规则设置会阻止您将非 ASCII 字符输入数据库,从而导致错误。
\n因此,您不应更改排序规则设置(这将允许无效的邮件地址)。
正如所指出的,ToUpper(应该是 ToUpperInvariant)是罪魁祸首,因为它在幕后将 \'i\' 更改为 \'\xc4\xb0\',这不是有效的 ASCII 字符。
\n\n这是字符串/字符的 ToUpper 方法的常见问题。
\n例如,德语字母表中包含字母 \xc3\x9f (Unicode U+00DF),也称为“double s”,它首先没有对应的大写字符,因此如果您尝试使用 toUpper 比较字符串,总是会失败,这就是为什么你应该总是使用 ToLower() 来比较字符串——另一个 Microsoft 失败。
ToUpper 也发生了类似的情况。
\n\n您首先需要做的是确保您的用户输入 ASCII 字符。
\n这是不可能的,因为它们有土耳其语键盘和语言环境,虽然小 i 看起来与 ASCII 小 i 相似,但它具有不同的数字表示形式,因此有不同的大写字符(顺便说一句,小写也是如此)。
因此,您需要做的是在调用会员资格方法之前对输入字符串进行“拉丁化/罗马化”。
\n\n我在使用第三方的仅支持 ASCII 的软件时遇到了类似的问题,该软件在元音变音和法语重音字符上失败,并使用以下方法解决了这个问题。
\n您可能想检查土耳其语 \xc3\xa4\xc3\xb6\xc3\xbc 的数字表示形式是否与(瑞士)德语 \xc3\xa4\xc3\xb6\xc3\xbc 不同。在这里使用。
\n有关风险和副作用,请阅读包装说明书并咨询您的医生或药剂师。
// string str = ApertureSucks.Latinize("(\xc3\xa6\xc3\xb8\xc3\xa5 \xc3\xa2\xc3\xb4\xc3\xbb?a\xc3\xa8");\n public static string Latinize(string stIn)\n {\n // Special treatment for German Umlauts\n stIn = stIn.Replace("\xc3\xa4", "ae");\n stIn = stIn.Replace("\xc3\xb6", "oe");\n stIn = stIn.Replace("\xc3\xbc", "ue");\n\n stIn = stIn.Replace("\xc3\x84", "Ae");\n stIn = stIn.Replace("\xc3\x96", "Oe");\n stIn = stIn.Replace("\xc3\x9c", "Ue");\n // End special treatment for German Umlauts\n\n string stFormD = stIn.Normalize(System.Text.NormalizationForm.FormD);\n System.Text.StringBuilder sb = new System.Text.StringBuilder();\n\n for (int ich = 0; ich < stFormD.Length; ich++)\n {\n System.Globalization.UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);\n\n if (uc != System.Globalization.UnicodeCategory.NonSpacingMark)\n {\n sb.Append(stFormD[ich]);\n } // End if (uc != System.Globalization.UnicodeCategory.NonSpacingMark)\n\n } // Next ich\n\n\n //return (sb.ToString().Normalize(System.Text.NormalizationForm.FormC));\n return (sb.ToString().Normalize(System.Text.NormalizationForm.FormKC));\n } // End Function Latinize\nRun Code Online (Sandbox Code Playgroud)\n\n最后但并非最不重要的一点是,我不会使用内置的 ASP.NET 成员资格提供程序,因为它通过用户名 + 应用程序名称到角色名称来连接表,而不是使用唯一的 id。这意味着您将无法在不更改所有映射表的情况下更改用户或组/角色名称。\n我认为这样做是非常不可取的,并且绝对是愚蠢和粗心的,如果不是微软方面的彻底危险的话。
\n我什至会称将此类垃圾释放到野外是无礼的。
下面的“东西”证明了这个问题是完全愚蠢的,永远不应该使用
\n\nCREATE TABLE [dbo].[UsersInRoles](\n [Username] [varchar](255) NOT NULL,\n [Rolename] [varchar](255) NOT NULL,\n [ApplicationName] [varchar](255) NOT NULL,\n CONSTRAINT [usersinroles_pkey] PRIMARY KEY CLUSTERED \n(\n [Username] ASC,\n [Rolename] ASC,\n [ApplicationName] ASC\n)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]\n) ON [PRIMARY]\nRun Code Online (Sandbox Code Playgroud)\n\n出于以下原因:
\n\n我确信 MS 提供的会员提供者惨败还存在更多问题。 \n例如,使用快速哈希算法 (MD5),这是这种情况的反模式,因为这允许彩虹表攻击,特别是如果哈希值没有加盐。\n如果 MS 会员提供程序展示了一件事,那么这就是不设计会员提供程序的方法。
\n| 归档时间: |
|
| 查看次数: |
710 次 |
| 最近记录: |