我们正在使用 asp.net mvc 构建一个网站。我们希望让用户能够轻松注册和创建帐户。不过,有一条非常特殊的信息将在他的个人资料中注册,我们希望在注册完成后向他显示,并且他是第一次登录。

逻辑是无论点击什么 URL,如果用户已通过身份验证并且没有有效的配置文件,则将其重定向到“创建配置文件”页面。

整个用户界面将取决于这些配置文件的选择。我们应该在 MVC 框架中使用什么方法来强制访问者执行此工作流?我能想到的想法需要控制器等中大量的代码重复,所以这显然是一个坏主意。

我们对用户使用会员资格,但配置文件是我们自己的实现(无配置文件提供程序),它将配置文件数据连接到 userId。

有帮助吗?

解决方案

我想这样做的最简单的方法是任一创建自定义AuthorizeAttribute,延伸的现有的一个或创建一个单独的FilterAttribute。无论这些人会得到适用于所有的控制器,并确保身份验证的用户都有一个配置文件。在没有配置文件存在的情况下,过滤器将用户重定向到创建个人资料页面。这将通过对上下文的结果属性设置为RedirectResult到配置文件创建动作来完成。只有在文件中不存在,并已完成将过滤器允许用户继续所需的操作。

可替换地,可以创建一个基本控制器,它覆盖OnActionExecuting并执行相同的任务。我喜欢,因为它是更灵活的属性机制,即你可以有一些可没有公开个人资料的行为(包括配置文件设置操作)。

其他提示

回答我自己的问题:最后我创建了一个自定义的actionFilter。一开始,我采取了将[authorize]子类化为[AuthorizeCheckProfile]的路径。但后来我意识到用例是错误的:如果不存在用户配置文件,我不希望网站的仅登录部分重定向到创建配置文件页面。我想了 任何页面 如果是没有个人资料的登录用户,我的网站将重定向到该页面。我唯一不想检查的地方是在实际的配置文件创建中。这是代码:

public class AssertProfileAttribute : ActionFilterAttribute {
    public AssertProfileAttribute() {
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        if (filterContext.HttpContext.Request.IsAuthenticated == false)
            return;
        //we have a user, but does he have a profile?
        if (filterContext.HttpContext.Session["UserProfile"] == null) { //not in the session
            IUnityContainer container = filterContext.HttpContext.Application["container"] as IUnityContainer;
            Profile hasProfile = container.Resolve<IProfileRepository>().GetUserProfile(Membership.GetUser());
            if (hasProfile == null) {
                //we have to redirect to the create profile 
                string returnURL = filterContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath;
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Profile", action = "Create", returnTo = returnURL }));
            } else {
                //he has a profile but we haven't put it in session yet
                filterContext.HttpContext.Session["UserProfile"] = hasProfile;
            }
        }
    }
}

它的副作用是它将配置文件存储在会话密钥中。通过这种方式,可以轻松获取它,以便可以使用其他自定义过滤器在每个请求中进行进一步的角色检查。该实现使用 Unity 和存储库进行数据库访问。

非常感谢社区。

尝试考虑ActionFilter和FilterAttribute如果不是大多数网页都需要这样做,否则,你实际上可能把这个重定向逻辑Global.asax中(在那些开始请求或类似事件)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top