raranibar
raranibar

Reputation: 1267

asp.net mvc reading ViewBag generic list via javascript

I'm working with asp.net mvc4, How I can read data from ViewBag, my ViewBag is a Generic List, I would like to access the data (viewbag) from javascript.

I'm passing a generic list from the controller to the view, this list helps me to load a dropdownlist up here works well. Besides loading the dropdownlist I need to access some generic list data so that when the value of the dropdownlist to update a textbox with data from the list

Upvotes: 1

Views: 14141

Answers (5)

This answer is simple and Okay

<script type="text/javascript">
     var jsList= @Html.Raw(Json.Encode(@ViewBag.GenericList));
</script>

But default .Net Json.Encode has some problem and not friendly with javascript data type (example Datetime field will get format like /Date(1245398693390)/) so I recommend to use Newtonsoft.Json.JsonConvert

<script type="text/javascript">
     var jsList= @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(@ViewBag.GenericList));
</script>

Upvotes: 0

ecasper
ecasper

Reputation: 509

<script type="text/javascript">
     var jsList= @Html.Raw(Json.Encode(@ViewBag.GenericList));
</script>

Upvotes: 1

Andre Calil
Andre Calil

Reputation: 7692

DISCLAIMER

This is an extremely straightforward, simple and non-elegant solution. However, it works =)

Consider this class:

public class Something
{
    public int Id { get; set; }
    public string PropA { get; set; }
    public string PropB { get; set; }
}

And this code on your action:

List<Something> list = new List<Something>() { 
  new Something(){ Id = 1, PropA = "1-A", PropB = "1-B "}
  , new Something(){ Id = 2, PropA = "2-A", PropB = "2-B "}
};

ViewBag.Things = list;

Finally, the view:

<select id="theSelect">
    @foreach (Something item in ViewBag.Things)
    { 
        <option value="@item.Id">@item.PropA</option>
    }
</select>
<input type="text" id="selectedPropB" readonly />
<div style="display: none;">
    @foreach (Something item in ViewBag.Things)
    { 
        <span id="[email protected]">@item.PropB</span>
    }
</div>
<script type="text/javascript">
    $(function () {
        $('#theSelect').on('change', function () {
            var id = $(this).val();

            $('#selectedPropB').val($('#propb-'+id).html());
        });
    });
</script>

Notes:

  • I'd rather be using a viewmodel instead of the ViewBag, because reasons. Anyway, it's up to you
  • I'm sure you can find better solutions if you work with knockout and so on. Anyway, as I said, this works

Upvotes: 1

pfluggs11
pfluggs11

Reputation: 166

Technically you ViewBag is a dictionary that can contain a Generic List. It is only available when your page is initially rendered. Thus you can't access it directly from JavaScript. But what you can do is get the list from your ViewBag, serialize it as JSON in Razor and deserialize it in JavaScript.

public ActionResult Index(){
    //make this whatever list you want
    ViewBag.MyList = new ArrayList();
}

This sets a key in the ViewBag dictionary equal to a list of your choosing. Now, we need to serialize it so we can access it in JavaScript.

var jsonList = '@Html.Raw(Json.Convert(ViewBag.MyList))'
var jsList = JSON.parse(jsonList);

This is a lot of work to just get a list, not to mention, making dependencies in the View for Newtonsoft.Json or whatever serializer you use, and also if memory serves, it is not very efficient. Why not make a request to get the data you need from an API controller which will take care of the serialization for you, resulting in a faster initial page load?

Edit: I think what you're looking for is this. You don't need to use JavaScript to achieve what you are asking for. Leverage the power of MVC.

Upvotes: 3

GHP
GHP

Reputation: 3231

One of the easiest ways to pass data back and forth from your ASP.NET code to your JS layer, is to serialize your objects and then render the serialization into the View as a JS object. Here's an example:

// helper extension method
public static string ToJSON(this object o)
{
    var oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    return oSerializer.Serialize(o);
}

Inside your controller:

Viewbag.Foo = myObj.ToJSON();

Then, inside your View, you just spit out the serialized obj as literal JavaScript:

var json = @Html.Raw(Viewbag.Foo); // mix of Razor and JS here! 

When you run it, if you view source, you'll see something like this in that section of the View:

var json = {"prop1":true, "arrayItems":[{ "prop1": "dog" }, { "prop": "car" }]}

Upvotes: 1

Related Questions