首先,一点上下文(因为我知道你们都喜欢它!):
我有一个名为注意的模型。它有一个名为 Type 的字段,在数据库中,它是一个整数值,用于指定此注释所属的对象类型(1 = Customer,2 = Sales Lead等)。第二个名为 Source 的字段指定此便笺所属的特定对象的ID。
例如,如果我想向客户#34添加注释,我会将类型设置为1,将源设置为34。
为了让事情更具可读性,我有一个名为 DataObjectType 的枚举,它包含每个可能的 Type 整数值到友好名称的映射。因此,例如, DataObjectType.Customer 与类型字段中的值1相同。
接下来,我有一个自定义路线:
/Notes/New/{type}/{id}
和两个控制器动作来处理新笔记的创建:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult New(DataObjectType type, int id) {
Note note = new Note { Type = type, Source = id };
return View(note);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Note note) {
// This is just an example
note.Persist();
return View("New", note);
}
首先,我需要确保提供给 {type} 路由值的值对 DataObjectType 枚举有效。这可以通过路线约束来完成吗?目前, New()的类型参数将接受任何整数,无论它是否存在于 DataObjectType 中。
其次,在显示New Note表单之前,我需要确保用户正在尝试将该注释添加到数据库中的对象。我可以轻松地在 New()方法中执行此操作,但可能会有一段时间用户将数据直接发布到创建()而无需访问新()即可。在这种情况下,我还需要验证该对象是否存在于 Create()方法中。在没有重复代码的情况下,在两种方法中执行此操作的最佳方法是什么?
答案 0 :(得分:1)
设置路线时,可以使用参数指定约束(通过Regex完成)。你可以使用它来限制那里的id,但你必须为这个场景创建一个单独的路由,因为你不希望在该规则上过滤所有“id”。
或者,你可以在控制器动作开始时坚持这个检查。
至于确保数据库中已存在该注释,我无法看到在创建操作的开头粘贴检查的任何方法。
答案 1 :(得分:1)
您是正确的,New和Create操作都需要确保他们传递了有效的模型。这样做的正确位置是模型绑定器。如果传递了无效对象(或Id),模型绑定器应添加模型状态错误。 New和Create可能使用相同的模型绑定器。
不要将路由约束与用户输入验证混淆。当您没有自己指定路径时(即,当您使用Html.ActionLink而不是RouteLink时),路径约束只是帮助路由系统找到合适的路径。如果您使用命名路由,那么您应该使用约束来查找适当的路由,因为您已直接指定了路由。路由约束旨在防止某个路由被选择用于其未设计处理的操作,并且不是验证用户输入的位置。
您要求的功能是一种用户输入验证,即使有问题的用户输入恰好在URL中。如果您要超越这个简单的单一案例,您可能需要考虑使用验证框架,因为这将使其他类型的验证更加简单。 Here is one which looks interesting to me