如何编写C# ASP.NET Core WebAPI返回SqlDataReader数据供React下拉框使用?
ASP.NET Core WebAPI 单行产品数据接口优化实现
针对你的需求,先梳理现有代码存在的问题,再给出最佳实现方案:
现有代码的问题
- 方法名重复(两个
GetProductInfo),易造成逻辑混淆 - 手动拼接字典再序列化JSON,后续维护成本高,且存在双重序列化问题(返回
JsonResult时会再次序列化已转成字符串的JSON) - 未使用
using语句管理数据库资源,容易导致连接泄漏 - 参数名错误:
intProduct_ID应为Product_ID - 需求是返回单行数据,但用
List<object>包装,返回结果为数组,不符合前端下拉框的使用需求
最佳实现方案
1. 定义强类型数据模型
对应数据库返回的prodid、prodname、proddescr字段,创建强类型类:
public class ProductInfo { public int prodid { get; set; } public string prodname { get; set; } public string proddescr { get; set; } }
2. 优化后的WebAPI控制器代码
[HttpGet("{productId}")] public IActionResult GetProductInfo(int productId) { var product = GetSingleProductInfo(productId); return product != null ? Ok(product) : NotFound(); } private ProductInfo GetSingleProductInfo(int productId) { // using语句自动释放数据库连接、命令、阅读器资源 using (var connection = new SqlConnection(_connectionString)) using (var command = new SqlCommand("usp_GetProdInfo", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@Product_ID", SqlDbType.Int) { Value = productId }); connection.Open(); using (var reader = command.ExecuteReader()) { // 读取单行数据,符合需求 if (reader.Read()) { return new ProductInfo { prodid = reader.GetInt32(reader.GetOrdinal("prodid")), prodname = reader.GetString(reader.GetOrdinal("prodname")), // 处理可能为null的字段,避免DBNull异常 proddescr = reader.IsDBNull(reader.GetOrdinal("proddescr")) ? null : reader.GetString(reader.GetOrdinal("proddescr")) }; } return null; } } }
3. React下拉框数据获取示例
import { useState, useEffect } from 'react'; function ProductSelect({ targetProductId }) { const [product, setProduct] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { if (!targetProductId) return; const fetchProduct = async () => { setLoading(true); setError(null); try { const response = await fetch(`/api/your-controller-path/${targetProductId}`); if (!response.ok) throw new Error('获取产品信息失败'); const data = await response.json(); setProduct(data); } catch (err) { setError(err.message); } finally { setLoading(false); } }; fetchProduct(); }, [targetProductId]); if (loading) return <select disabled><option>加载中...</option></select>; if (error) return <select disabled><option>{error}</option></select>; return ( <select> {product ? ( <option value={product.prodid}> {product.prodname} - {product.proddescr || '无描述'} </option> ) : ( <option value="">请选择产品</option> )} </select> ); } export default ProductSelect;
优化说明
- 强类型模型:让数据结构更清晰,避免弱类型字典的潜在问题,同时便于前端对接
- 资源自动管理:
using语句确保数据库资源在使用后自动释放,杜绝连接泄漏 - RESTful规范:返回
Ok(200)或NotFound(404)状态码,前端可根据状态码做对应处理 - 单行数据读取:直接使用
reader.Read()获取单行数据,无需循环,符合需求 - 空值处理:对可能为
DBNull的字段做判断,避免运行时异常
内容的提问来源于stack exchange,提问作者TestUser
相关产品推荐
相关产品推荐

