Javascript AJAX发送到控制器未正确设置VIewModel参数

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;

当一个字段通过AJAX更改时,我试图将参数发布到控制器操作,但找到的第一个参数总是空的

我试图发布到的控制器操作是:

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