2009-07-03 3 views
2

Мы строим сайт, используя asp.net mvc. Мы хотим разрешить пользователю легко регистрироваться и создавать учетную запись. Существует хотя и очень специальная информация, которая будет зарегистрирована в его профиле, которую мы хотим показать ему * после завершения регистрации, и он регистрируется в первый раз.asp.net MVC, как перенаправить зарегистрированных пользователей, у которых нет профиля на страницу?

Логика - это какой бы ни был URL-адрес, если пользователь аутентифицирован и не имеет действительного профиля, перенаправляйте его на страницу «Создать профиль».

Весь ui будет зависеть от этих вариантов выбора. Какой подход следует использовать в рамках MVC, чтобы заставить этот рабочий процесс посетителя? Идеи, которые я могу придумать, требуют тонны дублирования кода в контроллерах и т. Д., Поэтому его явно плохая идея.

Мы используем членство для пользователей, но профиль - это наша собственная реализация (без провайдера профиля), которая будет подключать данные профиля к userId.

ответ

3

Я думаю, что самый простой способ сделать это - либо создать пользовательский атрибут AuthorizeAttribute, либо расширить существующий, либо создать отдельный FilterAttribute. Любой из них будет применяться ко всем вашим контроллерам и гарантирует, что аутентифицированный пользователь имеет профиль. В случае отсутствия профиля фильтр будет перенаправлять пользователя на страницу, где создается профиль. Это можно сделать, установив свойство result в контексте RedirectResult в действие создания профиля. Только если профиль существует и будет завершен, фильтр позволит пользователю перейти к желаемому действию.

В качестве альтернативы вы можете создать базовый контроллер, который переопределяет OnActionExecuting и выполняет ту же задачу. Я предпочитаю механизм атрибута, поскольку он более гибкий, т. Е. Вы можете иметь некоторые публичные действия, доступные без профиля (включая действие настройки профиля).

+0

Я думаю, что его большие накладные расходы придется применять один и тот же actionfilter снова и снова, когда вы знаете, что всегда хотите это сделать. Я рассмотрю это как с базовым контроллером (тогда мне нужно будет сделать все мои контроллеры наследуемыми от этого вместо этого?) Или зайти в запрос на начало global.asax. –

+0

Вы можете применить фильтр на контроллере или уровне действия. При применении на уровне контроллера это в основном то же самое, что и в базовом контроллере. Если у вас есть несколько разных фильтров, которые не всегда применяются, вы начнете понимать гибкость механизма фильтра.Только когда это действительно глобальное действие, я бы рекомендовал механизм базового контроллера. В вашем случае это может применяться. – tvanfosson

+0

Спасибо за ваши ответы. Это действительно выглядит как нечто особенное, что мне нужно обеспечить соблюдение правил, куда бы ни вошли мои зарегистрированные пользователи. Я думаю, что это цена за дополнительную удобство использования, не слишком нагружая ваших пользователей при регистрации. Использование пользовательского базового контроллера требует, чтобы все контроллеры, которым необходимо выполнить эту проверку, должны были расширить пользовательский ctrler? Не проще было бы поставить логику в Global.asas, как предлагает xandy? –

0

Попробуйте рассмотреть ActionFilter и FilterAttribute если не большинство страниц нужно сделать так, или иначе, вы можете на самом деле поставить это переназначение логик global.asax (в той Begin запроса или аналогичные событий)

2

Ответ на свой вопрос: В конце концов я создал собственный 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 и репозитории для доступа к db.

Большое спасибо сообществу.

Смежные вопросы