57

I have a datatable that I'm converting into a List<string[]>, 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?

0

11 Answers 11

67

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

    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

Sign up to request clarification or add additional context in comments.

6 Comments

I think you need to encode the model to Json: @Html.Raw(Json.Encode(Model.Addresses))
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: [[&quot;123 Street St.&quot;,&quot;City&quot;,&quot;CA&quot;,&quot;12345&quot;],...] 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"
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.
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.
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<string>
|
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>

1 Comment

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.
23

This worked for me in ASP.NET Core MVC.

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

1 Comment

Perfect. Using on ASP.NET Core 2.0.
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.

Comments

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>

Comments

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"}]

1 Comment

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!
1

Here's how you accomplish that:

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

Comments

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>

Comments

1

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

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

Comments

0

Simplest way is to convert data model to javascript object notation then markup without encoding.

    var addresses = @Html.Raw(Json.Encode(Model.Addresses));
    console.log(addresses);

Comments

-1

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>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.