验证 Ajax POST 请求的数据
我有一个订单输入页面和相应的 ViewModel(简化示例):
public class OrderCreateViewModel
{
[Required]
[StringLength(100)]
public string Remark { get; set; }
[Required]
[StringLength(50)]
public string AddressCity { get; set; }
}
该模型用于创建视图:
@model MyNamespace.OrderCreateViewModel
@using (Html.BeginForm())
{
@Html.ValidationSummary(false)
@Html.EditorFor(model => model.Remark)
@Html.EditorFor(model => model.AddressCity)
<input type="submit" value="Create order" name="saveButton" />
}
控制器中 POST 请求的创建操作是:
[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
if (ModelState.IsValid)
{
// Save order in DB
return RedirectToAction("Index");
}
return View(viewModel);
}
订单(必填字段和字符串长度)在客户端上进行验证端(使用不显眼的 Javascript、jQuery 验证)和服务器端 (ModelState.IsValid
)。
现在,我向页面添加第二个按钮,其目的是将 Address
(示例中的 AddressCity
)保存在主表中。这应该发生在 Ajax POST 请求(使用 jQuery)中:
<input id="buttonAddAddress" type="button" value="Add address" />
一个点击事件处理程序被挂接到这个按钮,它读取与地址相关的输入字段的内容(示例中只有 AddressCity
)并且向服务器发送 POST 请求:
$("#buttonAddAddress").click(function () {
var address = JSON.stringify({
City: $('#AddressCity').val()
});
$.ajax({
type: 'POST',
url: '@Url.Action("AddAddress")',
data: address,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
...
});
});
控制器对此请求有相应的 POST 操作:
[HttpPost]
public ActionResult AddAddress(Address address)
{
// Create address in database
return Json(true);
}
Address
是辅助类型:
public class Address
{
public string City { get; set; }
// ...
}
此代码不会验证 AddressCity
是否是必需的,并且不能更长超过 50 个字符。
问题:如何向此 Ajax POST 请求添加验证 - 客户端和服务器端验证? 我不知道如何在客户端执行此操作。在服务器端,我想避免使用明显的简单解决方案来重复验证属性的含义(例如 if (!string.IsNullOrEmpty(address.City) && address.City.Length <= 50 ) ...
等)并利用现有的验证属性(如果可能的话)。
I have an order entry page and a corresponding ViewModel (simplified example):
public class OrderCreateViewModel
{
[Required]
[StringLength(100)]
public string Remark { get; set; }
[Required]
[StringLength(50)]
public string AddressCity { get; set; }
}
This model is used for the Create view:
@model MyNamespace.OrderCreateViewModel
@using (Html.BeginForm())
{
@Html.ValidationSummary(false)
@Html.EditorFor(model => model.Remark)
@Html.EditorFor(model => model.AddressCity)
<input type="submit" value="Create order" name="saveButton" />
}
The Create action for the POST request in the controller is:
[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
if (ModelState.IsValid)
{
// Save order in DB
return RedirectToAction("Index");
}
return View(viewModel);
}
The order (required fields and length of strings) gets validated on client side (using unobtrusive Javascript, jQuery validation) and on server side (ModelState.IsValid
).
Now, I add a second button to the page which has the purpose to save the Address
(AddressCity
in the example) in a master table. This is supposed to happen with an Ajax POST request (using jQuery):
<input id="buttonAddAddress" type="button" value="Add address" />
A click event handler is hooked to this button which reads the content of input fields related to the address (only AddressCity
in the example) and sends a POST request to the server:
$("#buttonAddAddress").click(function () {
var address = JSON.stringify({
City: $('#AddressCity').val()
});
$.ajax({
type: 'POST',
url: '@Url.Action("AddAddress")',
data: address,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
...
});
});
The controller has a corresponding POST action for this request:
[HttpPost]
public ActionResult AddAddress(Address address)
{
// Create address in database
return Json(true);
}
Address
is a helper type:
public class Address
{
public string City { get; set; }
// ...
}
This code doesn't validate that AddressCity
is required and must not be longer than 50 characters.
Question: How can I add validation to this Ajax POST request - client side and server side validation as well? I have no clue how to do it on client side. On server side I'd like to avoid the obvious trivial solution to repeat the meaning of the validation attributes (like if (!string.IsNullOrEmpty(address.City) && address.City.Length <= 50) ...
, etc.) and leverage the existing validation attributes if that is possible at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于服务器:
对于客户端,由于您使用的是 AddressCity 字段,因此它已经具有与从主视图模型应用的验证规则相同的验证规则。
但因为我猜你会告诉我这不是干的,好吧,OOP 来救援:
和你的主视图模型:
以及你各自的控制器操作:
For the server:
and for the client, since you are using the AddressCity field, it will already have the same validation rule as the one applied from the main view model.
But since I guess that you will tell me that this is not DRY, well, OOP to the rescue:
and your main view model:
and your respective controller actions: