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

如何编写C# ASP.NET Core WebAPI返回SqlDataReader数据供React下拉框使用?

ASP.NET Core WebAPI 单行产品数据接口优化实现

针对你的需求,先梳理现有代码存在的问题,再给出最佳实现方案:

现有代码的问题

  1. 方法名重复(两个GetProductInfo),易造成逻辑混淆
  2. 手动拼接字典再序列化JSON,后续维护成本高,且存在双重序列化问题(返回JsonResult时会再次序列化已转成字符串的JSON)
  3. 未使用using语句管理数据库资源,容易导致连接泄漏
  4. 参数名错误:intProduct_ID应为Product_ID
  5. 需求是返回单行数据,但用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:33:30