2009-07-03 15 views
2

asp.net mvcを使用してサイトを構築しています。ユーザーは簡単にアカウントを登録して作成することができます。彼のプロフィールに登録される非常に特別な情報がありますが、登録が完了して初めて彼に見せたいのです。彼は初めてログインしています。asp.net MVC、プロファイルを持たない登録ユーザをページにリダイレクトする方法は?

論理は、ユーザーが認証され、有効なプロファイルを持たない場合は、「プロファイルの作成」ページにリダイレクトされます。

全体のUIは、これらのプロファイルの選択に依存します。このワークフローを訪問者に強制するには、MVCフレームワーク内でどのようなアプローチを使用する必要がありますか?私が思い付くことができるアイデアはコントローラのコードの重複を必要とするので、明らかに悪い考えです。

ユーザーのメンバーシップを使用していますが、プロファイルはプロファイルデータをuserIdに接続する独自の実装(プロファイルプロバイダなし)です。

答えて

3

これを行う最も簡単な方法は、カスタムAuthorizeAttributeを作成すること、既存のAuthorizeAttributeを拡張すること、または既存のFilterAttributeを作成することだと思います。これらのいずれかがすべてのコントローラに適用され、認証されたユーザーがプロファイルを持つことを確認します。プロファイルが存在しない場合、フィルターはユーザーがプロファイルが作成されたページにリダイレクトされます。これは、コンテキストのresultプロパティをRedirectResultに設定して、プロファイル作成アクションに設定することで実行されます。プロファイルが存在し、完了している場合にのみ、フィルタはユーザが所望の動作に進むことを可能にする。

また、OnActionExecutingをオーバーライドして同じタスクを実行するベースコントローラを作成することもできます。属性メカニズムは、柔軟性が高いため、プロファイルなしで利用可能な公開アクション(プロファイル設定アクションを含む)を持つことができます。

+0

私は、あなたがいつもこれをやりたいと思っているときに、同じアクションフィルタを何度も繰り返して適用する必要があると考えています。 私はベースコントローラーでこれを行うことにします(それから、私のすべてのコントローラーを代わりにそのコントローラーから継承させる必要がありますか?)か、global.asaxの開始要求に行きます。 –

+0

コントローラまたはアクションレベルでフィルタを適用できます。コントローラーレベルで適用すると、基本コントローラーで行うのと基本的に同じです。常に適用されるわけではない複数のフィルタを用意したら、フィルタ機構の柔軟性を理解し始めます。本当にグローバルなアクションである場合にのみ、ベースコントローラーのメカニズムをお勧めします。あなたの場合、それが適用されるかもしれません。 – tvanfosson

+0

あなたの返信をありがとう。実際には、私の登録ユーザがどこに行っても、私はそれを強制する必要がある非常に特別なもののように見えます。私は、あなたのユーザーにあまりにも多くの登録に負担をかけないように余分なユーザビリティを支払うのはその価格だと思います。 カスタムベースコントローラを使用するには、このチェックを実施する必要があるすべてのコントローラがカスタムctrlerを拡張する必要がありますか? xandyが示唆しているように、単にGlobal.asasにロジックを入れるのは簡単ではないでしょうか? –

2

自分の質問に答える(これらに要求または同様のイベントを開始します)ではないほとんどのページが他にそうする必要がある場合、または、あなたが実際にGlobal.asaxのために、このリダイレクトロジックを出してもよいのActionFilterとFilterAttributeを検討してみてください。最後にカスタムアクションフィルタを作成しました。最初は[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; 
      } 
     } 
    } 
} 

セッションキーにプロファイルを保存するという副作用があります。こうすることで、他のカスタムフィルタを使用して、すべてのリクエストでさらなるロールチェックを実行できるように、簡単にフェッチできます。この実装では、dbアクセス用のUnityおよびリポジトリが使用されます。

コミュニティに大きな感謝です。

関連する問題