我们一直在迁移大量遗留代码和系统到ASP.NET MVC表单.我已经使用模型绑定,验证,属性等编写了许多与MVC 4的CRUD类型接口,所以我对这个范例非常熟悉.到目前为止,所有这些形式一直在我们的后端管理和&管理应用程序,它需要非常严格的输入验证.我们正在MVC推出我们的第一个面向消费者的应用程序,并面临着不同类型的问题.
问题
我们在该领域的传统形式是我们公司的主要收入引擎.消费者体验的可用性是当今的规则.为此,我们希望我们的表单尽可能宽松 – 遗留系统做了很多事情来自动纠正用户输入(当然,每次都是完全自定义的,非标准的方式).为此,我们并不需要输入验证,因为我们需要卫生设施.
例子
我们要求用户输入具有隐含度量单位的数字输入.常见的是货币金额或平方英尺.输入标签很清楚,他们不需要提供以下格式:
What is the approximate square footage? (example: 2000)
What is your budget? (example: 150)
人是人,不是每个人都遵循指示,我们经常得到如下答案:
approx 2100
1500 sq. ft.
$47.50,give or take
(好吧,我夸大了最后一个.)我们最终存储到业务逻辑中的模型接受这些字段的数字输入类型(例如int& float).我们当然可以使用datatype validator attributes(示例[DataType(DataType.Currency)]作为预算输入,或者只是将字段类型设置为平方英尺的整数),以清楚地向用户表明他们做错了,提供了有用的错误消息如:
The square footage must be numbers only.
然而,更好的用户体验是尝试尽可能宽松地解释他们的响应,因此他们可以尽可能少地中断完成表单. (注意我们有一个广泛的客户服务方面,他们可以在我们的系统之后解决错误,但我们必须让用户在我们联系之前填写表格.)对于上面的平方镜头示例,这只是意味着剥离非数字字符.对于预算,这将意味着剥离不是数字或小数点的所有内容.只有这样我们才能应用其余的验证(是一个数字,大于0,小于50000等)
我们坚持采取最佳方法来实现这一目标.
潜在解决方案
我们已经考虑了自定义属性,@R_404_5670@绑定以及将在模型和数据库之间存在的单独的scrubber服务类.以下是我们在尝试确定方法时考虑的一些注意事项.
自定义验证属性
我已经阅读了很多有用的资源. (它们具有不同程度的相关性和新近性.我找到的很多东西都是为MVC2或MVC3编写的,并且可以在MVC4中使用标准属性.)
> Extending ASP.NET MVC’s Validation
> Custom Validation Attribute in ASP.NET MVC3
>很多问题&有关输入清理的主题,主要关注跨站点脚本攻击或数据库注入.
我没有找到任何人做我想做的事情,这将改变模型价值本身.我显然可以创建值的本地副本,清理它并提供通过/失败,但这会导致大量重复的代码.在保存到数据库之前,我仍然需要再次清理任何输入值.
更改模型值本身有3个好处:
>它影响后续验证规则,这将提高其接受率.
>该值更接近将放入数据库的值,从而减少了额外的准备工作.存储前需要的映射开销.
>如果表单因其他原因被拒绝,它会向用户轻轻地建议“你正在努力尝试这些领域.”
这是一种有效的方法吗?是否有人以这种方式使用验证属性,我错过了?
@R_404_5670@绑定
我阅读了Splitting DateTime – Unit Testing ASP.NET MVC Custom Model Binders,重点关注自定义日期时间输入字段以及自定义验证&解析在模型绑定层完成.这与模型本身更接近,所以它似乎是修改模型值的更合适的地方.实际上,示例类DateAndTimeModelBinder:IModelBinder正好在几个地方完成.
但是,为此示例提供的控制器 *** 作签名不使用整体模型类.看起来像这样
public ActionResult Edit(int ID,[DateAndTime("year","mo","day","hh","mm","secondsorhwatever")] DateTime foo) {
而不是这个
public ActionResult Edit( MyModelWithADateTimeProperty model) {
在此之前不久,文章确实说
First,usage. You can either put this Custom Model Binder in charge of all your DateTimes by registering it in the Global.asax:
ModelBinders.Binders[typeof(DateTime)] = new DateAndTimeModelBinder() { Date = "Date",Time = "Time" };
这足以在单参数模型示例MyModelWithADateTimeProperty上调用日期时间字段的模型绑定吗?
我在这里看到的另一个可能的缺点是模型绑定器对类型进行 *** 作,而不是可以应用于标准数据类型的属性.因此,例如,我想要应用的每组验证规则都需要一个新的自定义类型.这不一定是坏事,但它可能会变得混乱并导致大量重复的代码.想像:
public class MyDataModel { [required] public CurrencyType BudgetRange { get; set; } public PositiveOnlyCurrencyType PaymentAmount { get; set; } [required] public StripNonDigitsIntegerType SquareFootage { get; set; }
不是我见过的最丑的模型代码,但也不是最漂亮的.
自定义,外部洗涤器类
这对我来说问题最少,但也有最大的缺点.我之前做过一些这样的事情,只是因为以下原因之一而后悔:
>与控制器和模型分离,几乎不可能优雅地将其验证规则扩展到客户端.
>它彻底混淆了不同模型字段的可接受输入和不可接受的输入.
>它会产生一些非常麻烦的箍,用于向用户显示错误.您必须将模型状态传递给scrubber服务,这使得您的scrubber服务与MVC框架唯一关联.或者,您必须使您的scrubber服务能够以控制器可以消化的格式返回错误,这比通常建议用于控制器的逻辑更多.
问题
你会采取哪种方法(或者,你已经采取过)来实现这种类型的消毒?它为你解决了什么问题?你遇到了什么问题?
解决方法 我会采用ModelBinder方法.当表单数据进入时 – 它转到模型绑定器基础结构.在那里你可以覆盖十进制模型绑定器来优化输入.之后,您可以将其发送到验证例程,而无需编写特定的验证属性或类似的东西.
此外,您可以使用一个智能模型绑定器,它将执行internaly类型切换或覆盖ModelBinderProvIDer,因此您的代码不会使用ModelBinderAttribute膨胀.这是Jimmy Bogart article.此外,您将获得一些灵活性,因为您可以使用属性来声明模型是否使用严格绑定或自适应绑定.
总体而言,恕我直言,验证属性不会改变输入.他们应该验证它.模型绑定器实际上负责将所有奇怪的东西转换为系统中可用的东西,而第三种方法重复模型绑定器功能
希望这对我的英语有帮助和抱歉)
总结以上是内存溢出为你收集整理的c# – 更正ASP.NET MVC4中的用户输入全部内容,希望文章能够帮你解决c# – 更正ASP.NET MVC4中的用户输入所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)