【问题标题】:Post handler doesn't parse serialized form后处理程序不解析序列化表单
【发布时间】:2021-07-03 03:16:15
【问题描述】:

我在互联网上阅读了很多关于处理通过 AJAX 调用传递给 POST 处理程序的表单值的教程。 他们都假设 serialized 表单被 Handler 方法解析,没有任何问题。不幸的是,就我而言,出了点问题,我无法从我的 序列化 表单中获取正确的值。

以下图片展示了 post 处理程序、用于表单和 ajax 调用的 html。

我想提一些额外的事情。 首先,根据教程,我想将表单字段封装在单独的类中,在本例中为 ResponseModel。无论如何,我无法从作为 ajax 参数传递的序列化表单中检索任何值。看起来表单是序列化的,因为我在记录 serializedForm 变量时可以看到正确的值。

当我将 response 参数的参数类型从 ResponseModel 更改为简单字符串时,字符串将传递给处理程序,我可以将该值作为字符串检索,但不能作为一个对象(这就是我所期望的)。只是无法理解为什么它在所有这些教程中都没有任何问题,而且我无法在我自己的项目中实现它。

所以我的问题 - 为什么后处理程序无法将序列化形式解析为预期的对象?

非常感谢

ResponseModel 类:

public class ResponseModel
{
    public string Status { get; set; }
    [Required]
    public string Description { get; set; }
}

输入字段的属性:

    [BindProperty]
    public ResponseModel EditedTicket { get; set; }

后处理程序:

    public async Task<JsonResult> OnPostUpdateTicket(ResponseModel response, int ticketId)
    {
        if (!ModelState.IsValid)
        {
            Debug.WriteLine("Model invalid");
        }

        return new JsonResult(new { success = true, message = "Ticket has been assigned!", errormessage = "Something went wrong, try again later" });
    }

表单 HTML:

            <form id="edit_ticket" method="post">
                <label asp-for="EditedTicket.Description">Description</label>
                <input asp-for="EditedTicket.Description" name="EditedTicket.Description" class="form-control" />
                <input id="update-ticket" type="submit" class="btn btn-success text-white" value="Update" />
            </form>

Ajax 调用:

    //Button submit
    updateTicketBtn.click(function (e) {
        e.preventDefault();
        var serializedForm = $('#edit_ticket').serialize();
        console.log('This is serialized form: ', serializedForm);

        $.ajax({
            type: "POST",
            url: "/QAView/ProjectDetails?handler=UpdateTicket",
            beforeSend: function (xhr) {
                xhr.setRequestHeader("XSRF-TOKEN",
                    $('input:hidden[name="__RequestVerificationToken"]').val());
            },
            dateType: 'application/json',
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',   
            data: { 'response': serializedForm, 'ticketId': ticketId }
        }).done(function (response) {
            console.log('Done!');
        })
    });

【问题讨论】:

  • 您发布从具有responseticketId 属性的对象格式转换而来的表单数据。为什么要将其映射到具有DescriptionStatus 属性的格式?这太清楚了为什么它们都是空的。你的data 应该是serializedForm
  • 顺便说一句,请发布您的实际代码而不是屏幕截图。
  • 我想传递两个参数 - 第一个是序列化形式 (response arg.),第二个是 javascript 代码捕获的数字 - tickedId。这就是为什么我的data 需要有两个键值对。 tickedId 值传递正确,唯一的问题是 response 参数仍然等于 null。我会在一分钟内替换这些屏幕截图。
  • 在这个论坛上发布问题总是迫使我尽快为自己的问题找到解决方案。通过为 html 表单添加正确的 name 属性解决了问题 - 我已将此属性的值从 EditedTicket.Description 更改为 Description,而没有明确引用属性名称。现在我的处理程序正在接收正确的数据。谢谢!
  • 如果您的数据仍然是 { 'response': serializedForm, 'ticketId': ticketId },则仅此一项是行不通的。我错过了关于表单元素名称的要点

标签: c# jquery asp.net-core razor


【解决方案1】:

您可以像这样附加您的额外信息(不包含在&lt;form&gt; 中):

var serializedForm = $('#edit_ticket').serialize();
serializedForm += "&ticketId=" + ticketId;
//...
//the posted data is changed to something like this:
data: serializedForm

对于模型ResponseModel,因为您通过属性EditedTicket 绑定它,所以在处理程序中不需要它,如下所示:

public async Task<JsonResult> OnPostUpdateTicket(int ticketId){
     //access the property EditedTicket here
     //...
}

如果你想通过参数绑定它,你需要这样的前缀设置:

public async Task<JsonResult> OnPostUpdateTicket([Bind(Prefix=nameof(EditedTicket))] ResponseModel response,
                                                 int ticketId){
    //...
}

【讨论】:

  • 感谢您提供这段 sn-p 代码,我希望它能让我的解决方案更加简洁。
  • @Tomitom 查看我更新的答案以获得更好的解决方案。如果您手动更新name属性,则不安全。在这种情况下,您应该使用asp-for,这意味着您需要坚持使用EditedTicket.Description
  • 现在完美运行!我从表单中删除了name 属性以及EditedTicket 属性的绑定。我认为通过处理程序参数绑定在我的情况下要好得多。非常感谢您简单明了的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 2017-08-06
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
相关资源
最近更新 更多