当使用ASP.NET MVC3的jquery不引人注目的客户端验证失败时,强制进行服务器端验证
本文关键字:验证 失败 服务器端 引人注目 ASP NET MVC3 jquery 客户端 | 更新日期: 2023-09-27 18:20:52
我将展示一些最低限度的代码,因为我认为我的公司不希望我展示太多,尽管我们目前只是在做研究。
我们在实体框架4中使用POCO将数据保存回数据库。我们正在使用数据注释来减少我们必须进行的重复验证的数量(这是我们旧的经典ASP解决方案的一个问题,我们在应用程序的三个不同级别上进行了相同的验证)。
我们希望在我们的模型中包括业务规则,其中包括确保根据其他表验证的字段是有效的(我们在模型中不使用下拉菜单,因此用户可以键入任何内容)。例如,我们正在存储建筑物中的房间信息。房间有一个名为"房间类型"的字段。有效的房间类型在另一个表中定义。
我们还希望立即进行客户端验证。例如,我们的数字字段必须介于0和32767之间。如果用户输入-1,我们使用客户端验证立即响应用户,让他们知道-1无效。我们通过启用客户端验证和使用数据注释来实现这一点。
Web配置:
<appSettings>
<add key="webpages:Version" value="1.0.0.0" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
型号:
public class Room : IValidatableObject
{
// I'm only showing the relevant properties...
// this is a field that's validated based on another table in the database.
// (In the model we are using autocomplete instead of a dropdown -- it's a long
// story --, so potentially invalid data can be passed through the form...
[DisplayName("Room Type"), MaxLength(5)]
public String RoomType { get; set; }
// A number field, with a range.
[Range(0, 32767), DisplayName("Maximum Seats")]
public Int16? MaxStudents { get; set; }
// do server side validation for this entity.
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validateErrors = new List<ValidationResult>();
// make sure room type is a valid type
if(!String.IsNullOrEmpty(RoomType)) {
// hit database, which is a little weird since we need to create a context,
// and I know that might make some people's brains explode
}
// return all of the errors
return validateErrors;
}
}
控制器:
// I didn't include all the actions, just edit
public ActionResult Edit(Int32 Building, String RoomID)
{
// return a single room and show the detail information in edit mode.
Room room = findRoom(Building, RoomID);
return View(room);
}
[HttpPost]
public ActionResult Edit(Int32 Building, String RoomID, FormCollection collection)
{
// get the current room from the database.
Room room = findRoom(Building, RoomID);
// save the room being edited, but don't touch the key fields.
if (TryUpdateModel(room, null, null, new string[] {"Building", "RoomID"}))
{
// if the entity changed, audit and save
if (db.Entry(room).State == EntityState.Modified)
{
db.setLastUpdate(room); // this is a function in our context for auditing
db.SaveChanges();
}
}
return View(room);
}
视图:(不想显示用于创建自动完成的javascript…)
@using (Html.BeginForm()) {
@Html.ValidationSummary(false, "The following errors occured when attempting to save this Room:")
<fieldset>
<legend>Room</legend>
<div class="field-block">
<div class="editor-label">
@Html.LabelFor(model => model.Building)
</div>
<div class="editor-field">
@Html.DisplayFor(model => model.Building)
</div>
</div>
<div class="field-block">
<div class="editor-label">
@Html.LabelFor(model => model.RoomID)
</div>
<div class="editor-field">
@Html.DisplayFor(model => model.RoomID)
</div>
</div>
<div class="field-block">
<div class="editor-label">
@Html.LabelFor(model => model.RoomType)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.RoomType)
</div>
</div>
<div class="field-block">
<div class="editor-label">
@Html.LabelFor(model => model.MaxStudents)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.MaxStudents)
@Html.ValidationMessageFor(model => model.MaxStudents)
</div>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
我注意到,如果用户在Maximum Seats字段中键入-1,客户端验证将启动,并让用户知道该值必须在0到32767之间。
如果用户单击提交,客户端验证将再次启动,并显示在表单顶部的验证摘要中
如果用户在Maximum Seats中输入了有效值,但在Room Type字段中输入了错误值,则客户端验证表明没有错误(我理解,因为Room Type没有在客户端上进行验证),如果用户单击Submit,则在TryUpdateModel()
调用期间调用IValidateObject.Valide函数,返回验证错误,然后在表单顶部的验证摘要中显示在页面上。
但是,如果用户键入错误的数字(-1)和无效的房型,并单击"提交",客户端验证将启动,但服务器端验证不会启动,因此他们只会看到与客户端相关的错误。
JavaScript中是否有一个设置或一些技巧可以用来调用客户端和服务器端验证?
如果没有,我认为我唯一的选择是在验证服务器端执行所有,这将在用户从一个字段到另一个字段时减少反馈,或者在客户端执行房型验证(通过ajax调用检查房型表中的值),这将重复工作。
有什么想法吗?
我认为远程验证是您想要的。这样,您就可以完成您提到的使用ajax进行验证的操作。您在客户端上进行数字验证,在服务器上进行房间验证,结果将与客户端验证一起报告。