我正在使用 Asp.net 身份 进行登录、注册、忘记密码 等操作,源代码取自以下链接:
现在我有 1 个 UserMaster 表,在注册期间我要求输入以下字段: 全名、电子邮件 ID、密码、联系电话、性别。
我的 UserMaster 包含以下字段:Id,FullName,EmailId,ContactNumber,Gender
现在,当用户提交注册表时,此 FullName、EmailId、ContactNumber、Gender 将与 Email、Password 一起保存在 UserMaster 中。
我的注册方法与上面2个链接提供的一样。
在这里你可能会注意到 我的 UserMaster 和 AspnetUser 之间没有关系 所以在登录期间当用户输入他的电子邮件 ID 登录时我将使用此方法 await SignInManager.PasswordSignInAsync 来验证用户,如果此方法返回成功,那么我要做的是使用此电子邮件 ID 并在我的 UserMaster 中检查此电子邮件,然后在何处找到匹配项我将从 UserMaster 中获取该 UserId 并将其存储在 session 中并彻底使用我的登录方法中的应用程序如下所示:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
using (var context = new MyEntities())
{
var fetchUSerId = context.UserMaster.Where(t => t.Email == model.Email).Select(t=>t.UserId).SingleOrDefault();
Session["UserId"] = fetchUSerId;
}
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
我在我的登录方法中谈到了这一点:
case SignInStatus.Success:
using (var context = new MyEntities())
{
var fetchUSerId = context.UserMaster.Where(t => t.Email == model.Email).Select(t=>t.UserId).SingleOrDefault();
Session["UserId"] = fetchUSerId;
}
这是一种合适的方式还是更好的方式,我想存储整个用户对象而不是只存储用户 ID。
那么谁能告诉我如何使用 aspnet 身份执行此操作?
最佳答案
由于您使用的是 Asp.Net Identity,因此您希望将与 session 相关的内容存储为声明。这很容易通过自定义声明进行扩展。
顺便说一句,我认为你最好简单地扩展 ApplicationUser 来保存额外的数据,详情 here .
也就是说,这是一个完整的示例,说明如何将自定义声明类型添加到您的应用程序。
第 1 步 - 定义一个或多个自定义声明类型以保存您的附加信息
public static class CustomClaimTypes
{
public const string MasterFullName = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/masterfullname";
public const string MasterUserId = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/masteruserid";
}
声明类型只是标识特定声明的唯一字符串。在这里,我们只是使用与内置声明类型类似的格式。
第 2 步 - 在登录过程中,为自定义声明类型设置值
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
//Fetch data from the UserMaster table
var userdata = GetdatafromUserMaster();
//Using the UserMaster data, set our custom claim types
identity.AddClaim(new Claim(CustomClaimTypes.MasterUserId, userdata.UserId));
identity.AddClaim(new Claim(CustomClaimTypes.MasterFullName, userdata.FullName));
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
注意:我们正在使用自定义声明类型,以便我们保留现有的 NameIdentifier 和 Name 声明,因此可以轻松地从 Asp.Net Identity < strong="">和我们的自定义 UserMaster 表。
第 3 步 - 向 IIdentity 添加扩展方法,以便我们可以轻松访问我们的自定义声明数据
public static class IdentityExtensions
{
public static string GetMasterUserId(this IIdentity identity)
{
if (identity == null)
return null;
return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.MasterUserId);
}
public static string GetMasterFullName(this IIdentity identity)
{
if (identity == null)
return null;
return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.MasterFullName);
}
internal static string FirstOrNull(this ClaimsIdentity identity, string claimType)
{
var val = identity.FindFirst(claimType);
return val == null ? null : val.Value;
}
}
这里没什么特别的。我们只是将 IIdentity 转换为 ClaimsIdentity,然后返回我们找到的给定 CustomClaimType 的第一个声明的值,或者我们返回null 如果声明不存在。
第 4 步 - 现在我们可以非常轻松地访问 View 和/或 Controller 中的自定义声明数据。假设您想使用 UserMaster 表中的全名而不是 ApplicationUser?您现在可以这样做:
<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + User.Identity.GetMasterFullName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
您也可以在 Controller 中执行相同的操作。
关于c# - 如何在 aspnet 身份中进行 session 管理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32880269/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f