我的服务器正在使用ServiceStack,并希望收到一些这样的数据:
{
Customer: {
Company: "TheCompany",
RegionCode: "AU_NSW"
},
Name: {
First: "Jimi",
Last: "Hendrix"
}
}
我有一个包含这些字段的表单,我可以使用JQuery轻松获取数据,创建嵌套的JSON对象并使用$ .post发送它。
但我不想将其作为AJAX发送,因为我希望整个页面都提交,然后浏览器将服务器的响应显示为新页面。只是经典的表单帖子行为。
我尝试将复杂的json作为字符串嵌入隐藏的表单字段中 - 没有雪茄。
我还查看了ServiceStack是否有任何命名约定,以便我可以调用我的表单字段“Name [First]”并让ServiceStack将正确的值放在正确的嵌套结构中 - 也就是没有雪茄。
答案 0 :(得分:6)
虽然Mythz建议发布JSV值会起作用,但在JavaScript中构建和维护复杂的JSV有时会很麻烦。 例如,您可能必须处理转义用户输入的数据,并且语法问题可能难以跟踪
这个解决方案看起来很复杂,但实际上并非如此,并且具有高度可重用性,只需要您可以发送编码的JSON,而jQuery非常容易。
JSON.stringify(data)
Data
field Data
字段的JSON值反序列化到您的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; }
}
$("#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>
答案 1 :(得分:1)
ServiceStack可以POST complex types using the JSV Format,例如:
<input name="Customer" value="{Company:TheCompany,RegionCode:AU_NSW}" />
<input name="Name" value="{First:Jimi,Last:Hendrix}" />
否则,您可以使用JSON发送复杂类型,例如使用jQuery的$ .ajax:
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: "http://host/myservice",
dataType: 'json',
data: JSON.stringify({Customer:{Company:'x',RegionCode:'x'}}),
success: function(response){ ... }
});
尽管为了实现最大的互操作性,您应该努力使您的请求DTO保持不变,例如:
<form id="theForm" ...>
<input name="Company" value="TheCompany" />
<input name="RegionCode" value="AU_NSW" />
<input name="FirstName" value="Jimi" />
<input name="LastName" value="Hendrix" />
</form>
然后您可以按原样使用x-www-form-urlencoded
Content-Type进行POST,或使用ServiceStack's ss-utils.js bindForm method进行ajaxify,例如:
$("#theForm").bindForm();
答案 2 :(得分:0)
将一个提交处理程序附加到表单,该表单将JSON作为表单中预先创建的隐藏输入字段的值。
$(form_to_submit).on('submit', function() {
$(form_to_submit).find(hidden_input).val(json_value);
});
使用jQuery提交表单:
$(form_to_submit).submit();
答案 3 :(得分:0)
我在这里遇到了同样的问题,我在使用NodeJS和Express Server。我想发布一个复杂的JSON对象,我已经构建为用户选择的客户端。然后我将onClick事件附加到一个调用我的SubmitForm函数的按钮。
您的数据可以是任何JSON对象。请务必解析服务器端。
function Param(name, value){
var hiddenField = document.createElement('input');
hiddenField.setAttribute('type', 'hidden');
hiddenField.setAttribute('name', name);
hiddenField.setAttribute('value', value);
return hiddenField;
}
function SubmitForm(data){
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', '/route');
form.appendChild(Param('data', JSON.stringify(data)));
document.body.appendChild(form);
form.submit();
}
此外,这是纯粹的JavaScript。对于那些喜欢消除开销的人来说,这里没有隐藏的HTML或jQuery。