ASP.NET C# WebService调用后反序列化DataTable失败求助
问题排查:ASP.NET WebService返回XML包裹JSON导致反序列化失败
问题概述
调用ASP.NET C# WebService访问SQL Server表时,反序列化步骤报错。相关代码如下:
客户端调用代码
HttpResponseMessage message2 = client.GetAsync("GetAll?Columns=*&Tbl=Coding_Sell").Result; string userJson2 = message2.Content.ReadAsStringAsync().Result; MessageBox.Show(userJson2); DataTable DT = JsonConvert.DeserializeObject<DataTable>(userJson2);
WebService方法
[WebMethod] public string GetAll(string Columns, string Tbl) { return ObjdBAccess.Get(Columns, Tbl); }
数据访问类代码
public string Get(string Columns, string TableName) { String query = "SELECT " + Columns + " From " + TableName; createConn(); SqlDataAdapter adapter = new SqlDataAdapter(query, connection); DataSet DS = new DataSet(); adapter.Fill(DS); DataTable DT = DS.Tables[0]; closeConn(); return JsonConvert.SerializeObject(DS); }
报错信息
Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
返回的userJson2内容
<?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">{"Table":[{"Main_Code":51,"Property_Name":"Sell","Sub_Code":"1"},{"Main_Code":52,"Property_Name":"Sell2","Sub_Code":"2"}]}</string>
核心问题分析
- XML包裹JSON导致格式错误:ASP.NET传统ASMX WebService默认以XML格式返回数据,
GetAll方法返回的JSON字符串被自动包裹在XML的<string>节点中,导致客户端拿到的不是纯JSON,反序列化时遇到开头的<字符直接报错。 - 序列化/反序列化类型不匹配:数据访问类中序列化的是
DataSet对象,对应的JSON结构是包含Table数组的DataSet格式,但客户端直接尝试反序列化为DataTable,类型不匹配。
修复方案
方案1:让WebService直接返回纯JSON(推荐)
修改WebMethod,跳过默认的XML包装,直接输出JSON内容:
[WebMethod] public void GetAll(string Columns, string Tbl) { // 设置响应内容类型为JSON HttpContext.Current.Response.ContentType = "application/json"; // 获取DataSet序列化后的JSON字符串 string jsonResult = ObjdBAccess.Get(Columns, Tbl); // 直接输出JSON到响应流 HttpContext.Current.Response.Write(jsonResult); }
客户端修改反序列化逻辑,先转成DataSet再取表:
HttpResponseMessage message2 = client.GetAsync("GetAll?Columns=*&Tbl=Coding_Sell").Result; string userJson2 = message2.Content.ReadAsStringAsync().Result; // 反序列化为DataSet后提取DataTable DataSet ds = JsonConvert.DeserializeObject<DataSet>(userJson2); DataTable DT = ds.Tables[0];
可选:客户端请求时明确指定接收JSON,添加请求头:
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
方案2:解析XML提取内部JSON后再反序列化
如果无法修改WebService代码,客户端先解析XML提取JSON内容:
HttpResponseMessage message2 = client.GetAsync("GetAll?Columns=*&Tbl=Coding_Sell").Result; string userJson2 = message2.Content.ReadAsStringAsync().Result; // 解析XML提取内部的JSON字符串 System.Xml.Linq.XDocument xmlDoc = System.Xml.Linq.XDocument.Parse(userJson2); System.Xml.Linq.XNamespace ns = "http://tempuri.org/"; string pureJson = xmlDoc.Element(ns + "string").Value; // 反序列化为DataSet后获取DataTable DataSet ds = JsonConvert.DeserializeObject<DataSet>(pureJson); DataTable DT = ds.Tables[0];
额外注意事项
你的Get方法存在SQL注入风险:直接拼接Columns和TableName到SQL语句中,恶意参数可能导致数据库被攻击。建议改用参数化查询,或提前限制允许访问的表名和列名范围。
内容的提问来源于stack exchange,提问作者user12235025
相关产品推荐
相关产品推荐

