我刚刚再次回到这个要求,因为当时我被迫离开它以做更重要的要求。
我问了一个类似的问题here,答案有所帮助。但是,在那个问题中,我传递了测试数据并将其保存到数据库中。但是,我无法弄清楚如何保存实际的小部件信息。该链接帮助我成功传递了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<Widgets> 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<Widgets> 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; }
}
}
Handler(只是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。
答案 0 :(得分:1)
问题似乎是c#数据协定中指定的data member names与您生成的JSON中的JSON属性名称不匹配。您的JavaScript代码生成的JSON看起来像
{"items":[{"id":"1","collapsed":"False","order":"1","column":"1"}]}
但是这些属性名称不是c#类中的属性名称,并且您没有覆盖这些名称。请尝试以下内容:
[DataContract]
public class SaveWidgetsDAL
{
[DataMember(Name="items")]
public List<Widgets> 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
和column: columnId
推断出正确的c#数据成员名称,但我无法弄清楚如何映射其余的,因为它们似乎不匹配1-1 。您需要进一步修复data member names以使其完全匹配。
<强> UPDATE2 强>
在更新的问题中,您省略了嵌套[DataContract]
类的Widgets
属性:
// [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);
因此,item
数组中的每个object items
只包含这四个命名属性:
id
collapsed
order
column
您在var item = { id: value1, collapsed: value2, ...};
语句中使用的属性名称是JSON.stringify()
写入json
字符串的名称。 c#code 中指定的数据成员名称必须与这些名称完全匹配,才能使用DataContractJsonSerializer
对其进行反序列化。因此,以下c#类将反序列化这四个命名属性:
[DataContract]
public class SaveWidgetsDAL
{
[DataMember(Name = "items")]
public List<Widgets> 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
字符串或debug log json
字符串:< / p>
System.Diagnostics.Debug.WriteLine(json);
这将允许您查看JSON并确保您的数据成员名称与您的JSON属性名称匹配。