Почему украшение HTML-элементов с помощью runat = server не делает их доступными из кода программной части?

Согласно этому как получить доступ к элементам управления html в коде позади, Я должен иметь возможность добавить runat = "server" 'к своим элементам html следующим образом:

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

... а затем получить доступ к элементу html по его идентификатору из C #, например:

String usersEmail = email.Value;

Однако попытка сделать это приводит к "Имя 'email' не существует в текущем контексте"

Действительно ли попытки получить доступ к элементам html для манипуляций из кода программной части безнадежны?

ОБНОВИТЬ

В ответ / ответ на предложение Стива Брукса вот что у меня в верхней части моего файла 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"), но даже после этого:

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

...это не имеет значения; Я по-прежнему получаю: «Имя 'email' не существует в текущем контексте»

ОБНОВЛЕНИЕ 3

Еще один ответ на предложения Стива Брукса, которые заключались в «изменении CodeBehind на CodeFile и добавлении атрибута Inherits, который должен соответствовать имени класса вашего кода позади файла. Другое предложение - изменить идентификатор на EmailAddress или что-то в этом роде, поскольку это может быть своего рода конфликт имен с зарезервированным словом! ":

Сначала я изменил CodeBehind на CodeFile

Затем я проверил, соответствует ли атрибут Inherits имени класса моего кода файла. Этот файл:

namespace PostTravelWizard.PostTravelWizardWebPart
{
    public partial class PostTravelWizardWebPartUserControl : UserControl

... и наследуемое значение - "PostTravelWizard.PostTravelWizardWebPart.PostTravelWizardWebPartUserControl"

Наконец, я также изменил идентификатор HTML-элемента с «email» на «emailaddress»:

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

... но теперь я получаю: «Имя 'emailaddress' не существует в текущем контексте»

ОБНОВЛЕНИЕ 4

Для небольшого контекста того, что здесь делается.

Здесь определяется ввод "email" в файле * .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

Следуя этому совету Стивена Брукса:

вы можете щелкнуть правой кнопкой мыши файл ascx и просмотреть конструктор, а затем перейти к просмотру кода. Это вполне может восстановить файл дизайнера

Мне удалось получить некоторые поля в файле designer.cs; остальные (большинство), потому что они начинаются «скрытыми»? Я не знаю...


person B. Clay Shannon    schedule 22.10.2015    source источник


Ответы (3)


Ваша страница является страницей asp.net? В таком случае убедитесь, что директива вашей страницы правильно указывает на файл кода программной части. Примерно так должно быть вверху вашей страницы:

<%@Page Language="C#" AutoEventWireup="false" CodeFile="Default.aspx.cs" Inherits="_Default"%>
person Steven Brookes    schedule 22.10.2015
comment
Ах, это пользовательский элемент управления, ваша директива была в порядке, но, возможно, измените CodeBehind на CodeFile и добавив атрибут Inherits, который должен соответствовать имени класса вашего кода за файлом. Другое предложение - изменить идентификатор на EmailAddress или что-то в этом роде, поскольку это может быть своего рода конфликт имен с зарезервированным словом! - person Steven Brookes; 23.10.2015
comment
Возможно, глупый вопрос, но вы пытаетесь получить доступ к элементу управления электронной почтой из файла кода для пользовательского элемента управления, а не где-либо еще, верно? - person Steven Brookes; 23.10.2015
comment
Я пытаюсь получить доступ к значению элемента HTML из кода программной части (чтобы я мог сгенерировать правильные значения в файле PDF, который я создаю с помощью iTextSharp). Я уже сделал это, создав все элементы управления динамически из кода программной части / C #, и я начинаю задаваться вопросом, не было ли ошибкой переход на собственный. - person B. Clay Shannon; 23.10.2015
comment
То, что вы делаете, должно быть в порядке. После прочтения некоторых других комментариев на этой странице выяснилось, что это может быть связано с stackoverflow.com/questions/45325/, один ответ говорит, что нужно вернуться с CodeFile на CodeBehind, извините! как только вы это сделаете, вы можете щелкнуть правой кнопкой мыши файл ascx и просмотреть конструктор, а затем перейти к просмотру кода. Это вполне может регенерировать файл дизайнера - person Steven Brookes; 23.10.2015
comment
Не беспокойся, приятель, я попробую это сделать, когда пойду на работу - мой последний день на этой работе, начинаю новую в понедельник, и, вероятно, никогда больше не буду использовать Sharepoint, но хотел бы привести этот проект в хорошее состояние, прежде чем я скажи Sayonara / до свидания / auf wiedersehen / adios и т. д. - person B. Clay Shannon; 23.10.2015

Иногда Visual Studio забывает определить элементы управления на стороне сервера в файле .designer, и вы не можете получить к ним доступ из кода.

В этих случаях вам придется вручную определять эти элементы в своем коде.

обратите внимание, что вы должны определить эти переменные с ТОЧНЫМ типом и именем вашего элемента и как «защищенные» члены

person Sepehr Davarnia    schedule 22.10.2015
comment
Так что это не так, Сепер; это то, что я делал раньше (динамически создавал элементы с помощью C #), но думал, что собственный HTML-маршрут будет более органичным - person B. Clay Shannon; 23.10.2015
comment
Я хотел написать: «Скажи, что это не так… не так». Так что это не так в отношении известного вопроса, заданного Босоногому Джо Джексону (в конце концов, это постсезон). - person B. Clay Shannon; 23.10.2015

Возможно, вы забыли поместить его в серверную форму:

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

Элементы html должны находиться внутри тега формы, а тег формы и элемент html должны иметь runat="server" в качестве атрибута, прежде чем вы сможете получить к ним доступ из своего кода программной части.

обновление 1

Я создал тестовую веб-форму и тестовый пользовательский элемент управления и поместил пользовательский элемент управления в веб-форму. Вот весь код:

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;
        }
    }
}

Это сработало для меня. Обратите внимание, что мне пришлось изменить тег <%@ Register %>, чтобы использовать атрибуты src и tagName вместо атрибутов Namespace и Assembly по умолчанию.

Кроме того, элемент управления html в конечном итоге заключен в тег <form> в веб-форме, поэтому он не нужен в пользовательском элементе управления.

А благодаря этому свойству к элементу управления 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;, я получу вашу точную ошибку. Так что ваш дизайнерский файл, скорее всего, не в порядке.

Удалите определение элемента управления html (<html id="email"/>) из файла .ascx, попробуйте скомпилировать (вы получите ошибки), добавьте его обратно, попробуйте скомпилировать (вы получите ошибки), попробуйте скомпилировать снова (теперь все должно работать).

person Thorin    schedule 22.10.2015
comment
Мне нужно немного больше ясности. У вас есть элемент управления электронной почты html в настраиваемом пользовательском элементе управления в форме на странице .aspx? Где вы пытаетесь получить доступ к элементу управления html, с главной страницы или из самого пользовательского элемента управления? Когда я создаю страницу веб-формы, затем настраиваемый пользовательский элемент управления и помещаю его на свою страницу веб-формы, а затем элемент управления электронной почты html внутри моего пользовательского элемента управления, я могу получить доступ к элементу управления электронной почты html из кода, стоящего за настраиваемым пользовательским элементом управления, но не из кода веб-формы. Я могу раскрыть свойства пользовательского элемента управления, которые передаются во внутренний элемент управления электронной почтой ... - person Thorin; 23.10.2015
comment
Это просто обычный старый элемент html, определенный в html в файле ascx. Я пытаюсь получить доступ к элементу html из кода программной части потомка UserControl (на / из Sharepoint WebPart). - person B. Clay Shannon; 23.10.2015
comment
Я добавил Обновление 4, которое должно поместить все в контекст, если что-то еще нечеткое. - person B. Clay Shannon; 23.10.2015
comment
Хорошо, я просмотрел файл TestWebUserControl.designer.cs и удалил найденный там код, а затем получил вашу точную ошибку. Похоже, проблема связана с файлом конструктора вашего элемента управления. - person Thorin; 23.10.2015
comment
Как я могу это исправить - можно ли его регенерировать или мне придется собирать его вручную? - person B. Clay Shannon; 23.10.2015
comment
Чтобы восстановить файл .designer.cs, я всегда просто вносил изменения в html в файле .aspx или .ascx. Затем Visual Studio видит разницу и регенерирует весь файл. Таким образом, вы можете сделать что-то вроде удаления элемента управления, компиляции, затем добавления элемента управления обратно, а затем повторной компиляции. Я обрисовал это в своем обновлении 2. - person Thorin; 23.10.2015