asp.net-mvc-2 - ASP.NET MVC 2 和 SQL 表配置文件提供程序

标签 asp.net-mvc-2 profile provider

我正在尝试添加来自 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/

相关文章:

asp.net-core - 如何使用 Identityserver4 从外部提供商获取个人资料图片?

http - 每个持久连接的 HTTP 内存使用

flutter - 从 Selector 访问多个字段(在 Flutter 中使用 Provider 状态管理时)?

java - guice中非单例的延迟加载

flutter - 如何根据bool值在Auth屏幕和Home屏幕之间切换?

c# - 从另一个局部 View 更新局部 View - ASP.NET MVC2

c# - 我可以有一个名为 "View"的 ActionResult 吗

maven - 如何在gradle中像maven一样定义配置文件来替换属性

asp.net - ASP.NET 框架中的异步页面 - 其他线程在哪里以及如何重新附加?

c# - 使用 Controller 操作过滤器捕获 HTML 输出