wootscootinboogie
wootscootinboogie

Reputation: 8695

Pass JavaScript array to server-side function with jQuery

I want to do the following steps:

  1. Take a list of check box values and make them into a string array in JavaScript.
  2. Take the array and send it to a server-side function.
  3. Take the array server side and make it into DataTable.
  4. Take the DataTable and send it as a TVP to a stored procedure.

I've gotten this to work from server-side on. Where I have trouble is going from JavaScript to server.

With my current code, I get this error:

There are not enough fields in the Structured type. Structured types must have at least one field.

How can I pass the JavaScript array to a web method?

<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</form>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Web.Script.Services;
using System.Web.Services;


    namespace SendTVP
    {
        public partial class _default : System.Web.UI.Page
        {
            //page variables
            string filterList = string.Empty;
            DataTable dt = new DataTable();
            protected void Page_Load(object sender, EventArgs e)
            {

            }
            protected void Button1_Click(object sender, EventArgs e)
            {

                string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
                using (var con = new SqlConnection(cs))
                {
                    using (var cmd = new SqlCommand("spFilterPatientsByRace",con))
                    {
                        con.Open();
                        cmd.CommandType = CommandType.StoredProcedure;
                        SqlParameter param = new SqlParameter();
                        //required for passing a table valued parameter
                        param.SqlDbType = SqlDbType.Structured;
                        param.ParameterName = "@Races";
                        //adding the DataTable
                        param.Value = dt;
                        cmd.Parameters.Add(param);
                        GridView1.DataSource = cmd.ExecuteReader();
                        GridView1.DataBind();
                    }                
                }
            }
            [ScriptMethod]
            [WebMethod]
            //this method will take JS array as a parameter and turn it into a DataTable

            public void TableFilter(string filterList)
            {
                DataTable filter = new DataTable();
                filter.Columns.Add(new DataColumn() { ColumnName = "Races" });
                dt.Columns.Add(new DataColumn() { ColumnName = "Races" });
                foreach (string s in filterList.Split(','))
                {
                    filter.Rows.Add(s);
                }
                dt = filter;
            }
        }

}

If this is a complete asinine way to do it, revisions are more than welcome :)

Upvotes: 0

Views: 1214

Answers (2)

Heretic Monkey
Heretic Monkey

Reputation: 12113

The problem here is that you have two methods on your web form which require a post back cycle.

  • When you call the WebMethod, it will create an instance of the _default class and set the dt variable, but do nothing with it.
  • When you call Button1_Click, a new instance of the _default class is created, so the dt variable is set to new DataTable();. Thus, your parameter has no columns or other data.

You'll want to do your processing of the DataTable in one method, presumably the TableFilter method.

Upvotes: 1

welegan
welegan

Reputation: 3043

I would suggest using JSON, which is a subset of javascript, to represent the data you are passing. An example of JSON would be:

[ "string1", "string2" ]

or

{ "property1": "a", "property2": "b" }

Where the first is a valid javascript array and the second is a valid javascript object when passed directly to the browser in a <script> tag. JQuery has various methods for dealing with JSON and you can look at JSON.NET or ServiceStack.Text on the .NET side for deserializing JSON into a C# object.

[Edit]

Though I should point out that it is difficult to get JSON deserialized into a C# DataTable because DataTable has a lot of properties that you would not necessarily need on the client. Your best bet would be to deserialize to a List<T> and iterating through that list adding to the DataTable rows as needed.

Upvotes: 0

Related Questions