このプロジェクトでは、ユーザーはプロパティを持つオブジェクトの配列を作成する機会があり、それらのプロパティはデータベース テーブルと一致し、オブジェクトのプロパティはデータベース ケーブルの列と同じになります。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();
}
}
}
この実際の例では、Web メソッドにデータを送信するために AJAX 呼び出しを使用していないことがわかります。このコードは現在機能しており、ハードコードされたリストからデータを正常に挿入します。したがって、実際に 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 に渡さない場合、コードが正常に機能することはわかっているため、配列のシリアライゼーションとデシリアライゼーションのどこかに問題があるはずです。どうすればこれを修正できますか? もう何日も頭がおかしくなってる