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

.NET 4.8 ASP.NET MVC项目中如何将用户输入订单号传入SQL Server存储过程实现扫描状态更新及错误处理

.NET 4.8 ASP.NET MVC项目中如何将用户输入订单号传入SQL Server存储过程实现扫描状态更新及错误处理

兄弟,我看了你这段代码和需求,确实新手容易踩这些坑,咱们一步步来把问题捋清楚、改好。首先你的存储过程本身在数据库能跑,但代码端完全没用到它,而且参数传递、方法设计都有不少问题,咱们一个个解决:


第一步:先修存储过程的小bug

你说存储过程能跑,但仔细看有几处语法和拼写问题,先把这些改了:

Use [testDB]
GO
SET ANSI_NULL ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[UpdateScanStatus]
@OrderNumber varchar(8)
AS
BEGIN
    SET NOCOUNT ON; -- 加上这个避免返回额外的行数消息,干扰逻辑

    IF EXISTS (SELECT 1 FROM Orders WHERE Order_Number = @OrderNumber)
    Begin
        DECLARE @ScanStatus BIT;
        SELECT @ScanStatus = Scan_Status -- 修正列名拼写:原代码写的ScanStatus,数据库列是Scan_Status
        FROM Orders
        WHERE Order_Number = @OrderNumber -- 修正参数名:原代码写的@Order_Number,存储过程参数是@OrderNumber

        IF @ScanStatus = 1
        BEGIN
            RAISERROR('Order is already scanned!', 16, 1); -- Severity用16更合适,23会强制断开数据库连接
        END
        ELSE
        BEGIN
            UPDATE Orders
            SET Scan_Status = 1
            WHERE Order_Number = @OrderNumber
            PRINT 'Successful!';
        END
    END
    ELSE
    BEGIN
        RAISERROR('Order does not exist!', 16, 1); -- 补上逗号:原代码少了逗号导致语法错误
    END
END;

第二步:重构Controller逻辑,真正调用存储过程

你之前的Controller写了static方法,而且完全没调用存储过程,而是自己写了UPDATE语句,还错误地把XML数据传给了订单号参数,这肯定跑不通。咱们改成标准的MVC Action,处理用户输入、调用存储过程、把结果返回给视图:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using System.Data;

namespace WebApplication1.Controllers
{
    public class ScanController : Controller
    {
        // 建议把连接字符串放到web.config里,这里暂时用你的配置
        private readonly string _connectionString = "Data Source=SBSQL;User ID=SpeedPass;Password=********;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False";

        // 显示订单号输入表单
        public IActionResult Index()
        {
            return View();
        }

        // 处理扫描提交的POST请求
        [HttpPost]
        public IActionResult SubmitScan(string orderNumber)
        {
            // 先校验用户输入
            if (string.IsNullOrWhiteSpace(orderNumber) || orderNumber.Length != 8)
            {
                ModelState.AddModelError("", "请输入有效的8位订单号");
                return View("Index");
            }

            try
            {
                using (SqlConnection connection = new SqlConnection(_connectionString))
                {
                    using (SqlCommand command = new SqlCommand("[dbo].[UpdateScanStatus]", connection))
                    {
                        // 关键:指定命令类型是存储过程
                        command.CommandType = CommandType.StoredProcedure;
                        // 添加存储过程需要的订单号参数
                        command.Parameters.Add("@OrderNumber", SqlDbType.VarChar, 8).Value = orderNumber.Trim();

                        connection.Open();
                        command.ExecuteNonQuery();

                        // 没有抛出异常就说明执行成功
                        ViewBag.SuccessMessage = "扫描成功!";
                    }
                }
            }
            catch (SqlException ex)
            {
                // 捕获存储过程抛出的错误信息
                string errorMsg = string.Empty;
                foreach (SqlError error in ex.Errors)
                {
                    errorMsg += error.Message + " ";
                }
                ModelState.AddModelError("", errorMsg.Trim());
                return View("Index");
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", $"系统错误:{ex.Message}");
                return View("Index");
            }

            return View("Index");
        }
    }
}

第三步:添加对应的视图(显示表单和提示)

在Views/Scan文件夹下创建Index.cshtml,用来展示输入表单和错误/成功提示:

@{
    ViewBag.Title = "订单扫描";
}

<h2>订单扫描</h2>

@using (Html.BeginForm("SubmitScan", "Scan", FormMethod.Post))
{
    <div class="form-group mt-3">
        @Html.Label("订单号", new { @class = "form-label" })
        @Html.TextBox("orderNumber", null, new { @class = "form-control", placeholder = "请输入8位订单号", maxlength = 8 })
        @Html.ValidationMessage("", new { @class = "text-danger mt-1" })
    </div>
    <button type="submit" class="btn btn-primary mt-2">确认扫描</button>
}

@if (!string.IsNullOrEmpty(ViewBag.SuccessMessage))
{
    <div class="alert alert-success mt-3">@ViewBag.SuccessMessage</div>
}

关键问题说明

  1. 为什么之前的代码不行?

    • 你没有调用存储过程,而是自己写了UPDATE语句,完全偏离了需求;
    • 错误地把XML数据传给了订单号参数,导致数据库根本找不到对应订单;
    • static方法无法和MVC的视图、ModelState交互,没法把错误信息返回给用户;
    • 异常处理只在控制台输出,用户看不到任何反馈。
  2. 存储过程的Severity级别
    之前用23会强制断开数据库连接,用16是标准的用户级错误提示,不会中断连接。

  3. 连接字符串的最佳实践
    不要把连接字符串硬编码在代码里,放到web.config的<connectionStrings>节点中,方便后续修改。


备注:内容来源于stack exchange,提问作者CodeHopperComeT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 12:50:28