C#MVC Post模型和来自js

时间:2015-12-18 19:17:49

标签: javascript c# jquery asp.net asp.net-mvc

我正在使用我正在创建的自定义工作流解决方案。我想创建一个包含模型的回发,以及两个表示我已完成的操作和步骤的整数值。我不想将它们添加到模型中,因为它们仅用于这一个地方。这个回发的签名就是这样的。

[HttpPost]
public void ProcessWorkflowAction(EditScreenModelValidation model, int stepActionId, int stepNumber)
{
    //Some work on model and actions
}

我真的想通过JS这样做,因为目前我正在获得StepActionId和StepId。有没有办法打包模型通过JS发送?

 var modelObj = CreateModelData();
 var postObj = JSON.stringify(modelObj);
 $.ajax({
        type: "POST",
        traditional: true,
        dataType: "json",
        url: "url",
        data: { model: modelObj, stepActionId: stepId, stepNumber: 3 }
        cache: false,
        complete: function (data) {
        }});

CreateModelData = function () {
    var modelObj = {};
    var modelArray = $('#frm').serializeArray()
    $.each(modelArray, function (index, value) {
        assign(modelObj, value.name, value.value);
    })

    return modelObj;
};

function assign(obj, prop, value) {
    if (prop != undefined) {
        if (typeof prop === "string")
            prop = prop.split(".");

        if (prop.length > 1) {
            var e = prop.shift();
            assign(obj[e] =
                     Object.prototype.toString.call(obj[e]) === "[object Object]"
                     ? obj[e]
                     : {},
                   prop,
                   value);
        } else
            obj[prop[0]] = value;
    }
}

模型在控制器中返回null。我也尝试了以下代码,结果相同。

$.ajax({
        type: "POST",
        traditional: true,
        dataType: "json",
        url: "url",
        data: { model: $('#frm').serializeArray(), stepActionId: stepId, stepNumber: 3 }
        cache: false,
        complete: function (data) {
        }});

5 个答案:

答案 0 :(得分:3)

您需要构建对象,分配属性(确保它匹配任何模型验证并且字段名称与您的模型相同)并使用JSON.stringify进行转换:

 var modelObj = {};
 modelObj.prop1 = $('#txtField1').val();
 modelObj.prop2 = $('#txtField2').val();
 // etc... make sure the properties of this model match EditScreenModelValidation

 var postObj = JSON.stringify(modelObj); // convert object to json

 $.ajax({
    type: "POST",
    traditional: true,
    dataType: "json",
    url: "/Workflow/Home/ProcessWorkflowAction",
    data: { model: postObj, stepActionId: stepId, stepNumber: 3 }
    cache: false,
    complete: function (data) {
        if (data.responseText.length > 0) {
            var values = $.parseJSON(data.responseText)
            $('#ActionErrors').html(values.message)
        }
        else {
            location.reload();
        }
    }});

答案 1 :(得分:0)

这可能并且非常容易。 MVC非常适合打包发送它的内容。

因此,如果您的模型如下:

public class TestModel
{
    public string Name { get; set; }
    public int Age { get; set; }
}

你的帖子方法如下:

[HttpPost]
public void TestMethod(TestModel model, int num1, int num2)
{
    // Stuff
}

您的javascript POST看起来像:

function doPost(){
    $.post("/Home/TestMethod",
    {
        model: {
            Name: "Joe",
            Age: 29
        },
        num1 : 5,
        num2 : 10
     },
     function (data, status) {
         //Handle status if you decide to return something
     });
}

希望有所帮助!

答案 2 :(得分:0)

获取模型中所有字段的最快速最简单的方法是序列化与Model绑定的Form。

更新

您在属性中收到null的问题是因为serializeArray()创建键值格式json。你只需要将json从key值重建为可以映射到模型的Property值。

var modelObj = $('#formId').serializeArray()
                           .reduce(function (a, x) { a[x.name] = x.value; return a; }, {});

在你的ajax调用中进行一些调整,而不是datatype使用contentType。这是您在控制器的模型对象参数中获取null的另一个原因。

         $.ajax({
            type: "post",
            url: "/Account/RegisterSome",
            data: { model: modelobj, id: 3 },
            contentType: 'application/json',
            cache: false,
            complete: function (data) {
            }
        });

答案 3 :(得分:0)

所以这就是我如何让它发挥作用。 CreateModelData使用(frm).serializeArray()方法,但我发现如果项目在页面上被禁用或没有,那么它就没有创建该属性。

    var modelObj = CreateModelData();

    var postObj = JSON.stringify(modelObj);

    $.ajax({
        type: "POST",
        traditional: true,
        dataType: "json",
        url: "url",
        data: { modelString: postObj, stepActionId: stepId, stepNumber: 3 },
        cache: false,
        complete: function (data) {
        }});
});

CreateModelData = function () {
    var modelObj = {};
    var modelArray = $('#frm').serializeArray();
    $.each(modelArray, function (index, value) {
        assign(modelObj, value.name, value.value);
    })

    return modelObj;
};

function assign(obj, prop, value) {
    if (prop != undefined) {
        if (typeof prop === "string")
            prop = prop.split(".");

        if (prop.length > 1) {
            var e = prop.shift();
            assign(obj[e] =
                     Object.prototype.toString.call(obj[e]) === "[object Object]"
                     ? obj[e]
                     : {},
                   prop,
                   value);
        } else
            obj[prop[0]] = value;
    }
}

在控制器端,我将签名更改为所有字符串值,如此。

[HttpPost]
public void ProcessWorkflow(string modelString, int stepActionId, int stepNumber)
{
}

为了使modelString值成为实际的模型对象,我做了这个。

using (Stream s = GenerateStreamFromString(json))
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(modelObj));
    return (modelObj)serializer.ReadObject(s);
}

最后,这对我有用。所有的领域都在那里,我没有错误。当我试图让控制器方法中的第一个变量成为模型对象时,无论我做什么,它总是对我无效。

答案 4 :(得分:0)

我通过删除JSON.stringify()并仅发布了我的JavaScript对象解决了该问题。