36

I am doing an MVC application where i need to pass json object from controller to view.

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

The above code i am using in my controller , now when i deploy the view page its opening a download dialog in my browser , when open the file it gives me json object as i needed format.

Now i want to return my view page also want to access the json object in the view page. how can i do that.

Karthik Chintala
  • 5,465
  • 5
  • 30
  • 60
Purushoth
  • 2,673
  • 3
  • 22
  • 36

4 Answers4

60

When you do return Json(...) you are specifically telling MVC not to use a view, and to serve serialized JSON data. Your browser opens a download dialog because it doesn't know what to do with this data.

If you instead want to return a view, just do return View(...) like you normally would:

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

Then in your view, simply encode your data as JSON and assign it to a JavaScript variable:

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

EDIT

Here is a bit more complete sample. Since I don't have enough context from you, this sample will assume a controller Foo, an action Bar, and a view model FooBarModel. Additionally, the list of locations is hardcoded:

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);
    }
}

Models/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>

By the looks of your error message, it seems like you are mixing incompatible types (i.e. Ported_LI.Models.Locatio‌​n and MyApp.Models.Location) so, to recap, make sure the type sent from the controller action side match what is received from the view. For this sample in particular, new FooBarModel in the controller matches @model MyApp.Models.FooBarModel in the view.

Daniel Liuzzi
  • 16,807
  • 8
  • 52
  • 57
  • Hi daniel, I got the following error in my view page ,when i used the above code. "The model item passed into the dictionary is of type '<>f__AnonymousType3`1[System.Collections.Generic.List`1[Ported_LI.Models.Location]]', but this dictionary requires a model item of type 'MyApp.Models.Location'". PLease help further. – Purushoth Mar 05 '13 at 06:44
  • 3
    Exactly what I was looking for. It seems odd that it is the view that does the Json encoding. I would think the Controller would/should have this function. Your example is extremely useful. – IAbstract Nov 10 '15 at 15:42
  • 1
    @IAbstract If you really wanted, you could put `Json.Encode` in the controller. Personally I wouldn't do it, because (1) you controller logic stays simple; (2) the canonical representation gives you more flexibility. For example, you can iterate the collection, do conditionals (i.e. `if (Model.Locations.Any()) { ... }`), etc.); if encode in your controller, your view is basically stuck with a string; and (3) I don't think the controller should be responsible for what's essentially a presentation concern (i.e. it is the JavaScript in your view what dictates the need for JSON). Cheers. – Daniel Liuzzi Nov 10 '15 at 18:12
  • @DanielLiuzzi: fair enough. Mine is not exactly a purist point of view ;) ... I recognize the *convention* and respect it. Since the server is actually encoding the object to json and views can get cluttered very quickly, I've been considering a dedicated object that encodes models to json outside of the Controllers themselves. But that is not on the plate for now. It may be a static utility that comes later depending on our growing requirements. Cheers. – IAbstract Nov 10 '15 at 18:22
  • In MVC 6 (maybe also 6) you need to use `Json.Serialize` instead of `Encode`. – KoalaBear Feb 20 '16 at 21:40
6

You could use AJAX to call this controller action. For example if you are using jQuery you might use the $.ajax() method:

<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>
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0
<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 },
         ]
     });
});

-2
$.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);
    }
});
Palec
  • 12,743
  • 8
  • 69
  • 138
  • 3
    Please include explanation of what your code does and how it answers the question. If you get a code snippet as an answer, you may not know what to do with it. Answer should give the OP and future visitors guidance on how to debug and fix their problem. Pointing out, what the idea behind your code is, greatly helps in understanding the issue and applying or modifying your solution. – Palec Jul 09 '14 at 14:25
  • @Palec While I agree with you in your explanation and believe that that would make the snippet a better answer, in practice 10K+ and 100K+ answerers give snippets all the time and that is accepted without question. This answer is therefore legitimate as the site stands now unless changes in governing philosophy are made. – demongolem Jul 09 '14 at 15:02
  • @demongolem I met this from VLQ review queue, posted the comment and edited; did not suggest deletion. I see [we agreed](https://stackoverflow.com/review/low-quality-posts/5258279) on the fact, that code-snippet answers are OK. I just like to give guidance on how to make them better. – Palec Jul 10 '14 at 02:11
  • 3
    It was me who flagged this as "not an answer" because it's confusing (the code leftover in the snippet from wherever it was copy/pasted is useless), not explained, and could've just as easily been a comment with a link to the jQuery page on `$.ajax`. I didn't think it was meaningful enough to be an actual answer. I would argue that code snippet-only answers are fine when they are relevant and self-explanatory, but I don't think this one fits that bill. – Cᴏʀʏ Jul 10 '14 at 13:30
  • I did try an append (of rows to a table) but without success. -su – Su Llewellyn Jun 05 '18 at 20:25