验证 Ajax POST 请求的数据

发布于 2024-12-28 00:37:25 字数 2247 浏览 3 评论 0原文

我有一个订单输入页面和相应的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯狂的代价 2025-01-04 00:37:25

对于服务器:

public class Address
{
    [Required]
    [StringLength(50)]
    public string City { get; set; }
}

对于客户端,由于您使用的是 AddressCity 字段,因此它已经具有与从主视图模型应用的验证规则相同的验证规则。

但因为我猜你会告诉我这不是干的,好吧,OOP 来救援:

public class AddressViewModel
{
    [Required]
    [StringLength(50)]
    public string City { get; set; }
}

和你的主视图模型:

public class OrderCreateViewModel: AddressViewModel
{
    [Required]
    [StringLength(100)]
    public string Remark { get; set; }
}

以及你各自的控制器操作:

[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
    ...
}

[HttpPost]
public ActionResult AddAddress(AddressViewModel address)
{
    ...
}

For the server:

public class Address
{
    [Required]
    [StringLength(50)]
    public string City { get; set; }
}

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:

public class AddressViewModel
{
    [Required]
    [StringLength(50)]
    public string City { get; set; }
}

and your main view model:

public class OrderCreateViewModel: AddressViewModel
{
    [Required]
    [StringLength(100)]
    public string Remark { get; set; }
}

and your respective controller actions:

[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
    ...
}

[HttpPost]
public ActionResult AddAddress(AddressViewModel address)
{
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文