currentUser作为模型绑定参数

时间:2012-12-31 16:27:40

标签: asp.net asp.net-mvc model-binding

现在我正在考虑一种模式,让'当前用户'成为我行动中的模型绑定参数。

我的行为看起来像这样:

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;
}

我真的很喜欢这个动作不太依赖于另一个Controller属性。它使得函数的“输入参数”更清晰,更可重用,并且将来可以更容易测试。

但是,我有点担心安全问题。我可能必须非常确定(即在DefaultModelBinder中)currentUser永远不会被其他ModelBinder自动绑定。

如果这可能是一个很好的模式,任何人都可以发光吗?如果有一些我目前没有想到的东西,但这会在未来产生问题。

2 个答案:

答案 0 :(得分: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)
{
}

绝对不像默认的模型绑定器那样干净,但更明确。

答案 1 :(得分:1)

有趣的想法。我喜欢它如何通过将需求注入到方法中来保持IoC(人们经常忘记你可以将依赖注入方法,而不仅仅是构造函数)。

您的安全问题将被抽象到您填充此上下文项的位置。我的建议是在同一位置放置相同的逻辑,以填充上下文项。在两个地方拥有这种逻辑(一个模型绑定器,然后说一个控制器方法)会让你追逐两个地方来追踪一个错误。我说这个模型绑定器应该负责加载该上下文项,如果它是null。

最后,如果您想要这样做,这将在未来抽象出更复杂的“用户验证”服务。例如,我一次有一个项目要求,以确保传递到域中的每个数据和ID都属于具有安全检查的用户。你描述的这个方法让你有一个自定义的User对象继承自你的用户对象,称为UserContext : User,可以有许多额外的UI相关函数和属性 - 包括附加安全性布尔值验证

我可以在下一个项目中尝试这个。