Quantcast
Channel: ASP.NET AJAX + Ajax Control Toolkit (ACT)
Viewing all articles
Browse latest Browse all 5678

JavaScript array of objects to DataTable, then saved to database using jQuery.

$
0
0

Hopefully I can get some help here, because this has been gnawing at me for days.  I would like to allow the user to create an array of objects in JavaScript (these objects match classes already defined in C# in name and properties).  The array of JS objects will then be used to make a DataTable.  That DataTable is then passed to a stored procedure which stores it to a database.  The following SQL is what I used to create my custom type and stored procedure.  The C# that directly follows that is an illustration that the WebMethod works and the SQL works: 

create table ServiceData
(ServiceId int
,ServiceDescription varchar(50)
)
go
create type ServiceType as table
(ServiceId int
,ServiceDescription varchar(50)
)
go
create proc spInsertService
@service ServiceType readonly
as
begin
    insert into ServiceData(ServiceId,ServiceDescription)
    select * from @service
end

C#

[WebMethod]
        public void InsertServiceData()
        {
            List<ServiceData> sdList = new List<ServiceData>();
            ServiceData sd1 = new ServiceData(1, "first");
            ServiceData sd2 = new ServiceData(2, "second");
            sdList.Add(sd1);
            sdList.Add(sd2);
            DataTable dt = new DataTable();
            dt.Columns.Add("ServiceId");
            dt.Columns.Add("ServiceDescription");
            foreach (var data in sdList)
            {
                dt.Rows.Add(data.ServiceId, data.ServiceDescription);
            }
            string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
            using (var con = new SqlConnection(cs))
            {
                using (var cmd = new SqlCommand("spInsertService",con))
                {
                    con.Open();
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@service", dt);
                    cmd.ExecuteNonQuery();
                }
            }
        }

As long as I'm creating the list of objects in the code behind this works fine.  Since I would like for the user to create these objects and I don't want to use ViewState or SessionState I tried something like this: JS and then the new C#

$(document).ready(function ()
        {
            sd1 = {};
            sd1.ServiceId = 1;
            sd1.ServiceDescription = "test";

            sd2 = {};
            sd2.ServiceId = 2;
            sd2.ServiceDescription = "other test";
            //create array which is meant to mirror the List<ServiceData> in the 
            //earlier example
            service = new Array();
            service.push(sd1);
            service.push(sd2);
            //wrap the array in a data transfer object
            var dto = {'sdList': service};$('#btnSubmit').click(function ()
            {$.ajax(
                {
                    type: "POST",
                    url: "WebService.asmx/InsertServiceData",
                    contentType: "application/json",
                    dataType: "json",
                    //stringify the dto
                    data: JSON.stringify(dto),
                    success: function(data)
                    {
                        console.log('success');
                    },
                    error: function(thrownError)
                    {
                        console.log(thrownError);
                    }
                });
            });
        });
[WebMethod]
        //this attempts to deserialize the DTO into a list of ServiceData objects
        //which are then inserted into the TVP and then to the database

        public void InsertServiceData(string sdList)
        {
            var jss = new JavaScriptSerializer();
            List<ServiceData> list = jss.Deserialize<List<ServiceData>>(sdList);
            DataTable dt = new DataTable();
            dt.Columns.Add("ServiceId");
            dt.Columns.Add("ServiceDescription");
            foreach (var data in list)
            {
                dt.Rows.Add(data.ServiceId, data.ServiceDescription);
            }
            string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
            using (var con = new SqlConnection(cs))
            {
                using (var cmd = new SqlCommand("spInsertService",con))
                {
                    con.Open();
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@service", dt);
                    cmd.ExecuteNonQuery();
                }
            }
        }

That code gives me the error: System.String is not supported for deserialization of an array.  If I don't wrap the array in a data transfer object I get the error: 

System.Collections.Generic.IDictionary`2[[System.String,mscorlib,Version=4.0.0.0

If I just try to send the array directly I get an error Invalid JSON primitive.  I know that if this isn't directly possible, there's got to be some way other than making an AJAX call for each item in the array.  I've been stuck on this for days now, how can I get this AJAX data parameter to be accepted by the web method?





Viewing all articles
Browse latest Browse all 5678

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>