自定义过滤器中不需要的模型绑定
我有一个奇怪/烦人的小错误,我什至不知道如何正确解释,所以如果这变得有点罗嗦,请原谅我。另外,为了保护对象,对象已被重命名;)
我正在处理的 MVC 站点(我没有启动它,我只是在处理它)有一个自定义过滤器属性,该属性将参数注入到任何被修饰的操作方法中与所述过滤器。该参数保存登录用户的详细信息,用于确定基于角色的权限。请参见下面的示例:
[UserFilter]
public ActionResult DoSomeStuffDependingOnPrivileges(string userId, UserObj user)
UserObj 是一个模型。它看起来有点像这样:
public class User
{
[DisplayName("User ID")]
public int UserID { get; set; }
...
...
...
public IEnumerable<RoleModels.Role> Roles { get; set; }
}
这是自定义操作过滤器:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionParameters.ContainsKey(key))
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
var user = (User)filterContext.HttpContext.Session["User"];
filterContext.ActionParameters[key] = user;
}
}
base.OnActionExecuting(filterContext);
}
所以它的工作方式是过滤器从会话存储的值填充 UserObj 参数。它不是由调用操作方法的代码传递的。我猜想是为了清理或集中代码或一些这样崇高的意图。
奇怪的是:看action方法。我传入一个名为 userId 的字符串参数。此 userId 是与 UserObj 参数中的用户不同的用户 ID(将其视为经理员工关系)。当操作过滤器执行时,它会根据需要填充用户参数,但由于某种原因,它会使用传递到操作方法中的 userId 参数(字符串)填充所述用户参数的 UserID 属性(int),从而导致 ModelState 变得无效,即使我不希望验证 UserObj 模型。
为什么拉里为什么!
解决方法很简单。重命名 userId 参数可以解决问题。
我的问题(最后)是:在不更改操作方法参数名称的情况下,如何阻止这种情况发生?
I've got a wierd/annoying little bug which I don't even know how to properly explain so forgive me if this becomes a bit wordy. Also, objects have been renamed for their protection ;)
The MVC site I'm working on (I didn't start it I'm just working on it) has a custom filter attribute that injects a parameter into any action method that is decorated with said filter. The parameter holds the details of the logged in user which are used to determine role based privileges. See example below:
[UserFilter]
public ActionResult DoSomeStuffDependingOnPrivileges(string userId, UserObj user)
The UserObj is a model. It looks a little like this:
public class User
{
[DisplayName("User ID")]
public int UserID { get; set; }
...
...
...
public IEnumerable<RoleModels.Role> Roles { get; set; }
}
Here's the custom action filter:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionParameters.ContainsKey(key))
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
var user = (User)filterContext.HttpContext.Session["User"];
filterContext.ActionParameters[key] = user;
}
}
base.OnActionExecuting(filterContext);
}
So the way it works is that the filter populates the UserObj parameter from the session stored value. It isn't passed by the code calling the action method. The idea I guess was to clean up or centralise the code or some such noble intention.
The weird thing is this: Look at the action method. I'm passing in a string parameter named userId. This userId is the ID of a different user than the one in the UserObj parameter (think of it as a manager employee relationship). When the action filter executes, it populates the user parameter as desired but for some reason it populates said user paremeter's UserID property (int) with the userId parameter (string) passed into the action method thus wich causes the ModelState to become invalid even though I did not wish to validate the UserObj model.
Why Larry why!
The work around is easy enough. renaming the userId parameter solves the problem.
My question (finally) is this: How, without resorting to changing the action method parameter name, do I stop this from happening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否尝试过使用 BindAttribute< /强>?
Have you tried using BindAttribute?
谢谢雅各布。
添加 BindAttribute 就可以了。
我将操作方法 UserObj 参数更改为
公共 ActionResult DoSomeStuffDependingOnPrivileges(string userId, [Bind(Exclude = "userId")] UserObj user)
Thanks Jakub.
Adding a BindAttribute did the trick.
I changed the action method UserObj parameter to
public ActionResult DoSomeStuffDependingOnPrivileges(string userId, [Bind(Exclude = "userId")] UserObj user)