如何在ModelBinder/UpdateModel方法中将子对象字段列入白名单/黑名单?

Fun*_*nka 7 asp.net-mvc

我有一个问题,关于如何获得MVC控制器的UpdateModel/TryUpdateModel的白名单和黑名单功能来处理子对象的各个属性.例如,假设我有一份调查问卷,收集有关填写表格的人和他或她公司的详细信息.

我的[简化]表单字段将被命名,例如:

YourName
YourEmail
Company.Name
Company.Phone
Run Code Online (Sandbox Code Playgroud)

现在在我的模型中,假设我不希望Company.ID或Company.IsPremiumMember被篡改,所以我想将它们从模型绑定中排除.我尝试了将白名单,黑名单和两者结合使用以使其发挥作用.我没有取得任何成功.这是我遇到的:

当我明确地在我的白名单中包含我上面写的相同的四个字段名称时,整个公司都没有受到限制(即问卷调查.公司保留为空),除非我在白名单中也包含"公司".但是这会对ENTIRE公司产生不良影响,而不仅仅是我想要的两个属性.

所以,我接着尝试将Company.ID和Company.IsPremiumMember包含在我的黑名单中,但这似乎被白名单所取代,并且"我认为事后"并没有过滤掉这些属性.

我知道还有其他方法来表达"绑定性",例如通过成员的[Bind]属性,但这并不理想,因为我希望在其他具有不同绑定规则的情况下使用相同的模型类,例如允许管理员设置她想要的任何属性.

我希望一个明显的答案是我应该编写自己的模型绑定器,并且我已经开始尝试研究如何做到这一点,但我真的希望使用"开箱即用"的解决方案什么(在我看来)似乎是一个非常常见的情况.我正在思考的另一个想法是制作我自己的ValueProvider字典以交给UpdateModel方法,但同样,如果有更简单的方法,我宁愿避免.

谢谢你的帮助!-麦克风


附录#1

以下是我在表单上提供的字段:

YourName
YourEmail
Company.Name
Company.Phone

这就是黑帽子送我的方式:

YourName=Joe+Smith&YourEmail=joe@example.com&Company.Name=ACME+Corp&Company.Phone=555-555-5555&Company.CreditLimit=10000000

(一定要注意到最后加上额外的参数!)

这是问题所在:

正如我最初发布的那样,似乎不可能(使用默认的模型绑定器)来阻止设置CreditLimit--它可能是整个公司,也可能没有 - 没有一些大的解决方法.我错了吗?


附录#2

我现在非常相信,我所拥有的简单目标不可能"开箱即用".我的解决方案是遍历已发布的表单字段并构建我自己的ValueProvider字典,从而将我想要允许的字段列入白名单,并将其交给UpdateModel.


附录#3

我还没有检查过AutoMapper,但是有了类似的东西,创建一些ViewModel/DTO来处理这种类型的复杂白名单的解决方案---以及轻松附加相同服务器端验证的能力(FluentValidation)我已经在我的域名对象上使用---似乎是一个可行的解决方案.谢谢大家!

yfe*_*lum 1

一般来说,最好的方法是创建视图模型,即专门为您的视图构建的模型。这些模型不是领域对象。它们是数据传输对象,旨在将数据从控制器操作传输到视图模板。您可以使用AutoMapper这样的工具轻松地从视图模型对象创建/更新域模型对象,或者从域模型创建/更新视图模型对象。