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

通过存储过程与ControlParameter传用户至GridView时遇控件查找错误

问题:Asp.Net WebForms中SqlDataSource找不到ControlParameter指定的控件

错误信息

服务器错误 '/' 应用程序。

找不到ControlParameter 'httpuser'中的控件 'hdn_httpuser'。

描述: 执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其代码来源的更多信息。

异常详细信息: System.InvalidOperationException: 找不到ControlParameter 'httpuser'中的控件 'hdn_httpuser'。

源错误:

执行当前Web请求期间生成了未处理的异常。可通过下面的堆栈跟踪信息确定异常的起源和位置。

堆栈跟踪:

[InvalidOperationException: 找不到ControlParameter 'httpuser'中的控件 'hdn_httpuser'。]

System.Web.UI.WebControls.ControlParameter.Evaluate(HttpContext context, Control control) +553

System.Web.UI.WebControls.Parameter.UpdateValue(HttpContext context, Control control) +70

System.Web.UI.WebControls.ParameterCollection.UpdateValues(HttpContext context, Control control) +137

System.Web.UI.WebControls.SqlDataSource.LoadCompleteEventHandler(Object sender, EventArgs e) +59

System.EventHandler.Invoke(Object sender, EventArgs e) +0

System.Web.UI.Page.OnLoadComplete(EventArgs e) +138

System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5909

现有代码

后台代码(aspx.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WorldsStrongestProgrammer2024App
{
    public partial class Orientation : System.Web.UI.Page
    {
        // 继承自母版页

        // # 用户检查变量
        public Orientation()
        {
        }

        public string httpuser;

        public string GetHttpUser()
        { 
            var a = HttpContext.Current.User.Identity.Name.ToString();
            httpuser = a;

            return httpuser; 
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                GetHttpUser();
            }

            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                GetHttpUser();
            }
        }
    }
}

前端页面(aspx)

<asp:GridView runat="server" ID="gv_httpuser"> 
    <columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:TextBox ID="hdn_httpuser" runat="server" Value="<%: httpuser %>"/>
            </ItemTemplate>
        </asp:TemplateField>
    </columns>
</asp:GridView>

<asp:GridView runat="server" ID="gv_aspuser" DataSourceID="sql_aspuser" AutoGenerateColumns="true" DataKeyNames="HttpUser">
</asp:GridView>

<asp:SqlDataSource runat="server" ID="sql_aspuser" ConnectionString="<%$ ConnectionStrings:Documents_SQLConn %>" SelectCommand="sLoginWizardOrientation_Step1" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:ControlParameter controlID="hdn_httpuser" PropertyName="Text" Name="httpuser" Type="String" />
    </SelectParameters>
</asp:SqlDataSource>

SQL存储过程

CREATE PROCEDURE sLoginWizardOrientation_Step1 
    (@httpuser varchar(max) = '%')
AS
    SELECT 
        [Id],
        [Hometown],
        [Email],
        [PhoneNumber],
        [UserName] AS HttpUser
    FROM 
        [db_a84118_maindocuments].[dbo].[AspNetUsers]
    WHERE 
        UserName = @httpuser

问题根源

  1. hdn_httpuser被放在gv_httpuser的ItemTemplate中,而这个GridView没有绑定任何数据,页面渲染时不会生成这个TextBox控件。
  2. 即使GridView有数据,模板内的控件属于GridView的子容器,SqlDataSource在页面生命周期的LoadComplete阶段查找控件时,无法直接通过ID定位到子容器内的控件(会生成带GridView前缀的客户端ID)。
  3. 用TextBox存储隐藏值不合理,应该用专门的HiddenField控件。

解决方案

方案一:改用页面级HiddenField

修改后台代码

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WorldsStrongestProgrammer2024App
{
    public partial class Orientation : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // 直接给HiddenField赋值当前用户名
                hdn_httpuser.Value = HttpContext.Current.User.Identity.Name;
                // 手动触发GridView绑定确保数据加载
                gv_aspuser.DataBind();
            }
        }
    }
}

修改前端页面

<!-- 用HiddenField替代GridView内的TextBox -->
<asp:HiddenField runat="server" ID="hdn_httpuser" />

<asp:GridView runat="server" ID="gv_aspuser" DataSourceID="sql_aspuser" AutoGenerateColumns="true" DataKeyNames="HttpUser">
</asp:GridView>

<asp:SqlDataSource runat="server" ID="sql_aspuser" ConnectionString="<%$ ConnectionStrings:Documents_SQLConn %>" SelectCommand="sLoginWizardOrientation_Step1" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <!-- 指向HiddenField的Value属性 -->
        <asp:ControlParameter ControlID="hdn_httpuser" PropertyName="Value" Name="httpuser" Type="String" />
    </SelectParameters>
</asp:SqlDataSource>

方案二:直接在代码中给SqlDataSource赋值参数(更简洁)

这种方式不需要额外的隐藏控件,直接通过代码传递参数:

修改后台代码

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WorldsStrongestProgrammer2024App
{
    public partial class Orientation : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // 直接给SqlDataSource的参数赋值
                sql_aspuser.SelectParameters["httpuser"].DefaultValue = HttpContext.Current.User.Identity.Name;
                gv_aspuser.DataBind();
            }
        }
    }
}

修改前端页面

<asp:GridView runat="server" ID="gv_aspuser" DataSourceID="sql_aspuser" AutoGenerateColumns="true" DataKeyNames="HttpUser">
</asp:GridView>

<asp:SqlDataSource runat="server" ID="sql_aspuser" ConnectionString="<%$ ConnectionStrings:Documents_SQLConn %>" SelectCommand="sLoginWizardOrientation_Step1" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <!-- 仅定义参数,不依赖控件 -->
        <asp:Parameter Name="httpuser" Type="String" />
    </SelectParameters>
</asp:SqlDataSource>

额外优化建议

  • 移除原代码中无用的GetHttpUser方法和httpuser字段,直接在需要的地方获取HttpContext.Current.User.Identity.Name即可。
  • 可以在Page_Load中添加判断,如果用户未认证,直接跳转到登录页,避免后续逻辑出错。

内容的提问来源于stack exchange,提问作者PJ Martin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:44:57