【问题标题】:How to return Json object from MVC controller to view如何从 MVC 控制器返回 Json 对象以查看
【发布时间】:2013-03-04 07:23:48
【问题描述】:

我正在做一个 MVC 应用程序,我需要将 json 对象从控制器传递到视图。

var dictionary = listLocation.ToDictionary(x => x.label, x => x.value);
return Json(new { values = listLocation}, JsonRequestBehavior.AllowGet);

上面的代码我在我的控制器中使用,现在当我部署视图页面时,它会在我的浏览器中打开一个下载对话框,当打开文件时,它会根据我需要的格式给我 json 对象。

现在我想返回我的视图页面也想访问视图页面中的 json 对象。我该怎么做。

【问题讨论】:

    标签: asp.net-mvc json


    【解决方案1】:

    当您执行return Json(...) 时,您是在明确告诉 MVC 不要使用视图,并提供序列化的 JSON 数据。您的浏览器会打开一个下载对话框,因为它不知道如何处理这些数据。

    如果您想返回视图,只需像往常一样执行return View(...)

    var dictionary = listLocation.ToDictionary(x => x.label, x => x.value);
    return View(new { Values = listLocation });
    

    然后在您的视图中,只需将您的数据编码为 JSON 并将其分配给 JavaScript 变量:

    <script>
        var values = @Html.Raw(Json.Encode(Model.Values));
    </script>
    

    编辑

    这里有一个更完整的示例。由于我没有从您那里获得足够的上下文,因此此示例将假定一个控制器 Foo、一个动作 Bar 和一个视图模型 FooBarModel。此外,位置列表是硬编码的:

    Controllers/FooController.cs

    public class FooController : Controller
    {
        public ActionResult Bar()
        {
            var locations = new[]
            {
                new SelectListItem { Value = "US", Text = "United States" },
                new SelectListItem { Value = "CA", Text = "Canada" },
                new SelectListItem { Value = "MX", Text = "Mexico" },
            };
    
            var model = new FooBarModel
            {
                Locations = locations,
            };
    
            return View(model);
        }
    }
    

    模型/FooBarModel.cs

    public class FooBarModel
    {
        public IEnumerable<SelectListItem> Locations { get; set; }
    }
    

    Views/Foo/Bar.cshtml

    @model MyApp.Models.FooBarModel
    
    <script>
        var locations = @Html.Raw(Json.Encode(Model.Locations));
    </script>
    

    从您的错误消息看来,您似乎在混合不兼容的类型(即Ported_LI.Models.Locatio‌​nMyApp.Models.Location),因此,回顾一下,确保从控制器操作端发送的类型与从控制器接收到的类型相匹配看法。特别是对于这个示例,控制器中的new FooBarModel 与视图中的@model MyApp.Models.FooBarModel 匹配。

    【讨论】:

    • 嗨,丹尼尔,当我使用上面的代码时,我的视图页面出现以下错误。 “传入字典的模型项的类型为'f__AnonymousType31[System.Collections.Generic.List1[Ported_LI.Models.Location]]',但此字典需要'MyApp.Models.Location'类型的模型项”。请进一步帮助。
    • 正是我想要的。执行 Json 编码的是视图,这似乎很奇怪。我认为控制器将/应该具有此功能。你的例子非常有用。
    • @IAbstract 如果你真的想要,你可以将Json.Encode 放在控制器中。我个人不会这样做,因为(1)你的控制器逻辑很简单; (2) 规范表示为您提供了更多的灵活性。例如,您可以迭代集合、执行条件(即if (Model.Locations.Any()) { ... })等);如果在你的控制器中编码,你的视图基本上被一个字符串卡住了; (3) 我认为控制器不应该对本质上是一个演示问题负责(即,您认为是 JavaScript 决定了对 JSON 的需求)。干杯。
    • @DanielLiuzzi:很公平。我的观点并不完全是纯粹主义的观点 ;) ...我承认 convention 并尊重它。由于服务器实际上是在将对象编码为 json 并且视图会很快变得混乱,因此我一直在考虑一个专用对象,它可以在控制器本身之外将模型编码为 json。但这暂时不在考虑范围之内。根据我们不断增长的需求,它可能是稍后出现的静态实用程序。干杯。
    • 在 MVC 6(也可能是 6)中,您需要使用 Json.Serialize 而不是 Encode
    【解决方案2】:

    您可以使用 AJAX 调用此控制器操作。例如,如果您使用 jQuery,您可能会使用 $.ajax() 方法:

    <script type="text/javascript">
        $.ajax({
            url: '@Url.Action("NameOfYourAction")',
            type: 'GET',
            cache: false,
            success: function(result) {
                // you could use the result.values dictionary here
            }
        });
    </script>
    

    【讨论】:

    • 嗨达林,我试过你的方法在访问查看页面时仍然给出下载对话框。
    【解决方案3】:
    <script type="text/javascript">
    jQuery(function () {
        var container = jQuery("\#content");
        jQuery(container)
         .kendoGrid({
             selectable: "single row",
             dataSource: new kendo.data.DataSource({
                 transport: {
                     read: {
                         url: "@Url.Action("GetMsgDetails", "OutMessage")" + "?msgId=" + msgId,
                         dataType: "json",
                     },
                 },
                 batch: true,
             }),
             editable: "popup",
             columns: [
                { field: "Id", title: "Id", width: 250, hidden: true },
                { field: "Data", title: "Message Body", width: 100 },
               { field: "mobile", title: "Mobile Number", width: 100 },
             ]
         });
    });
    

    【讨论】:

    • Json 返回 Html 数据。如何在视图中渲染这个 json 结果。
    【解决方案4】:
    $.ajax({
        dataType: "json",
        type: "POST",
        url: "/Home/AutocompleteID",
        data: data,
        success: function (data) {
            $('#search').html('');
            $('#search').append(data[0].Scheme_Code);
            $('#search').append(data[0].Scheme_Name);
        }
    });
    

    【讨论】:

    • 请说明您的代码的作用以及它如何回答问题。如果您得到一个代码 sn-p 作为答案,您可能不知道如何处理它。答案应该为 OP 和未来的访问者提供有关如何调试和解决问题的指导。指出您的代码背后的想法是什么,对理解问题以及应用或修改您的解决方案有很大帮助。
    • @Palec 虽然我同意你的解释并相信这会使 sn-p 成为更好的答案,但实际上 10K+ 和 100K+ 的回答者一直都在给出 sn-ps 并且无需问题。因此,除非改变管理理念,否则这个答案是合法的。
    • @demongolem 我在 VLQ 审核队列中遇到了这个,发表了评论并进行了编辑;不建议删除。我看到we agreed 事实上,code-sn-p 的答案是可以的。我只是想就如何让它们变得更好提供指导。
    • 是我将其标记为“不是答案”,因为它令人困惑(在 sn-p 中从复制/粘贴的任何地方剩余的代码都是无用的),没有解释,并且可能已经就像在$.ajax 上带有指向 jQuery 页面的链接的评论一样容易。我认为这不足以成为一个实际的答案。我认为代码 sn-p-only 答案在相关且不言自明时很好,但我认为这不符合该要求。
    • 我确实尝试了追加(将行添加到表中)但没有成功。 -su
    猜你喜欢
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多