8

リポジトリレイヤーを備えたWindows認証済みMVCアプリケーションがあります。コントローラとデータベースとのすべての対話は、リポジトリを介して行われます。各コントローラーには、リポジトリへの参照があります。

public class PostController : Controller
{
    private Repository db = new Repository();

    [HttpPost]
    public ActionResult DeletePost(int id)
    {
        // Authorize that the user is allowed to delete this post...

        db.DeletePost(id);
    }
}

私の質問は、承認ロジックをリポジトリ層に移動する良い方法があるかどうかです。Repository.DeletePost()認証されたユーザーが作成していない投稿の削除を拒否する機能が欲しいのですが。問題は、私のリポジトリが認証されたユーザーが誰であるかを知らないことです。コントローラは(経由でController.User)知っています。

コンストラクターが呼び出された時点では明らかに定義されていないため、コンストラクターController.Userへのの受け渡しは機能しません。RepositoryController.User

Repository認証されたユーザーが誰であるかをどのように通知できますか?Repository各アクション内で構築するのが最善でしょうか?それとも、リポジトリレイヤーで処理するのは悪い考えですか?

4

3 に答える 3

5

それとも、リポジトリ層で処理するのは悪い考えですか?

コントローラーは、あなたの承認に適した場所だと思います。リポジトリをデータへのゲートウェイに、コントローラーをアプリケーションへのゲートキーパーにします。承認/認証ロジックがライフサイクルのできるだけ早い段階で見られることを期待しています。

于 2013-02-15T19:27:58.560 に答える
1

@BigDaddyと@ChrisPrattの両方からの良い提案。

私はこの答えのように、ベースコントローラーを作成することでこれを解決することになりました。私の基本コントローラークラスは次のようになります。

public class BaseController : Controller
{
    private ILog _log;
    private Repository _db;

    protected Repository Db
    {
        get
        {
            return _db ?? (_db = new Repository(User));
        }
    }

    protected ILog Log
    {
        get
        {
            return _log ?? (_log = LogManager.GetLogger(this.GetType()));
        }
    }
}

すべてのコントローラーはこのクラスを継承しRepository、現在認証されているユーザーへの参照を持つ遅延読み込みへの組み込みアクセス権を持っています。

于 2013-02-15T19:58:21.007 に答える
1

次のようなことをしてください:

db.DeletePostForUser(id, User.Identity.UserId);

次に、リポジトリで:

public void DeletePostForUser(int id, int userId)
{
    var post = context.Posts.SingleOrDefault(m => m.PostId == id && m.User.UserId == userId)
    if (post != null)
    {
        context.Posts.Remove(post);
        context.SaveChanges();
    }
}
于 2013-02-15T19:26:27.947 に答える