Javascript AJAX发送到控制器未正确设置VIewModel参数
当一个字段通过AJAX更改时,我试图将参数发布到控制器操作,但找到的第一个参数总是空的 我试图发布到的控制器操作是:Javascript AJAX发送到控制器未正确设置VIewModel参数,javascript,ajax,asp.net-mvc,jquery,Javascript,Ajax,Asp.net Mvc,Jquery,当一个字段通过AJAX更改时,我试图将参数发布到控制器操作,但找到的第一个参数总是空的 我试图发布到的控制器操作是: public ActionResult Model_GroupCompanyIDChanged(ActionViewModel vm, int oldVal, int newVal) { vm.Model.Observation = "Changed from " + oldVal + " to " + newVal;
public ActionResult Model_GroupCompanyIDChanged(ActionViewModel vm, int oldVal, int newVal)
{
vm.Model.Observation = "Changed from " + oldVal + " to " + newVal;
return Refresh(vm);
}
我的post代码在屏幕上序列化表单,并将其与刚刚更改的字段的新旧值一起发布。在操作参数中正确设置了新旧值参数,但在控制器操作中vm参数始终为空。控制器URL没有问题,因为我可以调试该操作并看到它被调用
function ChangeRefreshScreen(ControllerURL, formActionUrl, oldVal, newVal) {
var origModel = $("form[action='" + formActionUrl + "']").serialize();
var data = {
"oldVal": oldVal
, "newVal": newVal
, "vm": origModel
};
RefreshScreenPassData(ControllerURL, formActionUrl, data);
}
function RefreshScreenPassData(ControllerURL, formActionUrl, data) {
alert(data);
$.ajax({
url: ControllerURL,
type: 'POST',
data: data,
success: function (response) {
RefreshScreenContent(response);
},
error: AjaxError
});
}
与单击某个字段时处理的同一屏幕上的以下内容相比:
控制器操作:
public ActionResult Model_ActionDateClicked(ActionViewModel vm)
{
vm.Model.Observation = "Clicked";
return Refresh(vm);
}
JavaScript(使用与上面相同的RefreshScreenPassData函数执行实际POST):
简而言之,第一个更改事件示例首先将参数设置为对象,因为存在多个参数,并且只有旧的和新的int参数在ViewModel vm为null时设置在服务器端。在第二个单击的示例中,使用序列化表单正确设置了vm
formActionUrl参数对于两者都是相同的,并且不是问题所在,因为我调试了帖子,我能看到的唯一区别是对于第一个示例(更改事件)中的请求主体,vm参数看起来是URL编码的:
oldVal=0&newVal=02&vm=uuu请求验证打开%3DoeQx0RyQ-Nopq1namoieruawrzfvltfpx5Ntsdpauftsdadugh_uu_5;y54hlwmf8aoaigyH8R_6;6qp77bjr1MM5YAG7R9OSQSe6e9NjMYG1%26视图模式%3编辑%26模型。操作日期%3D11%252F07%252F2013%2B09%253A32%253A32%253A08%26模型。观察%26点击%26模型。原始用户ID%3dOnUserID%26模型。操作状态%3%3D1%26Model.ActionTypeID%3D0%26Model.ClientID%3D23%26Model.ClientContactID%3D0%26Model.PriorityID%3D0%26Model.CloseOutDate%3D%26Model.ActionNotes%3D%26Model.ProgressNotes%3D%26Model.CommentId%3D0%26Model.GroupCompanyID%3D02%26Model.机密%3Dfalse%26Model.Id%3D1%26Model.Archived%3Dfalse%26Model.AddedUserID%3D1%26Model.AddedDataTime%3D11%252F07%252F2013%2B09%253A32%253A19%26模型。ModifiedUserID%3D1%26模型。ModifiedDataTime%3D11%252F07%252F2013%2B09%253A32%253A19
但对于正在工作的第二个单击事件,它不是:
__RequestVerificationToken=oeQx0RyQ-NOPQ1NAMOIERUAWRZFVLTFPX5NTSDPUAFTSDAUG\u eC\u Y54hlWmf8AOAigvyH8R\u 6QP77BJR1MM5YAG7R9OSQSE9NJMYG1&ViewMode=Edit&Model.ActionDate=11%2F07%2F2013+09%3A32%3A08&Model.Observation=Changed&Model.OrigatorUserID=1&Model.ActionUserID=0&Model.ActionStatusID=1&Model.ActionTypeID=0&Model.ClientContactID=0&Model.PriorityID=0&Model.CloseOutDate=&Model.ActionNotes=&Model.ProgressNotes=&Model.Comments=&Model.BusinessUnitID=0&Model.GroupCompanyID=0&Model.Confidential=false&Model.Id=1&Model.Archived=false&Model.AddedUserID=1&Model.addedStateTime=11%2F07%2F2013+09%3A32%3A19&Model.ModifiedUserID=1&Model.module.modifiedStated=11%2F07%2F07%2F2013+09%3A19
我试图通过将javascript更改为:
function ChangeRefreshScreen(ControllerURL, formActionUrl, oldVal, newVal) {
var origModel = $("form[action='" + formActionUrl + "']").serialize();
var data = "oldVal=" + oldVal + "&newVal=" + newVal + "&vm=" + origModel
RefreshScreenPassData(ControllerURL, formActionUrl, data);
}
请求后的主体更改为
oldVal=02&newVal=023&vm=\uuuu RequestVerificationToken=xiYEcz53UNPVoGZ3RQGO\uHFN54liu0btjqb-pb13ttewz7vuhmbsw25s7ri7d7lbltacutepynonnk66jxijzzfzfmcbo\u nDoXf\u FqsR9Cc81&ViewMode=11%2F07%2F2013+09%3A32%3A08&Model.Observation=Clicked&Model.Model.OriginatorUserID=1&Model.actionUserid=0&Model.actionUserid=0&ModelentID=23&Model.ClientContactID=0&Model.PriorityID=0&Model.CloseOutDate=&Model.ActionNotes=&Model.ProgressNotes=&Model.BusinessUnitID=0&Model.GroupCompanyID=023&Model.Confidential=false&Model.Id=1&Model.AddedUserID=1&Model.AddedDateTime=11%2F07%2F2013+09%3A32%3A19&Model.ModifiedUserID=1&Model.ModifiedDateTime=11%2F07%2F2013+09%3A32%3A19
但它仍然不绑定视图模型参数
当参数来自JavaScript对象时,如果不设置参数,我做错了什么
更新1
我曾尝试手动调用JSON stringify以使其正常工作,但仍然不起作用:
function ChangeRefreshScreen(ControllerURL, formActionUrl, oldVal, newVal) {
var origModel = $("form[action='" + formActionUrl + "']").serialize();
var data = "oldVal=" + oldVal + "&newVal=" + newVal + "&vm=" + JSON.stringify(origModel)
RefreshScreenPassData(ControllerURL, formActionUrl, data);
}
更新2
以下内容适用于我,它将旧VAL和新VAL添加到表单中,但需要再次删除它们,否则下一次它们在表单中多次结束时,会导致旧VAL和新VAL发生错误:
function ChangeRefreshScreen(ControllerURL, formActionUrl, oldVal, newVal) {
var $myForm = $("form[action='" + formActionUrl + "']");
$myForm.append("<input type='hidden' name='oldVal' value='" + oldVal + "' id='oldVal' />");
$myForm.append("<input type='hidden' name='newVal' value='" + newVal + "' id='newVal' />");
var origModel = $myForm.serialize();
RefreshScreenPassData(ControllerURL, formActionUrl, origModel);
$('#oldVal').remove();
$('#newVal').remove();
}
函数更改刷新屏幕(ControllerURL、formActionUrl、oldVal、newVal){
var$myForm=$(“form[action='“+formActionUrl+'”);
$myForm.append(“”);
$myForm.append(“”);
var origModel=$myForm.serialize();
RefreshScreenPassData(控制器URL、formActionUrl、原始模型);
$('#oldVal')。删除();
$('#newVal')。删除();
}
最好不要将元素添加到DOM中,但至少它是一小段代码,并且不占用CPU。我仍然希望再次尝试Gordatron的一种解决方案,看看是否可以让它工作,但可能没有时间。方法1 似乎篡改表单数据对您不起作用 你试试下面的怎么样
function ChangeRefreshScreen(ControllerURL, formActionUrl, oldVal, newVal) {
var $myForm = $("form[action='" + formActionUrl + "']");
$myForm.append("<input type='hidden' name='oldVal' value='" + oldVal + "' />");
$myForm.append("<input type='hidden' name='newVal' value='" + newVal + "' />");
var origModel = $myForm.serialize();
RefreshScreenPassData(ControllerURL, formActionUrl, origModel);
}
var form = $("form[action='" + formActionUrl + "']").toJSON();
var data = {
"oldVal": oldVal,
"newVal": newVal,
"vm": form
};
i、 e.在JSON对象中,您正在添加一个序列化的表单作为vm
。这就是为什么当oldVal
和newVal
正确填充时,您的操作中的vm
中会出现空值的原因
我建议,如果您不希望使用我的回答中提供的上述解决方案,您应该使用仅JSON的方法。i、 e.使用表单值创建JSON对象,并使用
$.ajax({
type: 'POST',
url: ControllerURL,
contentType: "application/json",
data: JSON.stringify(data),
success: function (response) {
RefreshScreenContent(response);
},
error: AjaxError
});
注意:contentType:“application/json”
我知道使用id/names获取表单的所有值并创建一个JSON对象会有点累,但幸运的是,我不久前写了一篇小文章,为您做到这一点
你所需要做的就是跟随
function ChangeRefreshScreen(ControllerURL, formActionUrl, oldVal, newVal) {
var $myForm = $("form[action='" + formActionUrl + "']");
$myForm.append("<input type='hidden' name='oldVal' value='" + oldVal + "' />");
$myForm.append("<input type='hidden' name='newVal' value='" + newVal + "' />");
var origModel = $myForm.serialize();
RefreshScreenPassData(ControllerURL, formActionUrl, origModel);
}
var form = $("form[action='" + formActionUrl + "']").toJSON();
var data = {
"oldVal": oldVal,
"newVal": newVal,
"vm": form
};
希望这有帮助我做了一个小测试来看看
public class Item {
public string id {get;set;}
public string name { get; set; }
}
<h2>Test</h2>
@using(Html.BeginForm()){
@Html.EditorFor(Model => Model.id)
@Html.EditorFor(Model => Model.name)
}
$(function () {
var origModel = $("form").serialize();
var data = {
"oldVal": 'old'
, "newVal": 'new'
, "vm": origModel
};
RefreshScreenPassData("/Home/Test", data);
});
function RefreshScreenPassData(ControllerURL, data) {
alert(data);
$.ajax({
url: ControllerURL,
type: 'POST',
data: data,
dataType:'json',
success: function (response) {
RefreshScreenContent(response);
},
error: AjaxError
});
}
function AjaxError(e) {
alert(e);
}
[HttpGet]
public ActionResult Test() {
return View(new Item() { id = "1", name = "name" });
}
[HttpPost]
public ActionResult Test(Item vm, string oldVal,string newval) {
return View(new Item() { id = vm.id+"oo", name = vm.name+"000" });
}
$.ajax({
url: ControllerURL,
type: 'POST',
data: {
"oldVal": 'old'
, "newVal": 'new'
, "vm": {"id":"1","name":"name"}
},
success: function (response) {
RefreshScreenContent(response);
},
error: AjaxError
});
$.ajax({
url: ControllerURL,
type: 'POST',
data: {
"oldVal": 'old'
, "newVal": 'new'
, "id": "1"
, "name": "name"
},
success: function (response) {
RefreshScreenContent(response);
},
error: AjaxError
});
id=1&name=name
jQuery(function () {
var data = {
"oldVal": 'old'
, "newVal": 'new'
};
var o = {};
var a = $("form").serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
jQuery.extend(data, o);
RefreshScreenPassData("/Home/Test", data);
});
function RefreshScreenPassData(ControllerURL, data) {
alert(JSON.stringify(data));
$.ajax({
url: ControllerURL,
type: 'POST',
data: data,
success: function (response) {
alert(response);
},
error: AjaxError
});
}
public class Item {
public string id {get;set;}
public string name { get; set; }
}
public class ViewModel {
public Item model { get; set; }
public String CapsName { get { return this.model.name.ToUpper(); } }
public String OtherField { get; set; }
}
[HttpGet]
public ActionResult Test2() {
return View("ViewModelTest",new ViewModel() {
model = new Item() {
id = "1"
, name = "name"
}
, OtherField="bubba"});
}
[HttpPost]
public ActionResult Test2(ViewModel vm, string oldVal, string newval) {
return View(new Item() {
id = vm.model.id + "oo"
, name = vm.model.name + "000"
});
//pointless code to allow me to put in a break point
}
@using(Html.BeginForm()){
@Model.CapsName<br />
@Html.EditorFor(m => m.model.id)
@Html.EditorFor(m => m.model.name)
@Html.EditorFor(m=>m.OtherField)
}
jQuery(function () {
var data = {
"oldVal": 'old'
, "newVal": 'new'
};
RefreshScreenPassData("/Home/Test2",
$.param(data) + "&"
+ $("form").serialize());
});
function RefreshScreenPassData(ControllerURL, data) {
alert(data);
$.ajax({
url: ControllerURL,
type: 'POST',
data: data,
success: function (response) {
alert(response);
},
error: AjaxError
});
}
oldVal=old&newVal=new&model.id=1&model.name=name&OtherField=bubba