如何使用SYNCHRONOUS页面POST从HTML表单发送复杂的JSON对象? [英] How do I send a complex JSON object from an HTML form using SYNCHRONOUS page POST?

查看:87
本文介绍了如何使用SYNCHRONOUS页面POST从HTML表单发送复杂的JSON对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的服务器正在使用ServiceStack,并希望接收一些这样的数据:

My server is using ServiceStack and would like to receive some data like this:

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

}

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

I have a form which has these fields and I can easily grab the data using JQuery, make the nested JSON object and use $.post to send it through.

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

But I don't want to send it as AJAX, because I want the entire page to submit and then the browser to show the server's response as a new page. Just classic form post behaviour.

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

I have tried embedding the complex json as strings inside hidden form fields - No cigar.

我还查看了ServiceStack是否具有任何命名约定,以便可以将表单字段命名为"Name [First]",并让ServiceStack在其正确的嵌套结构中放置正确的值-也不存在雪茄.

I have also looked to see if ServiceStack has any naming conventions such that I could call my form fields "Name[First]" and have ServiceStack put the right values in their correct nested structure - no cigar on that either.

  1. 有没有一种方法可以在表单发送数据之前将JSON对象附加到表单的POST数据? 或
  2. 有没有办法用jQuery完成整页提交(这样我就可以发送复杂的嵌套JSON,同时仍具有正常的页面提交"行为)?
  1. Is there a way I can attach a JSON object to a form's POST data just before that form sends the data through? or
  2. Is there a way I can do a full page submission with jQuery (so I can send a complex nested JSON whilst still having the normal "page-submit" behaviour)?

推荐答案

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

While Mythz suggestion of posting JSV values would work, it can sometimes be cumbersome to build and maintain complex JSV in JavaScript. For example, you may have to deal with escaping user inputted data, and syntax issues can be hard to track

此解决方案看起来很复杂,但实际上并非如此,它具有很高的可重用性,只要求您可以发送经过编码的JSON,而从jQuery进行编码则非常简单.

This solution looks complex but it's really not, and is highly re-usable and only requires that you can send encoded JSON, which from jQuery is very easy.

  1. 您的jQuery使用提交时的表单数据创建DTO
  2. 只需使用JSON.stringify(data)
  3. ,DTO即可编码为JSON
  4. JSON以隐藏形式发送,作为Data字段的值
  5. 服务器DTO属性过滤器将Data字段的JSON值反序列化为DTO
  6. 您的服务看到DTO正常填充.
  1. Your jQuery creates the DTO using the form data on submit
  2. The DTO is encoded as JSON, simply using JSON.stringify(data)
  3. The JSON is sent in a hidden form as the value of Data field
  4. A server DTO attribute filter deserializes the JSON value of Data field into your DTO
  5. Your service see the DTO populated as normal.

过滤器属性:

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

Filter Attribute:

My solution sends the DTO object encoded as JSON in a form post to the service. Then a simple filter intercepts the request and populates the DTO from the JSON payload.

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有效负载的表单变量的名称.您可以在此处选择任何名称.

Usage

Then to use you simply add the attribute to your DTO. Data is the name of the form variable that will hold the JSON payload. You can choose any name you want here.

[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与应在其上接收有效载荷的属性相匹配

With the HTML create the form your user will interact with, with no action, but is linked to the jQuery submit event code; And a hidden form that will actually perform the synchronous POST. Note the attribute Data matches that of the attribute the payload should be received on

<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>

这篇关于如何使用SYNCHRONOUS页面POST从HTML表单发送复杂的JSON对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆