3

我正在尝试将字典传递给 Html.Post 中的操作方法

Html.BeginForm("ProcessStage2", "Supplier", new {bookVars = Model.BookVars} , FormMethod.Post, new { name = "frmBook" })

我可以传递模型的其他属性(int、string、...),但不能传递 Dictionary。有没有机会实现这一目标?因为字典有 29 对,似乎太多了,无法拆分并将它们分开传递。

4

4 回答 4

3

序列化您的字典并将其作为字符串传递(可能是 base64 编码)。

于 2012-05-09T10:01:04.863 回答
3

您可以使用隐藏字段和编辑器模板。举个例子:

模型:

public class MyViewModel
{
    public IDictionary<string, string> BookVars { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            // fill the dictionary with some dummy data
            BookVars = Enumerable
                .Range(1, 5)
                .ToDictionary(x => "key" + x, x => "value" + x)
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        // the model.BookVars property will be properly bound here
        return View(model);
    }
}

查看 ( ~/Views/Home/Index.cshtml):

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.BookVars)
    <button type="submit">OK</button>
}

编辑器模板(~/Views/Home/EditorTemplates/KeyValuePair`2.cshtml):

@model KeyValuePair<string, string>

@Html.Hidden("Key", Model.Key)
@Html.Hidden("Value", Model.Value)

注意将为字典的每个元素自动呈现的编辑器模板的名称:KeyValuePair`2.cshtml

抱歉,我无法使用 SO 的编辑器正确格式化,但文件名应该是:重音字符KeyValuePair[grave accent]2.cshtml在哪里。[grave accent]

另外不要忘记阅读默认模型绑定器希望更好地了解幕后发生的事情的集合和字典的有线格式。

于 2012-05-09T09:58:02.487 回答
2

不,您不能将对象作为参数传递。唯一的方法是将对象存储在数据库中并仅传递该对象的 POST id。您应该创建包含该字典的模型:

public int id {get;set;}
public Dictionary<string, int> Dictionary {get;set};

并从服务器端通过 id 加载它。

于 2012-05-09T09:49:40.677 回答
0

您可以使用例如 json 序列化来做到这一点。我推荐这个,因为它非常灵活并且看起来很优雅。

您的模型可以包含任何对象集。在您的情况下,它是:

public class MyViewModel
{
    public IDictionary<string, string> BookVars { get; set; }
}

在控制器中,您可以根据我们的需要存根一些数据:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // mock data
        var model = new MyViewModel
                            {BookVars = new Dictionary<string, string> {{"key1", "value1"}, {"key2", "value2"}}};

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        // the binded model is avaliable
        return View(model);
    }
}

该视图包含一个表单,并包含一个用于 ajax 提交的自定义脚本。这些值可以以任何方式持久化和修改。例如,您可以使用隐藏字段。

@model MyViewModel

<script src="/Scripts/script.js" type="text/javascript"></script>

<script type="text/javascript">
        $(document).ready(function () {
            $('form').frmBookSubmit();
        });
</script>

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { name = "frmBook" }))
{
    <div class="books">
        @foreach (var item in Model.BookVars)
        {
            <input type="hidden" key="@item.Key" value="@item.Value" />        
        }
    </div>
    <input type="submit" />
}

Script.js,使用数据的 json 序列化为 ajax 提交创建一个简单的 jquery 插件:

(function ($) {

    $.fn.frmBookSubmit = function () {
        var $this = $(this);
        if ($this != null && $this != 'undefined' && $this.length > 0) {
            $this.submit(function (e) {
                e.preventDefault();

                var myviewmodel = new Object();
                myviewmodel.BookVars = $this.find(".books").booksCollect();
                var data = { model: myviewmodel };
                var jsonString = JSON.stringify(data);

                $.ajax({
                    url: $this.attr("action"),
                    type: 'POST',
                    dataType: 'json',
                    data: jsonString,
                    contentType: 'application/json; charset=utf-8'
                });

            });
        }
    };

    $.fn.booksCollect = function () {
        var books = new Array();
        $(this).find("input").each(function () {
            var k = $(this).attr('key');
            var v = $(this).attr('value');
            var item = {
                Key: k,
                Value: v
            };
            books.push(item);
        });
        return books;
    };

})(jQuery);

如果您觉得它有用,您还可以使用例如 Newtonsoft.Json 库编写您的自定义 json binder。

你完成了。

于 2012-05-09T11:35:14.403 回答