0

I am trying to pass an IList back to my View where it can be accessible in a jQuery .each(), but I'm not having any success.

Example class:

public class MyClass
{
    private string _Name = "";
    public int Id = null;

    public MyClass ( string Name, int Id = null )
    {
       ... Do something ...
    }

    public string Name 
    { 
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
        }
    }
}

In Controller:

IList<MyClass> myClass = null;
myClass = GetNames();

ViewDataDictionary viewData = new ViewDataDictionary(null);
viewData.Add("myNames", Json(myClass));

// The string writer where to render the HTML code of the view
StringWriter stringWriter = new StringWriter();

// Render the Index view in a HTML string
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext,
    "GeneratePDF", null);

ViewContext viewContext = new ViewContext(
    ControllerContext,
    viewResult.View,
    viewData,
    new TempDataDictionary(),
    stringWriter
    );
viewResult.View.Render(viewContext, stringWriter);

... Omitted for brevity ...

In the View I would like to use jQuery to iterate through ViewData["myNames"]:

<script type="text/javascript">

    _myNames = '@ViewData["myNames"]';

    $.each(_myNames, function (i, item) {
        ...
    });

</script>

The above doesn't work and unfortunately I'm not sure how to debug it because the view is being called by EvoPDF PDF Generator.

I've also tried this in my View:

<input type="hidden" id="myNames" value="@ViewData["myNames"]" />

<script type="text/javascript">

    _myNames = $('#myNames').val();

    $.each(_myNames, function (i, item) {

    });

</script>

Tracing through the controller code (where EvoPDF renders the page) I can see that the hidden field is containing the Type Name in the value attribute - not the data.

I've used ViewData many times without problem, but this is a bit different usage than I'm familiar with. Can anyone tell me how to pass an IList/List/IENumerable using ViewData so that I can iterate through it with jQuery .each()?

EDIT

As an alternative, I could make a jQuery call from within my razor, but I'm not sure how to pass the variable to jQuery:

@foreach (var myName in (List<MyClass>)ViewData["myNames"])
{
    <tr>
    <td class="text-center">
        <script type="text/javascript">
            FormatName('@myName.Name', 1);
        </script>
    </td>
    </tr>
}

But myName.Name doesn't seem to being passed to the FormatName() function. I know for a fact that myName.Name contains a valid value because it renders fine without the jQuery. How do I pass that var to my jQuery function?

rwkiii
  • 5,716
  • 18
  • 65
  • 114
  • your requirement is some different either you can make ajax call and get the list or you have to make a custom helper for your purpose.. – Kartikeya Khosla Aug 16 '14 at 08:30
  • I can't find any documentation that confirms an Ajax call is even valid using this method. The example I whipped up above comes mainly from an EvoPDF sample code. I can successfully pass data using ViewData and iterate through it using `@foreach (var myName in (List)ViewData["myNames"])` and the output is fine. But I have several helper functions written in jQuery that help format the outputted data and I'm not sure how to use them in the razor C# code. What would a custom helper look like? – rwkiii Aug 16 '14 at 08:35
  • Actually, the reason I am not using Ajax is because there are input values that come from a different page. On the other page there is a button that can be clicked to generate the PDF, but it is an Ajax POST itself. It seems clutsy to pass those posted values (parameters) from View to Controller, then Controller to View again. Are you saying I cannot pass a Json of this class to my View using ViewData and access it using jQuery? – rwkiii Aug 16 '14 at 08:40
  • 1
    i m just saying that the way you are iterating viewdata in jquery is incorrect...just visit this..http://forums.asp.net/t/1758990.aspx?How+to+get+access+to+a+list+of+Models+in+jQuery+...i think custom helper will solve your problem.. – Kartikeya Khosla Aug 16 '14 at 08:42
  • @Exception, thank you for that nice link. I may go this route, although I am curious to know if you can comment on why `Json(myNames)` in the Controller doesn't satisfy serializing to Json for use in the View by jQuery? I thought that's what it was used for. I have other .each() routines that make use of Json() Lists after making an Ajax call - or is the problem with ViewData itself? – rwkiii Aug 16 '14 at 08:50
  • 1
    yes that is what i m saying that with ajax call getting list from controller and then you can do .each() and also if you have list in viewdata you can do foreach in c# code but doing .each() with viewdata list in jquery is not possible you are just mixing server side and client side code... – Kartikeya Khosla Aug 16 '14 at 08:57
  • @Exception, Got it. Thanks. I've made an edit to this post that would be a decent alternative, but not sure how to get it to work either. – rwkiii Aug 16 '14 at 09:36

3 Answers3

3

You first need to convert TempData property to a javascript array of objects. Oualid KTATA was on the right track with first suggestion, but that only returns a string. In you document ready function:

var _myNames = JSON.parse('@Html.Raw(Json.Encode(ViewData["myNames"]))');

which will return something like

[{ID:1, Name:"FirstName"}, {ID:2, Name:"SecondName"}, ...]

You can then access it with

$.each(_myNames, function(index, item) {
  var id = item.ID;
  var name = item.Name;
});
  • Perfect! Your first line resolved my issue. Thank you for this answer. I got things to work by iterating the object in razor but it was lengthy and ugly. This really cleans up my code and opens up my jQuery library to each data member. – rwkiii Aug 17 '14 at 06:18
  • Is there any way to debug this? I'm using jQuery v2.2.1, and it says, `Uncaught SyntaxError: Unexpected token @ in JSON at position 0 at JSON.parse()` –  Feb 18 '21 at 14:07
1
var UserName =@Html.Raw(Json.Encode(this.ViewData["UserName"]));

working fine

or

var UserName =JSON.parse('@Html.Raw(Json.Encode(this.ViewData["UserName"]))');

(less time consuming) or controller code:

this.ViewData["UserName"] = HttpUtility.HtmlEncode("somestring");

UI example:

var UserName ="Html.Raw(this.ViewData["UserName"])"  

or JUST

var UserName ="Html.Raw(this.ViewData["UserName"])"
0

Try to use this when you set the viewData object to your client side variable:

var _myNames= @Html.Raw(Json.Encode(ViewData["myNames"]));

OR

_myNames = '<%= ViewData["myNames"] %>'

Instead of:

_myNames = '@ViewData["myNames"]';
Oualid KTATA
  • 1,116
  • 10
  • 20