我有一个正在运行的WCF-WPF应用程序,但我正在寻找一些优化。下面是我的代码,其中WCF restful服务公开了一个JSON数组,WPF UI接收它时没有任何问题。
WCF:
public clsStatus[] GetAllStatus()
{
DataTable dt = new DataTable();
List<clsStatus> lstGetAllStatus = new List<clsStatus>();
try
{
dt = // My Data Table
foreach (DataRow dr in dt.Rows)
{
dcStatus objGetAllStatus = new clsStatus();
objGetAllStatus.Id = Convert.ToInt32(dr["Id"]);
objGetAllStatus.Status = dr["Status"].ToString();
lstGetAllStatus.Add(objGetAllStatus);
}
}
return lstGetAllStatus.ToArray();
}
在WPF UI中:
public ObservableCollection<T> InvokeGet<T>(string sUrl)
{
System.Net.WebRequest request = System.Net.HttpWebRequest.Create(sUrl);
request.Method = "GET";
request.UseDefaultCredentials = true;
request.ContentLength = 0;
System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;
Stream objResponseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(objResponseStream);
string objResponseString = reader.ReadToEnd();
response.Close();
JavaScriptSerializer objJsonserialiser = new JavaScriptSerializer();
objJsonserialiser.MaxJsonLength = 999999999;
T[] arrResult = objJsonserialiser.Deserialize<T[]>(objResponseString);
return new ObservableCollection<T>(arrResult);
}
这样序列化/反序列化就可以正常工作,而当我进行下面所示的更改时,反序列化就不再工作了:
在WCF中:
public string[] GetAllStatus()
{
DataTable dt = new DataTable();
try
{
dt = // My Data Table
string jsonresp = JsonConvert.SerializeObject(dt, Formatting.None);
}
return jsonresp;
}
在WPF:
public ObservableCollection<T> InvokeGet<T>(string sUrl )
{
System.Net.WebRequest request = System.Net.HttpWebRequest.Create(sUrl);
request.Method = "GET";
request.UseDefaultCredentials = true;
request.ContentLength = 0;
System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;
Stream objResponseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(objResponseStream);
string objResponseString = reader.ReadToEnd();
response.Close();
dsReportRequests dsrepreq = new dsReportRequests();
//This conversion is failing with error
dsrepreq = JsonConvert.DeserializeObject<dsReportRequests>(objResponseString);
}
错误:"Error converting value "[{"Id":11280,"statName}]" to type 'clsStat[]'. Path '', line 1, position 759."
我发现更改后的代码中的JSON格式包含转义字符(),这似乎是在反序列化时导致错误的原因。
您的JSON正在进行双重序列化。(JSON中额外的反斜杠就是这方面的症状。)
请注意,在第一个版本中,您不会在GetAllStatus()
中调用来序列化返回对象,但在InvokeGet()
中,您会调用来反序列化它。因此,GetAllStatus的返回对象必须自动序列化。应该清楚的是,WCF必须为您处理返回对象的序列化。
在第二个版本中,使用JsonConvert.SerializeObject()
手动序列化GetAllStatus()
中的返回对象。由于我们刚刚确定WCF也在进行序列化,因此您最终会得到双重序列化的JSON。
为了使它发挥作用,您需要确保输出只序列化一次。大概你有理由开始在你的服务中使用Json.Net,所以我想找一种方法用Json.Net取代WCF序列化程序。你不必看得太远——在StackOverflow上有很多问题和答案都涉及这个主题。以下是一些想法:
- 用NewtonsoftJson.Net Json序列化程序替换WCF内置的JavascriptSerializer(简介:编写一个自定义消息格式化程序并配置WCF使用它)
- 将WCF 4中的默认JSON序列化程序替换为JSON.NET(简介:手动序列化为流并完全绕过WCF的序列化)
- 带有JSON.Net的WCF RESTful web服务:避免双重序列化(简介:使用web API而不是WCF,因为默认情况下它已经使用JSON.Net)