使用json传递窗口小部件数据并保存到数据库

我刚刚回到这个要求,因为当时我被迫离开它以做更重要的要求。

我在这里问了一个类似的问题,答案有所帮助。 但是,在那个问题中,我传递了测试数据并将其保存到数据库中。 但是,我无法弄清楚如何保存实际的小部件信息。 该链接帮助我成功传递了json。

我在尝试保存数据时收到此消息。 在此处输入图像描述

jQuery的

function updateWidgetData() { var items = []; $('.column').each(function () { var columnId = $(this).attr('id'); $('.dragbox', this).each(function (i) { var collapsed = 0; if ($(this).find('.dragbox-content').css('display') == "none") collapsed = 1; //Create Item object for current panel var item = { id: $(this).attr('id'), collapsed: collapsed, order: i, column: columnId }; //Push item object into items array items.push(item); }); }); //Assign items array to sortorder JSON variable var sortorder = { items: items }; $.ajax({ url: "/Handlers/SaveWidgets.ashx", type: "POST", contentType: "application/json; charset=uft-8", dataType: "json", data: JSON.stringify(sortorder), success: function (response) { alert("Passed json"); }, error: function (error) { alert("Failed passing json."); } }); 

处理器

  public void ProcessRequest(HttpContext context) { String json = String.Empty; // you have sent JSON to the server // read it into a string via the input stream using (StreamReader rd = new StreamReader(context.Request.InputStream)) { json = rd.ReadToEnd(); } // create an instance of YourDataModel from the // json sent to this handler SaveWidgetsDAL data = null; DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(SaveWidgetsDAL)); using (MemoryStream ms = new MemoryStream()) { byte[] utf8Bytes = Encoding.UTF8.GetBytes(json); ms.Write(utf8Bytes, 0, utf8Bytes.Length); ms.Position = 0; data = serializer.ReadObject(ms) as SaveWidgetsDAL; } // update the DB and // send back a JSON response int rowsUpdated = 0; foreach (var item in data.wdata) { using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["dboCao"].ConnectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand("UPDATE tWidgetControl SET SortNo = @SortNo, ColumnId = @ColumnId, Collapsed = @Collapsed " + "WHERE UserId = @UserId AND WidgetId = @WidgetId;", conn)) { cmd.Parameters.AddWithValue("@SortNo", item.SortNo); cmd.Parameters.AddWithValue("@ColumnId", item.ColumnId); cmd.Parameters.AddWithValue("@Collapsed", item.Collapsed); cmd.Parameters.AddWithValue("@UserId", "2"); cmd.Parameters.AddWithValue("@WidgetId", item.WidgetId); rowsUpdated = cmd.ExecuteNonQuery(); } conn.Close(); } } context.Response.ContentType = "application/json"; context.Response.Write("{ \"rows_updated\": " + rowsUpdated + " }"); } public bool IsReusable { get { return false; } } 

小部件数据类

 public class SaveWidgetsDAL { public List wdata { get; set; } public SaveWidgetsDAL() { } public class Widgets { [DataMember] public string SortNo { get; set; } [DataMember] public string ColumnId { get; set; } [DataMember] public string Collapsed { get; set; } [DataMember] public string Title { get; set; } [DataMember] public string UserId { get; set; } [DataMember] public string WidgetId { get; set; } } } 

我想我需要将json保存到列表中,然后将每个窗口小部件信息插入/更新到数据库中。 但是,当我尝试这个时,我收到上面的错误。 我显然遗漏了一些东西,但我不确定它是什么。 我的处理程序中发生此错误,但SaveWidgetsDAL中的列表为空,从而导致NullReference。 我不确定我错过了什么或确定从哪里开始。 任何帮助是极大的赞赏!

编辑1:

我和SaveWidgetsDAL一起改变了我的数据库。

SaveWidgetsDAL

 [DataContract] public class SaveWidgetsDAL { [DataMember(Name = "items")] public List wdata { get; set; } public SaveWidgetsDAL() { } public class Widgets { [DataMember(Name = "order")] public string SortNo { get; set; } [DataMember(Name = "column")] public string ColumnId { get; set; } [DataMember(Name = "collapsed")] public string Collapsed { get; set; } [DataMember(Name = "id")] public string Title { get; set; } } } 

处理程序(只是foreach)

 foreach (var item in data.wdata) { using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["dboCao"].ConnectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand("UPDATE tWidgetTest SET Title = @Title, SortNo = @SortNo, ColumnId = @ColumnId, Collapsed = @Collapsed " + "WHERE UserId = @UserId AND Title = @Title;", conn)) { cmd.Parameters.AddWithValue("@Title", item.Title); cmd.Parameters.AddWithValue("@SortNo", item.SortNo); cmd.Parameters.AddWithValue("@ColumnId", item.ColumnId); cmd.Parameters.AddWithValue("@Collapsed", item.Collapsed); cmd.Parameters.AddWithValue("@UserId", "2"); rowsUpdated = cmd.ExecuteNonQuery(); } conn.Close(); } } 

但是,我现在在插入数据库时​​遇到此错误。 在此处输入图像描述

我能够看到我的foreach计数是11,但是Collapsed,SortNo,ColumnId,Title对于每个项目都是null。

问题似乎是c#数据协定中指定的数据成员名称与您生成的JSON中的JSON属性名称不匹配。 您的JavaScript代码生成的JSON看起来像

 {"items":[{"id":"1","collapsed":"False","order":"1","column":"1"}]} 

但是这些属性名称不是c#类中的属性名称,并且您没有覆盖这些名称。 尝试类似以下内容:

 [DataContract] public class SaveWidgetsDAL { [DataMember(Name="items")] public List wdata { get; set; } public SaveWidgetsDAL() { } [DataContract] public class Widgets { // I was able to figure out which JSON properties to which to map these properties. [DataMember(Name = "column")] public string ColumnId { get; set; } [DataMember(Name = "collapsed")] public string Collapsed { get; set; } // However it is unclear how to map these to your JSON. [DataMember(Name = "sortno")] public string SortNo { get; set; } [DataMember(Name = "title")] public string Title { get; set; } [DataMember(Name = "userid")] public string UserId { get; set; } [DataMember(Name = "widgetid")] public string WidgetId { get; set; } } } 

我能够推断出collapsed: collapsed的正确的c#数据成员名称collapsed: collapsedcolumn: columnId ,但我无法弄清楚如何映射其余的,因为它们似乎不匹配1-1。 您需要进一步修复数据成员名称以使它们完全匹配。

UPDATE2

在更新的问题中,您省略了嵌套Widgets类的[DataContract]属性:

  // [DataContract] missing public class Widgets { 

您需要确保外部类和嵌套类都具有此属性。

更新

这是创建JSON的代码的一部分:

  var collapsed = 0; if ($(this).find('.dragbox-content').css('display') == "none") collapsed = 1; //Create Item object for current panel var item = { id: $(this).attr('id'), collapsed: collapsed, order: i, column: columnId }; //Push item object into items array items.push(item); var json = JSON.stringify(sortorder); 

因此, items数组中的每个对象 item只包含这四个命名属性:

  • id
  • collapsed
  • order
  • column

您在var item = { id: value1, collapsed: value2, ...};使用的属性名称var item = { id: value1, collapsed: value2, ...}; statement是JSON.stringify()写入json字符串的名称。 c#代码中指定的数据成员名称必须与这些名称完全匹配 ,以便使用DataContractJsonSerializer对它们进行反序列化。 因此,以下c#类将反序列化这四个命名属性:

 [DataContract] public class SaveWidgetsDAL { [DataMember(Name = "items")] public List wdata { get; set; } public SaveWidgetsDAL() { } [DataContract] public class Widgets { // I was able to figure out which JSON properties to which to map these properties. [DataMember(Name = "id")] public string Id { get; set; } [DataMember(Name = "collapsed")] public string Collapsed { get; set; } [DataMember(Name = "order")] public string Order { get; set; } [DataMember(Name = "column")] public string ColumnId { get; set; } } } 

如果需要传输其他属性,则需要在var item语句中添加它们,然后在Widgets类中添加具有相同数据成员名称的属性。 要确认您已正确匹配名称,您可以使用Visual Studio调试ProcessRequest()方法并手动检查您的json字符串,或通过以下方式调试您的json字符串:

  System.Diagnostics.Debug.WriteLine(json); 

这将允许您查看JSON并确保您的数据成员名称与您的JSON属性名称匹配。