You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

核心问题分析

  1. XML包裹JSON导致格式错误:ASP.NET传统ASMX WebService默认以XML格式返回数据,GetAll方法返回的JSON字符串被自动包裹在XML的<string>节点中,导致客户端拿到的不是纯JSON,反序列化时遇到开头的<字符直接报错。
  2. 序列化/反序列化类型不匹配:数据访问类中序列化的是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:32:16