我们已经将大量的旧代码和系统迁移到ASP.NET MVC表单。我已经使用模型绑定,验证,属性等使用MVC 4编写了许多CRUD类型的接口,因此我对整个范例相当熟悉。到目前为止,所有这些表格都已在我们的后端管理和管理应用程序中使用,在那里必须进行非常严格的输入验证。我们正在MVC中启动我们的第一个面向消费者的应用程序,并且面临着其他类型的问题。
我们在这方面的传统形式是我们公司的主要收入引擎。消费者体验的可用性是日常工作。为此,我们希望表格尽可能宽大-传统系统做了很多事情来自动纠正用户输入(当然,每次都以完全自定义,非标准的方式)。为此,我们不希望输入验证,而是想要卫生。
我们要求用户提供隐含度量单位的数字输入。常见的是货币金额或平方英尺。输入标签很清楚,他们不需要提供以下格式:
大概平方英尺是多少?(例如:2000年)
你的预算是多少?(例如:150)
人是人,不是每个人都遵循指示,我们经常得到如下答案:
约2100
1500平方呎
$ 47.50,给予或接受
(好吧,我在最后一个方面夸大了。)我们最终存储到业务逻辑中的模型接受这些字段的数字输入类型(例如int和float)。我们当然可以使用数据类型验证器属性(例如[DataType(DataType.Currency)]
,预算输入,或者仅将字段类型作为平方英尺的整数)来向用户清楚地表明他们做错了,提供有用的错误消息,例如:
平方英尺必须仅是数字。
但是,更好的用户体验将是尝试尽可能宽大地解释其响应,以便他们可以尽可能少地打断表格。(请注意,我们有一个广泛的客户服务部门,可以在以后解决我们系统上的错误,但是在联系之前,我们必须让用户填写表格。)对于上面的平方英尺示例,这仅意味着剥离非数字字符。对于预算,这意味着要删除所有不是数字或小数点的内容。只有这样,我们才能应用其余的验证(是一个数字,大于0,小于50000等)
我们坚持采用最佳方法来完成此任务。
我们考虑了自定义属性,自定义模型绑定以及将存在于模型和数据库之间的单独的洗涤器服务类。这是我们在尝试确定方法时已考虑的一些注意事项。
我已经阅读了许多有用的资源。(它们具有不同程度的相关性和新近度。我发现搜索该内容的很多东西都是为MVC2或MVC3编写的,并且在MVC4中具有标准属性。)
我还没有发现有人在做我想做的事,那就是改变模型值本身。我显然可以创建该值的本地副本,对其进行清理并提供通过/失败的指示,但这将导致大量重复代码。在保存到数据库之前,我仍然必须再次清理所有输入值。
更改模型值本身具有3个好处:
这是有效的方法吗?那里有人以我刚刚错过的方式使用过验证属性吗?
我阅读了Splitting DateTime-ASP.NET MVC定制模型绑定器的单元测试,它着重于定制日期时间输入字段,并在模型绑定层完成了定制验证和解析。这与模型本身相距很近,因此似乎更适合修改模型值。实际上,该示例class DateAndTimeModelBinder : IModelBinder
确实在几个地方做到了这一点。
但是,为此示例提供的控制器动作签名未使用整体模型类。看起来像这样
public ActionResult Edit(int id,
[DateAndTime("year", "mo", "day", "hh","mm","secondsorhwatever")]
DateTime foo) {
而不是这个
public ActionResult Edit(
MyModelWithADateTimeProperty model) {
在此之前不久,文章确实说
首先,用法。您可以通过在Global.asax中注册该Custom Model Binder来管理所有DateTime:
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; }
不是我见过的最丑陋的模型代码,但也不是最漂亮的。
这对我来说问题最少,但缺点也最多。之前,我已经做过几件事,但出于以下原因之一,我对此感到非常遗憾:
您将采取(或已采取)哪种方法来完成这种消毒?它为您解决了什么问题?您遇到了什么问题?
我将采用ModelBinder方法。
当输入表单数据时,它将进入活页夹基础设施模型中。在那里,您可以覆盖十进制模型联编程序以细化输入。之后,您可以将其发送到验证例程,而无需编写特定的验证属性或类似内容。
另外,您可以使用一种智能模型绑定程序,该绑定程序可以在内部进行类型切换或覆盖ModelBinderProvider,因此您的代码不会因ModelBinderAttribute而肿。这是关于吉米·博加特(Jimmy Bogart)的文章。您还将获得一些灵活性,因为您可以使用属性来声明模型是使用严格绑定还是自适应绑定。
总的来说,恕我直言,验证属性不会更改输入。他们应该验证它。实际上,模型联编程序负责将所有奇怪的东西转换为系统中可用的东西,而第三种方法则与模型联编程序功能相同)
希望对您有所帮助,对不起我的英语)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句