向Web API发送JSON对象

22

我正在尝试找出如何将表单中的一些信息发送到Web API操作。这是我正在尝试使用的jQuery / AJAX:

var source = { 
        'ID': 0, 
        'ProductID': $('#ID').val(), 
        'PartNumber': $('#part-number').val(),
        'VendorID': $('#Vendors').val()
    }

    $.ajax({
        type: "POST",
        dataType: "json",
        url: "/api/PartSourceAPI/",
        data: JSON.stringify({ model: source }),
        success: function (data) {
            alert('success');
        },
        error: function (error) {
            jsonValue = jQuery.parseJSON(error.responseText);
            jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
        }
    });

这是我的模型

public class PartSourceModel
{
    public int ID { get; set; }
    public int ProductID { get; set; }
    public int VendorID { get; set; }
    public string PartNumber { get; set; }
}

这是我的观点

<div id="part-sources">
    @foreach (SmallHorse.ProductSource source in Model.Sources)
    {
        @source.ItemNumber <br />
    }
</div>
<label>Part Number</label>
<input type="text" id="part-number" name="part-number" />

<input type="submit" id="save-source" name="save-source" value="Add" />

这是我的控制器操作

// POST api/partsourceapi
public void Post(PartSourceModel model)
{
    // currently no values are being passed into model param
}

我错过了什么?目前在调试时,当ajax请求触发控制器操作时,没有任何内容传递到模型参数中。


你尝试过不用JSON.stringify吗?data: { model: source },或者可能只需要data : source - jQuery会为您处理转换... - nnnnnn
是的,我尝试过不用JSON.stringify,但那也不起作用。我已经在AJAX端尝试了我能想到的每种可能的组合,但我认为控制器上有些东西我漏掉了.. 不过我不确定,这只是一个猜测。 - Cory
当你说“没有什么”被传递到模型参数中时,你是指实例“model”为空吗?还是它的值为默认值/空值?如果您将模型类型更改为字符串以获取原始表示形式,或者甚至删除输入参数并直接探测Request.Content和Request.Headers属性以查找服务器正在接收什么,会发生什么? - Snixtor
4个回答

30
尝试这个:

jquery

    $('#save-source').click(function (e) {
        e.preventDefault();
        var source = {
            'ID': 0,
            //'ProductID': $('#ID').val(),
            'PartNumber': $('#part-number').val(),
            //'VendorID': $('#Vendors').val()
        }
        $.ajax({
            type: "POST",
            dataType: "json",
            url: "/api/PartSourceAPI",
            data: source,
            success: function (data) {
                alert(data);
            },
            error: function (error) {
                jsonValue = jQuery.parseJSON(error.responseText);
                //jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
            }
        });
    });

控制器

    public string Post(PartSourceModel model)
    {
        return model.PartNumber;
    }

查看

<label>Part Number</label>
<input type="text" id="part-number" name="part-number" />

<input type="submit" id="save-source" name="save-source" value="Add" />

现在,当你在文本框中填写完内容后,单击“Add”,控制器会在警报框中返还你在PartNumber框中写的内容。


1
谢谢!只需更改data:source,它就可以正确绑定到控制器中的“model”参数。我以为我必须在我的ajax中包含名称“model:”才能使其工作。非常感谢! - Cory
对于复杂的数据格式(无法默认反序列化),您需要在服务器端接收JSON字符串。您的答案可能适用于简单的数据,但对于复杂的数据则不起作用(这正是我正在寻找的哈哈)。不过,您的答案对于这位用户的问题很好! - Zwik
1
我发现在我的ajax调用中必须包含contentType:'application/json'。为什么这个答案不需要它呢? - V Maharajh

6

变更:

 data: JSON.stringify({ model: source })

To:

 data: {model: JSON.stringify(source)}

在控制器中,您需要这样做:
public void PartSourceAPI(string model)
{
       System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();

   var result = js.Deserialize<PartSourceModel>(model);
}

如果您在jquery中使用的url是/api/PartSourceAPI,则控制器名称必须为api,操作(方法)应该是PartSourceAPI

我尝试了这个,但不幸的是并没有产生任何影响。 - Cory

3
var model = JSON.stringify({ 
    'ID': 0, 
    'ProductID': $('#ID').val(), 
    'PartNumber': $('#part-number').val(),
    'VendorID': $('#Vendors').val()
})

$.ajax({
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    url: "/api/PartSourceAPI/",
    data: model,
    success: function (data) {
        alert('success');
    },
    error: function (error) {
        jsonValue = jQuery.parseJSON(error.responseText);
        jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
    }
});

var model = JSON.stringify({      'ID': 0,     ...': 5,      'PartNumber': 6,     'VendorID': 7 }) // output is "{"ID":0,"ProductID":5,"PartNumber":6,"VendorID":7}"

您的数据看起来像这样 "{"model": "ID":0,"ProductID":6,"PartNumber":7,"VendorID":8}}",但 Web API 控制器无法将其绑定到您的模型。


-4

我相信你需要在model周围加上引号:

JSON.stringify({ "model": source })

2
在对象字面量中,如果属性名是数字字面量或有效的标识符名称,则不需要将其用引号括起来。因此,{model:source} 是可以的。 - nnnnnn
你有没有使用浏览器的调试工具来检查请求体中发送给动作方法的内容? - Andy T
Queti,是的,我正在使用Fiddler,它显示请求中没有发送任何内容。 - Cory
我尝试使用引号并且像你一样精确地操作,但不幸的是没有任何区别。 - Cory
可能不加引号也能工作,但根据json.org的说法,这不是有效的语法。但我怀疑它不会引起任何麻烦,所以我想你是正确的。 - z00l
1
@z00l - 你只需要在JSON中使用引号,而这不是JSON。对象字面量和JSON并不是同一回事。 - nnnnnn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接