我正在尝试添加来自 http://www.asp.net/downloads/sandbox/table-profile-provider-samples 的示例表配置文件提供程序到新的 MVC 2 站点。
经过一番研究和摆弄,我得到了一个如下所示的配置文件类。
namespace MyNamespace.Models
{
public class UserProfile : ProfileBase
{
[SettingsAllowAnonymous(false),CustomProviderData("FirstName;nvarchar")]
public string FirstName
{
get { return base["FirstName"] as string; }
set { base["FirstName"] = value; }
}
[SettingsAllowAnonymous(false),CustomProviderData("LastName;nvarchar")]
public string LastName
{
get { return base["LastName"] as string; }
set { base["LastName"] = value; }
}
public static UserProfile GetUserProfile(string username)
{
return Create(username,false) as UserProfile;
}
public static UserProfile GetUserProfile()
{
return Create(Membership.GetUser().UserName,true) as UserProfile;
}
}
}
还有像这样的 web.config
<profile enabled="true" defaultProvider="TableProfileProvider" inherits="MyNamespace.Models.UserProfile">
<providers>
<clear />
<add name="TableProfileProvider" type="Microsoft.Samples.SqlTableProfileProvider" connectionStringName="ContentDB" table="aspnet_UserProfiles" applicationName="/"/>
</providers>
</profile>
我认为我一路上发现的事情是
- 通过 MVC 使用自定义提供程序需要
<profile>
上的“继承”属性web.config 中的元素,它阻止使用<properties><add ....>
使用相同的配置文件字段名称构建。 - 示例 SQL 表配置文件提供程序需要
CustomProviderData
属性,并且由于上述原因,它不能出现在 web.config 文件中,因此需要作为属性添加到配置文件类中的属性中。
一旦用户登录,一切似乎都可以正常工作。但是,我想捕获一些配置文件数据作为新用户注册过程的一部分,并且在用户登录之前我似乎无法访问配置文件对象。
我尝试在 MVC 模板代码的新用户注册部分添加一个调用来保存配置文件数据:
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName);
profile.FirstName = "Doug";
Profile.Save();
return RedirectToAction("Index", "Home");
然而似乎 Membership.GetUser()
在用户实际登录之前为 null。我还尝试使用模型中的用户名。
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
UserProfile profile = UserProfile.GetUserProfile(model.UserName);
profile.FirstName = "Doug";
profile.Save();
return RedirectToAction("Index", "Home");
这有点进一步,但在尝试设置 FirstName 配置文件字段时失败,并显示一条错误消息“尝试将属性设置为匿名用户,但这是不允许的”(抱歉,不要这样做)当我输入此内容时,无法访问确切的消息)。
有什么办法可以解决这个问题吗?它看起来像 FormsServer.SignIn
就表单例份验证而言,该方法实际上并不让用户登录,并且需要一个往返才能完全登录,大概需要将 cookie 提交回服务器。
如果没有简单的方法解决这个问题,我可以使用数据访问方法直接填充配置文件表(插入 aspnet_UserProfiles ....)。这是一座太过遥远的桥梁,还是一个可行的解决方案?
<小时/>没有人遇到这个问题吗?不?那就只有我了!
只是为了更新,我尝试了弗朗西·佩诺夫在对此问题的回答中提出的建议 posting .
所以,现在我的代码如下所示。
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
GenericIdentity id = new GenericIdentity(model.UserName);
HttpContext.User = new GenericPrincipal(id, null);
UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName) as UserProfile;
profile.FirstName = "Doug";
profile.Save();
return RedirectToAction("Index", "Home");
现在,至少对 Membership.GetUser() 的调用返回有效的 MembershipUser
对象,但尝试设置 FirstName 配置文件属性仍会导致消息 This property cannot be set for anonymous users.
因此,就成员(member)资格而言,用户已登录,但个人资料系统仍然认为未登录。
有什么想法吗?
最佳答案
万岁!
阅读本文posting更仔细地说,我想我应该尝试显式调用配置文件初始化方法,并且它起作用了!
注册操作方法的最终完整代码是:
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);
if (createStatus == MembershipCreateStatus.Success)
{
FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
GenericIdentity id = new GenericIdentity(model.UserName);
HttpContext.User = new GenericPrincipal(id, null);
UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName) as UserProfile;
profile.Initialize(Membership.GetUser().UserName, true);
profile.FirstName = "Doug";
profile.Save();
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
return View(model);
}
希望这有帮助。
道格
关于asp.net-mvc-2 - ASP.NET MVC 2 和 SQL 表配置文件提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3088317/