0

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

4

1 に答える 1

0

次の手順に注意して、コード行を変更してください。

  1. とを作成sd1={}しないでsd2{}ください。
  2. 一番上に作成var list = [];してから、次のようなjsonオブジェクトをプッシュしますlist.push({"ServiceId":1,"ServiceDescription":"test"}, {"ServiceId":2,"ServiceDescription":"other test"})
  3. のような ajax パラメータを作成var data = "{'sdLists':" +JSON.stringify(list)+"}";し、日付をパラメータとして渡します。
  4. 上記のリストに追加されたように、変数を使用して json オブジェクトをマップする Bean を作成します。打撃を参照してください。

    public class SdList{ private int Serviceid; public int Serviceid { get { return Serviceid; } 設定 { Serviceid= 値; } } プライベート文字列 ServiceDescription; public string ServiceDescription { get { return ServiceDescription; } 設定 { ServiceDescription= 値; } } }

  5. List<SdList> sdLists以下のように、パラメータリストとしてメソッドに渡します

    var data = "{'sdLists':"+JSON.stringify(list)+"}"; public void InsertServiceData(List sdLists)

  6. 次に、以下のように Java スクリプト シリアライザーを使用して、Json リストをジェネリック リストに変換します。 JavaScriptSerializer jss= new JavaScriptSerializer();

    List<SdList> list = jss.ConvertToType<List<SdList>>(sdLists);

上記の手順に従いましたが、正常に動作しています。

于 2013-11-27T06:30:10.377 に答える