javascript - 如何使用同步页面 POST 从 HTML 表单发送复杂的 JSON 对象?

标签 javascript jquery json servicestack

我的服务器正在使用 ServiceStack,并且希望接收如下数据:

{
    Customer: {
        Company: "TheCompany",
        RegionCode: "AU_NSW"
    },
    Name: {
        First: "Jimi",
        Last: "Hendrix"
    }

}

我有一个包含这些字段的表单,我可以使用 JQuery 轻松获取数据,创建嵌套的 JSON 对象并使用 $.post 发送它。

但我不想将其作为 AJAX 发送,因为我希望提交整个页面,然后浏览器将服务器的响应显示为新页面。只是经典的表单发布行为。

我尝试将复杂的 json 作为字符串嵌入隐藏表单字段中 - 没有雪茄。

我还查看了 ServiceStack 是否有任何命名约定,以便我可以将我的表单字段称为“Name[First]”,并让 ServiceStack 将正确的值放入其正确的嵌套结构中 - 也没有雪茄。

  1. 有没有办法可以在表单发送数据之前将 JSON 对象附加到表单的 POST 数据? 或
  2. 有没有办法可以使用 jQuery 进行整页提交(这样我就可以发送复杂的嵌套 JSON,同时仍然具有正常的“页面提交”行为)?

最佳答案

虽然 Mythz 关于发布 JSV 值的建议可行,但有时在 JavaScript 中构建和维护复杂的 JSV 会很麻烦。 例如,您可能必须处理转义用户输入的数据,并且语法问题可能很难跟踪

这个解决方案看起来很复杂,但实际上并不复杂,并且具有高度可重用性,并且只需要您可以发送编码的 JSON,这在 jQuery 中非常简单。

Full Demo Source Code Here

流程 - 工作原理:

  1. 您的 jQuery 使用提交时的表单数据创建 DTO
  2. DTO 被编码为 JSON,只需使用 JSON.stringify(data)
  3. JSON 以隐藏形式作为 Data 字段的值发送
  4. 服务器 DTO 属性过滤器将 Data 字段的 JSON 值反序列化到您的 DTO
  5. 您的服务会看到 DTO 已正常填充。

过滤属性:

我的解决方案将编码为 JSON 的 DTO 对象以表单发布的形式发送到服务。然后,一个简单的过滤器拦截请求并从 JSON 负载填充 DTO。

public class GetFromJsonVariableAttribute : Attribute, IHasRequestFilter
{
    string _variableName;

    public GetFromJsonVariableAttribute(string variableName = "Data")
    {
        _variableName = variableName;
    }

    public void RequestFilter(IRequest req, IResponse res, object requestDto)
    {
        // Convert the JSON payload to DTO format
        var payload = req.GetParam(_variableName);
        if(payload != null)
            requestDto = JsonSerializer.DeserializeFromString(payload, requestDto.GetType());
    }

    public int Priority { get { return int.MinValue; } }
    IHasRequestFilter IHasRequestFilter.Copy() { return this; }
}

用法

然后,要使用您只需将该属性添加到您的 DTO 中即可。 Data 是将保存 JSON 负载的表单变量的名称。您可以在这里选择任何您想要的名称。

[GetFromJsonVariable("Data")]
[Route("/Customers","POST")]
public class CreateCustomerRequest : IReturnVoid
{
    public Customer Customer { get; set; }
    public Name Name { get; set; }
}

客户端(jQuery):

  1. 获取表单值
  2. 将所需的 DTO 结构构建为 JavaScript 对象
  3. 将该 DTO 转换为 JSON 字符串
  4. 将隐藏表单值设置为 DTO 字符串并提交
$("#CreateCustomer").on("submit", function(){

    // Get the form values into simple key value array
    var values = {};
    $.each($(this).serializeArray(), function(){ values[this.name] = this.value; });

    // Prepare the DTO
    var data = {
        Customer: {
            Company: values["Company"],
            RegionCode: values["RegionCode"]
        },
        Name: {
            First: values["First"],
            Last: values["Last"]
        }
    };

    // Convert it to JSON
    $('#PayloadForm [name="Data"]').val(JSON.stringify(data));
    $('#PayloadForm').submit();
    return false;
});

使用 HTML 创建用户将与之交互的表单,无需任何操作,但链接到 jQuery 提交事件代码;以及一个将实际执行同步 POST 的隐藏表单。 请注意,Data 属性与应接收负载的属性相匹配

<form id="CreateCustomer">
    <input type="text" name="Company" value="TheCompany" /><br/>
    <input type="text" name="RegionCode" value="AU_NSW" /><br/>
    <input type="text" name="First" value="Jimi" /><br/>
    <input type="text" name="Last" value="Hendrix" /><br/>
    <input type="submit" value="Submit" />
</form>

<!-- This form is hidden -->
<form action="/Customers" method="POST" id="PayloadForm">
    <input type="hidden" name="Data" value="">
</form>

关于javascript - 如何使用同步页面 POST 从 HTML 表单发送复杂的 JSON 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23355017/

相关文章:

jquery - 如何从 KendoGrid 获取所有列名称?

ios - Swift 4 可解码,解码错误 : No value associated with key

c# - 在 ASHX AJAX C# 中获取 JSON

javascript - 使用 html 到 Canvas ,但也有 SVG

javascript - 如何在 jQuery 中通过 "this"引用 JavaScript 类?

javascript - jquery:如何将事件处理程序添加到动态添加的元素而不再次将其添加到现有元素

python - 如何 JSON 序列化集合?

javascript - 动画期间的 jQuery 碰撞检测

javascript - 如何链接这两个对象(图像映射形状和复选框)?

javascript - 将 jquery 函数添加到 Angular ng-repeat