【问题标题】:Why does decorating HTML elements with 'runat="server"' not make them accessible from the code-behind?为什么用 'runat="server"' 装饰 HTML 元素不能让它们从代码隐藏中访问?
【发布时间】:2015-10-24 01:42:18
【问题描述】:

根据这个How to access html controls in code behind,我应该能够像这样将'runat="server"'添加到我的html元素中:

<input type="email" id="email" runat="server" />

...然后在 C# 中通过其 ID 访问 html 元素,如下所示:

String usersEmail = email.Value;

但是,尝试这样做会导致“名称‘电子邮件’在当前上下文中不存在

试图从代码隐藏中访问 html 元素以进行操作真的是失败的原因吗?

更新

作为对 Steve Brookes 建议的回答/响应,以下是我的 ascx 文件顶部的内容:

<%@ Control Language="C#" AutoEventWireup="true" 
CodeBehind="PostTravelWizardWebPartUserControl.ascx.cs"
Inherits="PostTravelWizard.PostTravelWizardWebPart.PostTravelWizardWebPartUserControl" %>

...而布鲁克斯先生推荐这样的东西:

<%@Page Language="C#" AutoEventWireup="false" CodeFile="Default.aspx.cs" 
Inherits="_Default"%>

这是否足够接近? IOW,而不是“Page”,我有“Control”(它源自 UserControl);我有“CodeBehind”而不是“CodeFile”,而且我的继承不同。

我尝试将 AutoEventWireup 切换为 false,但没有任何区别。

更新 2

谢谢索林,

我不知道这个要求(将所有内容封装在“表单”标签中),但即使这样做了:

<form id="formPostTravel" runat="server">
   . . .  (all the html elements)
</form>

...没有区别;我仍然得到,“名称'电子邮件'在当前上下文中不存在”

更新 3

对 Steve Brookes 建议的另一个回应是“将 CodeBehind 更改为 CodeFile 并添加一个应与您的代码隐藏文件的类名匹配的 Inherits 属性。另一个建议是将 ID 更改为 EmailAddress 或其他可能的东西与保留字的某种命名冲突!”:

首先,我将 CodeBehind 更改为 CodeFile

然后,我验证了 Inherits 属性与我的代码隐藏文件的类名匹配。该文件是:

namespace PostTravelWizard.PostTravelWizardWebPart
{
    public partial class PostTravelWizardWebPartUserControl : UserControl

...继承值为“PostTravelWizard.PostTravelWizardWebPart.PostTravelWizardWebPartUserControl

最后,我还将 HTML 元素的 ID 从 'email' 更改为 'emailaddress':

<input type="email" id="emailaddress" runat="server" />

...但现在我得到了,“名称'emailaddress'在当前上下文中不存在

更新 4

关于这里正在尝试的内容。

这是在 *.ascx 文件中的 html 块中定义“电子邮件”输入的位置:

<input type="email" id="emailaddress" runat="server" />

这是我尝试从相应的 *.ascx.cs 文件中访问其值的方式:

namespace PostTravelWizard.PostTravelWizardWebPart
{
    public partial class PostTravelWizardWebPartUserControl : UserControl
    {
    . . .
    String usersEmail = emailaddress.Value; 

但我得到了奖励,“名称'emailaddress'在当前上下文中不存在

更新 5

遵循 Steven Brookes 的建议:

您可以右键单击 ascx 文件并查看设计器,然后更改为查看代码。这很可能会重新生成设计器文件

我能够将一些字段放入designer.cs;其他人(大多数)因为他们开始“隐藏”?我不知道...

【问题讨论】:

    标签: c# sharepoint-2010 code-behind runatserver htmlelements


    【解决方案1】:

    您的页面是asp.net 页面吗?如果是这样,请确保您的页面指令正确指向您的代码隐藏文件。类似这样的内容应该出现在您的页面顶部:

    <%@Page Language="C#" AutoEventWireup="false" CodeFile="Default.aspx.cs" Inherits="_Default"%>
    

    【讨论】:

    • 啊,它是一个用户控件,您的指令很好,但可能将 CodeBehind 更改为 CodeFile 并添加一个应与您的代码隐藏文件的类名匹配的 Inherits 属性。另一个建议是将 ID 更改为 EmailAddress 或其他内容,因为它可能与保留字有某种命名冲突!
    • 可能是一个愚蠢的问题,但您正试图从用户控件的代码文件而不是其他地方访问电子邮件控件,对吧?
    • 我正在尝试从代码隐藏中访问 HTML 元素的值(以便我可以在使用 iTextSharp 创建的 PDF 文件中生成正确的值)。我已经从代码隐藏/C# 中动态创建了所有控件,并且开始怀疑“走向原生”是否是一个错误。
    • 你所做的应该没问题。在阅读了此页面上的其他一些 cmets 后进行了挖掘,它可能与 stackoverflow.com/questions/45325/… 有关,一个答案说从 CodeFile 改回 CodeBehind,对不起!完成此操作后,您可以右键单击 ascx 文件并查看设计器,然后更改为查看代码。这很可能会重新生成设计器文件
    • 不用担心,伙计 - 我会在我开始工作时尝试 - 我在这份工作的最后一天,星期一开始新的一天,可能永远不会再使用 Sharepoint,但想得到在我说“Sayonara / goodbye / auf wiedersehen / adios”等之前,这个项目处于良好状态。
    【解决方案2】:

    有时 Visual Studio 会忘记在“.designer”文件中定义服务器端控件,而您无法从后面的代码中访问它们

    在这些情况下,您必须在代码中手动定义这些元素。

    请注意,您必须使用元素的确切类型和名称以及“受保护”成员来定义这些变量

    【讨论】:

    • 不是这样的,Sepehr;这就是我之前所做的(使用 C# 动态创建元素),但认为原生 HTML 路由更“有机”
    • 我的意思是写,“说它不是这样的,....”而不是“所以它不是这样”,参考向 Shoeless Joe Jackson 提出的著名问题(它是毕竟季后赛)。
    【解决方案3】:

    您可能忘记将其放入服务器端形式:

      <form id="form1" runat="server">
        <input type="email" id="email" runat="server" />
      </form>
    

    html 元素需要位于表单标签内,并且表单标签和 html 元素都需要具有runat="server" 作为属性,然后您才能从代码隐藏中访问它们。

    更新 1

    我创建了一个测试 web 表单和测试用户控件,并将用户控件放在 web 表单中。这是所有代码:

    TestWebForm.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestWebForm.aspx.cs" Inherits="TestWeb.TestWebForm" %>
    <%@ Register TagPrefix="uc" src="~/TestWebUserControl.ascx" tagName="TestWebUserControl" %>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <form id="form1" runat="server">
            <uc:TestWebUserControl id="TestWebUser" runat="server" />
        </form>
    </body>
    </html>
    

    TestWebForm.aspx.cs

    using System;
    using System.Web.UI;
    
    namespace TestWeb
    {
        public partial class TestWebForm : Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                var y = TestWebUser.InnerControlEmail.Value;
            }
        }
    }
    

    TestWebUserControl.ascx

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TestWebUserControl.ascx.cs" Inherits="TestWeb.TestWebUserControl" %>
    
    <input type="email" id="ControlEmail" runat="server" />
    

    TestWebUserControl.ascx.cs

    using System;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    
    namespace TestWeb
    {
        public partial class TestWebUserControl : UserControl
        {
            public HtmlInputGenericControl InnerControlEmail
            {
                get { return ControlEmail; }
            }
            protected void Page_Load(object sender, EventArgs e)
            {
                var x = ControlEmail.Value;
            }
        }
    }
    

    这对我有用。请注意,我必须更改&lt;%@ Register %&gt; 标记以使用srctagName 属性,而不是默认的NamespaceAssembly 属性。

    另外,html 控件最终会被包装在 web 表单中的 &lt;form&gt; 标记中,因此用户控件中不需要它。

    并且由于该属性,可以通过放置此用户控件的表单访问 html 控件。

    更新 2

    这是 TestWebUserControl.ascx.designer.cs 文件:

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated. 
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    namespace TestWeb {
    
    
        public partial class TestWebUserControl {
    
            /// <summary>
            /// ControlEmail control.
            /// </summary>
            /// <remarks>
            /// Auto-generated field.
            /// To modify move field declaration from designer file to code-behind file.
            /// </remarks>
            protected global::System.Web.UI.HtmlControls.HtmlInputGenericControl ControlEmail;
        }
    }
    

    如果我删除 protected global::System.Web.UI.HtmlControls.HtmlInputGenericControl ControlEmail;,我会得到您的确切错误。因此,您的设计器文件很可能不正常。

    从您的 .ascx 文件中删除 html 控件定义 (&lt;html id="email"/&gt;),尝试编译(您会收到错误),重新添加,尝试编译(您会收到错误)再次尝试编译(现在应该工作)。

    【讨论】:

    • 我需要更清楚一点。您在 .aspx 页面上的表单中的自定义用户控件中有一个电子邮件 html 控件?您试图从哪里访问 html 控件,主页或用户控件本身?当我创建一个 Web 表单页面,然后是一个自定义用户控件并将其放在我的 Web 表单页面上,然后在我的用户控件中创建一个电子邮件 html 控件时,我可以从自定义用户控件后面的代码访问电子邮件 html 控件,但是不是来自网络表单背后的代码。我可以公开用户控件上的属性,这些属性通过内部电子邮件控件...
    • 它只是一个普通的旧html元素,在ascx文件中的html中定义。我正在尝试从 UserControl 后代(在/从 Sharepoint WebPart 上)的代码隐藏中访问 html 元素。
    • 我添加了一个更新 4,它应该把它放在上下文中,如果有什么仍然模糊的话。
    • 好的,我查看了TestWebUserControl.designer.cs 文件并删除了我在那里找到的代码,然后得到了您的确切错误。因此,您的控件的设计器文件似乎有问题。
    • 我该如何解决这个问题 - 可以重新生成,还是必须手动构建?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    相关资源
    最近更新 更多