ASP.NET Core Web API无法显示DataTable的问题求助
代码示例
控制器代码
[Route("api/[controller]")] [ApiController] public class MapDataTableDemo : ControllerBase { Product p; public MapDataTableDemo() { p = new Product(); } [HttpGet] public async Task<IActionResult> MapDataTable() { var response = p.GetDataTable(); return Ok(response); } }
Product模型类代码
public class Product { public DataTable dataTable { get; set; } public DataTable GetDataTable() { this.dataTable = new DataTable(); this.dataTable.Columns.Add("product name"); this.dataTable.Columns.Add("product price"); this.dataTable.Rows.Add("mobile", 20000); this.dataTable.Rows.Add("tv", 15000); this.dataTable.Rows.Add("washing machine", 30000); return this.dataTable; } }
报错信息
System.NotSupportedException: Serialization and deserialization of 'System.Type' instances are not supported. Path: $.Columns.DataType.
System.NotSupportedException: Serialization and deserialization of 'System.Type' instances are not supported.
at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter
1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) at System.Text.Json.Serialization.JsonConverter1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)at System.Text.Json.Serialization.Metadata.JsonPropertyInfo
1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)at System.Text.Json.Serialization.JsonConverter
1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter1.TryWriteAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)at System.Text.Json.Serialization.JsonConverter
1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.Converters.IEnumerableConverter1.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
解决办法
方法1:将DataTable转换为匿名对象列表(推荐)
直接把DataTable的行数据转换成前端易处理的匿名对象集合,避开DataTable本身的复杂结构:
[HttpGet] public IActionResult MapDataTable() { var dt = p.GetDataTable(); var result = dt.AsEnumerable() .Select(row => new { ProductName = row["product name"].ToString(), ProductPrice = Convert.ToDecimal(row["product price"]) }) .ToList(); return Ok(result); }
方法2:自定义Json转换器处理DataTable
创建转换器只序列化行数据和列名,忽略无法序列化的属性:
- 定义转换器类:
public class DataTableConverter : JsonConverter<DataTable> { public override DataTable Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { throw new NotImplementedException(); // 无需反序列化可留空 } public override void Write(Utf8JsonWriter writer, DataTable value, JsonSerializerOptions options) { writer.WriteStartArray(); foreach (DataRow row in value.Rows) { writer.WriteStartObject(); foreach (DataColumn col in value.Columns) { writer.WritePropertyName(col.ColumnName); JsonSerializer.Serialize(writer, row[col], options); } writer.WriteEndObject(); } writer.WriteEndArray(); } }
- 在Program.cs注册转换器:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new DataTableConverter()); });
方法3:改用Newtonsoft.Json替代System.Text.Json
Newtonsoft.Json对DataTable序列化支持更完善:
- 安装NuGet包:
Microsoft.AspNetCore.Mvc.NewtonsoftJson - 在Program.cs配置:
builder.Services.AddControllers() .AddNewtonsoftJson();
配置完成后原代码可直接返回DataTable。
内容的提问来源于stack exchange,提问作者Aman

