使用AJAX将JavaScript对象数组发送到数据库
本文关键字:数据库 数组 对象 AJAX JavaScript 使用 | 更新日期: 2023-09-27 18:30:13
在这个项目中,用户将有机会创建一个具有属性的对象数组,这些属性与数据库表匹配,对象的属性与数据库电缆中的列相同。SQL看起来像:
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
在这里,我创建了一个自定义类型,并以表值参数的形式将该自定义类型传递给存储过程。SQL和以下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();
}
}
}
您可以看到,在这个工作示例中,我没有使用任何AJAX调用将数据发送到web方法。这段代码目前可以工作,并插入硬编码列表中的数据。因此,当我更改代码以实际尝试使用JavaScript数组时,如下所示:
$(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);
}
});
});
});
新的C#
[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();
}
}
}
目前,该代码给了我错误:Type'u0027System.String'u0027isnotsupportedfordeserializationofanarray
如果我不把数组包装在DTO对象中,但仍然字符串化,我就会得到
`System.Collections.Generic.IDictionary`2[[System.String,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken`
我不想为此使用ViewState的SessionState。既然我知道如果我不将JavaScript数组传递给WebMethod,代码会很好地工作,那么它一定是在数组的序列化和反序列化中的某个地方破坏了它。我该如何解决这个问题?这已经让我抓狂好几天了
请注意以下步骤,然后更改代码行。
- 不要创建
sd1={}
和sd2{}
- 在顶部创建
var list = [];
,然后推送类似list.push({"ServiceId":1,"ServiceDescription":"test"}, {"ServiceId":2,"ServiceDescription":"other test"})
的json对象 - 创建类似
var data = "{'sdLists':" +JSON.stringify(list)+"}";
的ajax参数,并将日期作为param传递 -
创建一个带有变量的bean来映射上面列表中添加的json对象。请参阅blow。
公共类SdList{private int Serviceid;public int Serviceid{获取{return Serviceid;}设置{Serviceid=value;}}私有字符串ServiceDescription;公共字符串ServiceDescription{获取{return ServiceDescription;}设置{ServiceDescription=value;}}}
-
现在将
List<SdList> sdLists
作为参数列表传递给下的方法var data="{'sLists':"+JSON.stringfy(list)+"}";public void InsertServiceData(List-sdLists)
-
然后使用java脚本序列化程序将中的Json List转换为泛型列表,如下所示,
JavaScriptSerializer jss= new JavaScriptSerializer();
List<SdList> list = jss.ConvertToType<List<SdList>>(sdLists);
我已经遵循了上述步骤,它运行良好。