50

I have a datatable that I'm converting into a List, serializing it and passing it to my view using a viewmodel.

My viewmodel looks like this:

public class AddressModel
{
    public string Addresses { get; set; }
}

My controller action looks like the following:

AddressModel lAddressGeocodeModel = new AddressGeocodeModel();
List<string[]> lAddresses = new List<string[]>();

string lSQL = " select Address1, CityName, StateCode, ZipCode " +
                      " from AddressTable  ";

// Convert the data to a List to be serialized into a Javascript array.
//{
...data retrieval code goes here...
//}
foreach (DataRow row in AddressTable.Rows)
{
    string[] lAddress = new string[5];
    lAddress[1] = row["Address1"].ToString();
    lAddress[2] = row["CityName"].ToString();
    lAddress[3] = row["StateCode"].ToString();
    lAddress[4] = row["ZipCode"].ToString();
    lAddresses.Add(lAddress);
}

lAddressGeocodeModel.UnitCount = lAddresses.Count().ToString();
// Here I'm using the Newtonsoft JSON library to serialize my List
lAddressGeocodeModel.Addresses = JsonConvert.SerializeObject(lAddresses);

return View(lAddressModel);

Then in my view I get the following string of addresses:

[["123 Street St.","City","CA","12345"],["456 Street St.","City","UT","12345"],["789 Street St.","City","OR","12345"]]

How am I supposed to get this serialized string residing in a razor model into a javascript array?

bynary
  • 841
  • 2
  • 11
  • 26

10 Answers10

63

You could directly inject the values into JavaScript:

//View.cshtml
<script type="text/javascript">
    var arrayOfArrays = JSON.parse('@Html.Raw(Model.Addresses)');
</script>

See JSON.parse, Html.Raw

Alternatively you can get the values via Ajax:

public ActionResult GetValues()
{
    // logic
    // Edit you don't need to serialize it just return the object

    return Json(new { Addresses: lAddressGeocodeModel });
}

<script type="text/javascript">
$(function() {
    $.ajax({
        type: 'POST',
        url: '@Url.Action("GetValues")',
        success: function(result) {
            // do something with result
        }
    });
});
</script>

See jQuery.ajax

Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92
  • 34
    I think you need to encode the model to Json: `@Html.Raw(Json.Encode(Model.Addresses))` – Nate-Wilkins Aug 27 '13 at 16:30
  • When I check the string at the controller it's like this: [[\"123 Street St.\",\"City\",\"CA\",\"12345\"],...] which is a proper JSON string. When I print the string out to the console in Chrome it looks like this: [["123 Street St.","City","CA","12345"],...] When I re-encode it using Json.Encode and then try to parse it with JSON.parse (like this - JSON.parse('@Html.Raw(Json.Encode(Model.Addresses))'); I get the following error in the console: "Uncaught SyntaxError: Unexpected number" – bynary Aug 27 '13 at 16:47
  • I think I'm going to try a different approach and do a proper JsonResult controller action that returns a Json() C# object. I'm not sure why I'm having so much trouble with Javascript and Razor syntax, but it's just not working. – bynary Aug 27 '13 at 16:48
  • View the source of the page and see what's getting printed. – Dustin Kingen Aug 27 '13 at 16:52
  • 1
    When you can print string on CSHTML, you dont need to do JSON.parse, you can simply assign JSON string to variable. JSON is a valid JavaScript Object anyway. – Akash Kava Aug 27 '13 at 17:41
  • 9
    For those showing up now (2019) the correct way to inject a c# array into javascript is as simple as `var data = @Json.Serialize(Model.Tags)` where tags is a `List` – barnacle.m Mar 14 '19 at 23:40
41

Many way to Json Parse but i have found most effective way to

 @model  List<string[]>

     <script>

         function DataParse() {
             var model = '@Html.Raw(Json.Encode(Model))';
             var data = JSON.parse(model);  

            for (i = 0; i < data.length; i++) {
            ......
             }
         }
     </script>
Mehul Bhalala
  • 780
  • 7
  • 16
  • 3
    I have no idea why this wasn't the answer – BoundForGlory May 17 '16 at 13:46
  • 3
    Because it was posted three years after the question was originally asked. – bynary Jul 29 '17 at 16:08
  • By the way, is missing a closing curly bracket after the for (). – Leo Sep 29 '17 at 11:39
  • And because here the model object is a `List` but in the question it is a comma-separated string. However, I would directly send the list to the view and let the view handle that by doing what Mehul posted, but just in one line. – Andrew Aug 08 '18 at 14:58
22

This worked for me in ASP.NET Core MVC.

<script type="text/javascript">
    var ar = @Html.Raw(Json.Serialize(Model.Addresses));
</script>
John81
  • 3,726
  • 6
  • 38
  • 58
18

Many of these answers do work, but I have found the easiest way by far is to send data through ViewData or ViewBag and let JSON.Net serialize it.

I use this technique when Javascript is needed for HTML generation before the page load or when AJAX overhead needs to be avoided:

In the controller:

public ActionResult MyController()
{
    var addresses = myAddressesGetter();
    ViewData["addresses"] = addresses ;
    return View();
}

In the view:

@section scripts {
<script type="text/javascript">
    var MyjavascriptAddresses: @Html.Raw(JsonConvert.SerializeObject(ViewData["addresses"])),
</script>
}

You can always rely on JSON.NET whereas some browsers have poor JSON deserialization support. Another benefit over some methods in that you can see the Javascript using your browser's View --> Source, since it is simply text generated server-side.

Note that In most situations, Web API a more elegant way to get JSON to the client.

Charles Burns
  • 10,310
  • 7
  • 64
  • 81
6

For those trying to do it without using JSON, the following is how I did it:

<script>
    var originalLabels = [ '@Html.Raw(string.Join("', '", Model.labels))'];
</script>
Hashim Akhtar
  • 813
  • 2
  • 11
  • 16
4

I would say it's more a problem of the way you're modeling your data. Instead of using string arrays for addresses, it would be much cleaner and easier to do something like this:

Create a class to represent your addresses, like this:

public class Address
{
    public string Address1 { get; set; }
    public string CityName { get; set; }
    public string StateCode { get; set; }
    public string ZipCode { get; set; }
}

Then in your view model, you can populate those addresses like this:

public class ViewModel
{
    public IList<Address> Addresses = new List<Address>();

    public void PopulateAddresses()
    {
        foreach(DataRow row in AddressTable.Rows)
        {
            Address address = new Address
                {
                    Address1 = row["Address1"].ToString(),
                    CityName = row["CityName"].ToString(),
                    StateCode = row["StateCode"].ToString(),
                    ZipCode = row["ZipCode"].ToString()
                };
            Addresses.Add(address);
        }

        lAddressGeocodeModel.Addresses = JsonConvert.SerializeObject(Addresses);
    }
}

Which will give you JSON that looks like this:

[{"Address1" : "123 Easy Street", "CityName": "New York", "StateCode": "NY", "ZipCode": "12345"}]
Jedediah
  • 1,916
  • 16
  • 32
  • I'm sure you're right. The only problem is that my original code works GREAT in non-MVC ASP.NET. There was no problem until I tried to implement the same solution in MVC. I'm going to stick with my "new" solution of using $.getJSON() to get the result of a JsonResult action. If that doesn't work, I'll be looking at your solution much closer. Thanks! – bynary Aug 27 '13 at 17:08
1

Here's how you accomplish that:

//View.cshtml
<script type="text/javascript">
    var arrayOfArrays = JSON.parse('@Html.Raw(Json.Encode(Model.Addresses))');
</script>
Jules Dupont
  • 7,259
  • 7
  • 39
  • 39
Ahmed Elbendary
  • 379
  • 5
  • 7
1

For one dimension array

Controller:

using Newtonsoft.Json;
var listOfIds = _dbContext.Countries.Where(x => x.Id == Country.USA).First().Cities.Where(x => x.IsCoveredByCompany).Select(x => x.Id).ToList();
string strArrayForJS = JsonConvert.SerializeObject(listOfIds); //  [1,2,6,7,8,18,25,61,129]
//Now pass it to the view through the model or ViewBag 

View:

<script>
    $(function () {
        var myArray = @HTML.Raw(Model.strArrayForJS);
        console.log(myArray); // [1, 2, 6, 7, 8, 18, 25, 61, 129]
        console.log(typeof (myArray)); //object
    });
</script>
Adel Mourad
  • 1,351
  • 16
  • 13
0

JSON is valid JavaScript Object anyway, while you are printing JavaScript itself, you don't need to encode/decode JSON further once it is converted to JSON.

<script type="text/javascript">
    var addresses = @Html.Raw(Model.Addresses);
</script>

Following will be printed, and it is valid JavaScript Expression.

<script type="text/javascript">
    var addresses = [["123 Street St.","City","CA","12345"],["456 Street St.","City","UT","12345"],["789 Street St.","City","OR","12345"]];
</script>
Akash Kava
  • 39,066
  • 20
  • 121
  • 167
0

You can directly use the Json.Serialize of the C#

<script type="text/javascript">
    var addresses = @Json.Serialize(Model.Addresses);
</script>
Emil Rowland
  • 538
  • 5
  • 25