3

現在、アクションのモデルバインドされたパラメーターとして「現在のユーザー」を持つパターンについて考えています。

私の行動は次のようになります。

public JsonResult ListStuff(User currentUser, string paramter1, int parameter2)
{
}

そして、私は次のような非常に単純なModelBinderを持っています:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    if ( bindingContext.ModelName == "currentUser" )
        return Globals.HttpContextItems.User;

    return null;
}

アクションが別のコントローラープロパティにあまり依存しないのが本当に好きです。これにより、関数の「入力パラメーター」がより明確になり、再利用性が高まり、将来的にはもう少し簡単にテストできるようになります。

しかし、私はセキュリティの問題に少し不安を感じています。currentUserが他のModelBinderによって自動的にバインドされないように(つまり、DefaultModelBinderで)確認する必要があります。

これが良いパターンかもしれないし、今私が考えていないことがあるが、それは将来問題になるだろうとしたら、誰もが光を当てることができますか?

4

2 に答える 2

2

他のModelBinderがそのパラメーターを設定することが心配な場合は、アクションメソッドを明示的に装飾する必要があるようにActionFilterAttributeを作成してみませんか。

public class GetCurrentUserAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.ActionParameters["currentUser"] = filterContext.HttpContext.User;
    }
}

次にそれを使用するには:

[GetCurrentUser]
public ActionResult Index(User currentUser)
{
}

デフォルトのモデルバインダーほどクリーンではありませんが、より明確です。

于 2012-12-31T16:50:18.387 に答える
1

面白いアイデア。また、メソッドに要件を注入することでIoCを維持する方法が気に入っています(コンストラクターだけでなく、メソッドに依存性を注入できることを忘れがちです)。

セキュリティ上の懸念は、このコンテキストアイテムを設定する場所に抽象化されます。私の推奨事項は、これとまったく同じロジックを配置して、コンテキストアイテムをこの同じ場所に配置することです。この種のロジックを2か所(モデルバインダー、次にコントローラーメソッドと言う)に配置すると、バグを追跡するために2か所を追跡することになります。nullの場合、このモデルバインダーがそのコンテキストアイテムの読み込みを担当する必要があると言います。

最後に、これにより、将来、さらに複雑な「ユーザー検証」サービスが抽象化されます。たとえば、ドメインに渡されるすべてのデータとIDがセキュリティチェックでそのユーザーに属していることを確認するというプロジェクト要件が一度にありました。このメソッドで説明するのは、ベースのUserオブジェクトを継承するカスタムUserオブジェクトがあり、そのようなものにUserContext : User、追加のセキュリティブール値検証を含む多数の追加のUI関連の関数とプロパティを含めることができるというものです。

次のプロジェクトでこれを試すかもしれません。

于 2012-12-31T16:50:06.597 に答える