Je développe un site Web MVC4 avec une database SQL Server. Je veux save des personnes avec leur adresse email.
Toutefois, si l'adresse électronique contient le caractère i
, la méthode WebSecurity.CreateUserAndAccount
lève une exception:
Le fournisseur d'authentification a renvoyé une erreur. Veuillez vérifier votre input et réessayer. Si le problème persiste, contactez votre administrateur système.
J'ai beaucoup étudié et trouvé quelques articles à ce sujet, mais il n'y a pas de solution.
http://forums.asp.net/t/1862233.aspx/1?How+can++++address+address+for+username+in+MVC4+Membership
http://aspnetwebstack.codeplex.com/workitem/714
Votre problème fondamental est que vous essayez d'entrer des caractères non ASCII en tant qu'adresse de messagerie.
Le "jeu de caractères ASCII" vous limite à l'alphabet US-anglais, qui se trouve être l'alphabet latin.
Je ne parle pas turc, mais comme indiqué dans http://aspnetwebstack.codeplex.com/workitem/714
En turc, «i» est en minuscule, tandis que «İ» est supérieur à «i».
Dans l'alphabet latin, que vous (et moi) ne possédez pas, IT est en minuscule, tandis que «I» est majuscule de i.
Vous avez donc un caractère qui n'est pas membre du jeu de caractères ASCII EN-US.
Par conséquent, le paramètre de classment vous empêche d'entrer des caractères non ASCII dans votre database, d'où l'erreur.
Et d'où le commentaire que vous ne devez pas modifier le paramètre de classment (ce qui permettrait d'adresses de messagerie invalides).
Comme indiqué, ToUpper (qui devrait être ToUpperInvariant) est à blâmer, parce que dans les coulisses change le 'i' en 'İ', qui n'est pas un caractère ASCII valide.
C'est un problème courant avec la méthode ToUpper d'une string / caractère.
Par exemple, l'alphabet allemand contient la lettre ß (Unicode U + 00DF), également appelée "double s", qui n'a pas de caractère majuscule correspondant, donc si vous essayez de comparer des strings avec toUpper, il échouera toujours, C'est pourquoi vous devriez toujours utiliser ToLower () pour comparer les strings – un autre Microsoft échoue.
Une chose similaire arrive ici avec ToUpper.
Ce que vous devez faire en premier lieu est de s'assurer que vos users entrent des caractères ASCII.
Ce n'est pas possible car ils ont un keyboard turc et une locale, et tandis que le petit i ressemblera au petit i d'ASCII, il a une représentation numérique différente, et donc une majuscule différente (et des minuscules aussi bien que btw).
Donc, ce que vous devez faire est de "latiniser / romaniser" votre string d'input, avant d'appeler la méthode d'adhésion.
J'ai rencontré des problèmes similaires avec des logiciels compatibles ASCII d'un tiers, qui ont échoué sur les trémas et les caractères d'accent français, et j'ai utilisé la méthode ci-dessous pour résoudre ce problème.
Vous voudrez peut-être vérifier si le äöü turc n'a pas une représentation numérique différente du äöü (suisse) allemand que j'ai utilisé ici.
Pour les risques et les effets secondaires, lisez les notices et requestz à votre médecin ou à votre pharmacien.
// ssortingng str = ApertureSucks.Latinize("(æøå âôû?aè"); public static ssortingng Latinize(ssortingng 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 ssortingng stFormD = stIn.Normalize(System.Text.NormalizationForm.FormD); System.Text.SsortingngBuilder sb = new System.Text.SsortingngBuilder(); 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.ToSsortingng().Normalize(System.Text.NormalizationForm.FormC)); return (sb.ToSsortingng().Normalize(System.Text.NormalizationForm.FormKC)); } // End Function Latinize
Et last but not least, je n'utiliserais pas le fournisseur d'appartenance ASP.NET embedded, car il joint les tables via nom d'user + nom d'application à rolename, au lieu d'utiliser un identifiant unique. Cela signifie que vous ne pourrez pas modifier un nom d'user ou de groupe / rôle sans modifier toutes les tables de mappage. Je pense que faire cela de cette façon est hautement indésirable, et certainement stupide et négligent, sinon carrément dangereux de la part de Microsoft.
J'irais même jusqu'à dire qu'il est impudent de libérer de telles ordures dans la nature.
La "chose" ci-dessous démontre la stupidité totale du problème et ne devrait jamais être utilisée
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]
Pour les raisons suivantes:
et je suis sûr qu'il y a beaucoup plus de problèmes avec le fiasco de fournisseur d'adhésion fourni par MS. Par exemple en utilisant un algorithm de hachage rapide (MD5), qui est un anti-model pour ce cas, car cela permet une attaque de table arc-en-ciel, surtout si le hachage n'est pas salé. Si le fournisseur d'appartenances MS montre une chose, alors voici comment ne pas concevoir un fournisseur d'appartenances.
Oui, la solution consiste à utiliser ToUpperInvariant () lorsque vous créez l'user et le count WebSecurity.CreateUserAndAccount (model.UserName.ToUpperInvariant ()); . Cela résoudra le problème. Les valeurs seront stockées dans la table avec une majuscule ([email protected]).