将字典作为参数传递给ASP.NET MVC控制器

21
我想通过Ajax post将一个类型为<int,int>的字典传递给我的控制器。 主要原因是该post可能包含1-3个键值对(这些值在编译时都不知道),未来可能会增加到5个。
此外,在post中,我还需要传入一些其他数据,例如Id和name,所有这些都像平常一样工作。
那么我该如何在javascript中构造这个字典,然后通过JQuery post发送它,并最终在控制器上接收它以进行处理?
编辑2: 我已经决定只通过每个值进行post来解决这个问题,而不是尝试传递一个字典。
编辑: 这是我函数的源代码,以便您可以看到我正在尝试什么:
function BindAddMenuItem() {
        $(".AddMenuItem").click(function (e) {
            e.preventDefault();

            //get header id from link by removing addmenuitem from this.id
            var currentId = $(this).attr("id").replace("AddMenuItem", "");

            //get itemnumber, itemname, itemdetails from textboxes with same header id
            var restaurantId = jQuery.trim($("#RestaurantId").val());
            var itemNumber = jQuery.trim($("#ItemNumber" + currentId).val());
            var itemName = jQuery.trim($("#ItemName" + currentId).val());
            var itemDetails = jQuery.trim($("#ItemDetails" + currentId).val());

            var costs = new Object();
            //select all textboxes with class "Header" + currentId
            $(".Header" + currentId).each(function (i) {
                var optionId = $(this).attr("id").replace("Option", "");
                costs[optionId] = $(this).val();
            });


            $.ajax(
            {
                type: "POST",
                url: "/Menu/AddMenuItem",
                data: "reastaurantId=" + restaurantId + "&menuHeaderId=" + currentId + "&itemNumber=" + itemNumber + "&itemName=" + itemName + "&itemDetails=" + itemDetails + "&costs=" + costs,
                dataType: "html",
                success: function (result) {
                    var domElement = $(result);
                    $("#MenuContainer").replaceWith(domElement);
                    var newNum = parseInt(itemNumber) + 1;
                    $("#ItemNumber" + currentId).val(newNum);
                    BindAllBehaviours();
                }
            });
        });

    }
6个回答

28

类似于(JavaScript)的东西

dict = new Object();
dict['12'] = 5;
dict['13'] = 6;
dict['1000'] = 21;
dict['9'] = 13;
dict['13'] = 48;

$.post('/client.mvc/mypostaction/', { myDictionary: dict });
你可以使用 Dictionary<int, int> 作为属性类型将 dict 对象发布到你的控制器中。
ActionResult MyPostAction(Dictionary<string, int> myDictionary)

作者第二次编辑代码:

以下是我在拥有一个Dictionary<string, int>时可以工作的代码。最终,<int, int>不会起作用。

按照以下方式发布您的帖子:

var dict = new Object();
dict['13'] = 9;
dict['14'] = 10;
dict['2'] = 5;

$.post('controller.mvc/Test', { 'kvPairs': dict }, function(obj) { $('#output').html(obj.Count); }); 

当我按照你的建议传递字典时,我得到了一个空对象。我已经更新了我的问题以展示我的源代码。谢谢。 - ddd
我已经尝试了将字典作为字符串、整数和字符串、字符串。我已将帖子更改为您列出的方式,但仍然没有显示任何值。感谢迄今为止的帮助。我真的不知道还有什么其他方法可以让它工作。 - ddd
检查一下我的修改。你是否用 ' 把字典项包围起来了? - Jan Jongboom
@JanJongboom,对我也没用,它找不到该方法。 - Tito

19

当需要使用 Dictionary<TKey, TValue> 时,JavaScript 对象/字典必须作为键值对列表传递给 ASP.NET MVC 控制器。例如:

如果你有这样一个字典:

public Dictionary<string, decimal?> SomeMapping { get; set; }

然后在 JavaScript 中你需要使用类似于这样的代码:

var sourceMapping = { a: 1, b: 1.5, c: null };
var SomeMapping = [];
for (var key in sourceMapping) {
    if (sourceMapping.hasOwnProperty(key)) {
        SomeMapping.push({ Key: key, Value: sourceMapping[key] });
    }
}

我在使用jQuery发送异步POST请求时,采用了这种方法,并将内容类型设置为'application/json'(这在您的情况下可能重要,也可能不重要)。


我尝试了所有方法,但只有你的解决方案有效。所以给你加1。 - Deb

1

客户端(JavaScript):

var dict = new Object();
dict.Key1 = "Value1"
dict.Key2 = "Value2"

$.post('/YourController/YourAction/', dict);

注意:在发送到您的操作之前,“dict”对象会在后台进行序列化。

服务器:

public ActionResult YourAction()
{
    string postData = string.Empty;
    using (StreamReader sr = new StreamReader(Request.InputStream))
    {
        postData = sr.ReadToEnd();
    }    

    //Load post data into JObject (Newtonsoft.Json)
    JObject o = JObject.Parse(postData);

    //Extract each key/val 
    string val1 = (string)o["Key1"];

    //Do whatever....
}

你能写下这个 GET 请求吗?我想在 Chrome 的 PostMan 插件中测试它,所以我需要将我的参数传递给字典参数。 - Vincent Ducroquet

0

关于传递字典,我找到了以下可行的答案: 将字典提交给ASP.NET MVC操作

@model WebApplication3.Controllers.ExampleViewModel @{ ViewBag.Title = "New";
var first = Guid.NewGuid(); var second = Guid.NewGuid(); }

<h2>New</h2>

@using (Html.BeginForm(new { action = "create", controller = "home" })) {
foreach (var kvp in Model.Values) {
<p>
  <input type="text" name="Model.Values[@first].Key" value="@kvp.Key" />
  <input type="text" name="Model.Values[@first].Value" value="@kvp.Value" />
  <input type="hidden" name="Model.Values.Index" value="@first" />
</p>
}

你需要为字典索引生成 GUID,并创建三个输入,一个用于键,一个用于值,另一个用于字典的索引。

此外,我使用以下 Jquery 进行了提交:

$('form#frmFormId').submit(function (e) {
        e.preventDefault();
        var formData = new FormData(this);
        //debugger;
        $('#cover-spin').show(100);
        $.ajax({
            type: 'POST',
            url: $(this).attr('action'),
            data: formData,
            processData: false,
            contentType: false            
        }
        );
        return false;
    });

0

类似 IDictionary<string, string> 的字典可以在 JavaScript 中进行提交

{"Key1": "Value1", "Key2": "Value2"}

在ASP.NET Web API的服务器端

[HttpPost]
public IHttpActionResult([FromBody]IDictionary<string, string> requestParam){
}

以上示例针对在请求体中具有 Json 数据的 Http POST 请求。

0

除了mczers,这些都对我没有用,但他没有展示所有步骤,在你试图记住如何设置ajax请求时会让事情变得困难。所以我想把所有真正有效的东西都放在一起。首先,在JavaScript中:

        var validDict = new Array();
        validDict[0] = { key: 1, value: 4 }
        validDict[1] = { key: 42, value: 5}


var path = "@Url.Action("ControllerName", "ActionName")";
        $.ajax({
            url: path,
            type: "POST",
            data: JSON.stringify(validDict),
            contentType: "application/json; charset=utf-8",
            async:false,
            success: function(status, xhr)
            {

                alert(status);
              
            },
            error: function(xhr, status, error)
            {
                alert(error);
               

            }});

然后在你的控制器中:

        [HttpPost]
        public ActionResult ActionName(Dictionary<int, int> validDict)
        {
        // doStuff();
        return Content("Success");
        }

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