Как я могу взять на себя больше управления в ASP.NET?

Модуль проверки имеет методы для извлечения исходного кода из объектов python. По-видимому, он работает только в том случае, если источник находится в файле. Если у вас есть это, я думаю, вам не нужно будет получать источник от объекта.

123
задан Pale Blue Dot 17 September 2009 в 18:09
поделиться

7 ответов

Это решение предоставит Вам программный доступ к средствам управления в их полноте включая все атрибуты на средствах управления. Кроме того, только значения текстового поля появятся в URL после представления, таким образом, Ваш ПОЛУЧАТЬ URL запроса будет, больше "значимое"

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="JonSkeetForm.aspx.cs" Inherits="JonSkeetForm" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Jon Skeet's Form Page</title>
</head>
<body>
    <form action="JonSkeetForm.aspx" method="get">
    <div>
        <input type="text" ID="text1" runat="server" />
        <input type="text" ID="text2" runat="server" />
        <button type="submit">Submit</button>
        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
                <div>Some text</div>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

Затем в Вашем коде - позади Вас может сделать все, в чем Вы нуждаетесь на PageLoad

public partial class JonSkeetForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        text1.Value = Request.QueryString[text1.ClientID];
        text2.Value = Request.QueryString[text2.ClientID];
    }
}

, Если Вы не хотите форму, которая имеет runat="server", затем необходимо использовать средства управления HTML. Легче работать с в Ваших целях. Просто используйте регулярные HTML-тэги и поместите runat="server" и дайте им идентификатор. Затем можно получить доступ к ним программно и код без ViewState.

единственный недостаток - то, что у Вас не будет доступа ко многому из "полезного" управления сервером ASP.NET как GridView с. Я включал Repeater в свой пример, потому что я предполагаю, что Вы хотите иметь поля на той же странице, как результатами и (к моему знанию) Repeater является единственное управление DataBound, которое будет работать без runat="server" атрибут в Теге form.

76
ответ дан 24 November 2019 в 01:18
поделиться

Вы определенно (по моему скромному мнению), на правильном пути, не используя runat = "сервер" в Вашем Теге form. Это просто означает, что необходимо будет извлечь значения из Запроса. QueryString непосредственно, тем не менее, как в этом примере:

На самой .aspx странице:

<%@ Page Language="C#" AutoEventWireup="true" 
     CodeFile="FormPage.aspx.cs" Inherits="FormPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>ASP.NET with GET requests and no viewstate</title>
</head>
<body>
    <asp:Panel ID="ResultsPanel" runat="server">
      <h1>Results:</h1>
      <asp:Literal ID="ResultLiteral" runat="server" />
      <hr />
    </asp:Panel>
    <h1>Parameters</h1>
    <form action="FormPage.aspx" method="get">
    <label for="parameter1TextBox">
      Parameter 1:</label>
    <input type="text" name="param1" id="param1TextBox" value='<asp:Literal id="Param1ValueLiteral" runat="server" />'/>
    <label for="parameter1TextBox">
      Parameter 2:</label>
    <input type="text" name="param2" id="param2TextBox"  value='<asp:Literal id="Param2ValueLiteral" runat="server" />'/>
    <input type="submit" name="verb" value="Submit" />
    </form>
</body>
</html>

и в коде - позади:

using System;

public partial class FormPage : System.Web.UI.Page {

        private string param1;
        private string param2;

        protected void Page_Load(object sender, EventArgs e) {

            param1 = Request.QueryString["param1"];
            param2 = Request.QueryString["param2"];

            string result = GetResult(param1, param2);
            ResultsPanel.Visible = (!String.IsNullOrEmpty(result));

            Param1ValueLiteral.Text = Server.HtmlEncode(param1);
            Param2ValueLiteral.Text = Server.HtmlEncode(param2);
            ResultLiteral.Text = Server.HtmlEncode(result);
        }

        // Do something with parameters and return some result.
        private string GetResult(string param1, string param2) {
            if (String.IsNullOrEmpty(param1) && String.IsNullOrEmpty(param2)) return(String.Empty);
            return (String.Format("You supplied {0} and {1}", param1, param2));
        }
    }

прием здесь - то, что мы используем Литералы ASP.NET в значении = "" атрибуты вводов текста, таким образом, сами текстовые поля не имеют к runat = "сервер". Результаты затем перенесены в ASP:Panel и наборе Свойства видимости на загрузке страницы, зависящей, хотите ли Вы отобразить какие-либо результаты или нет.

12
ответ дан 24 November 2019 в 01:18
поделиться

Я создал бы HTTP-модуль, который обрабатывает маршрутизацию (подобный MVC, но не сложный, просто пара if операторы), и вручите его aspx или ashx страницы. aspx предпочтен, так как легче изменить шаблон страницы. Я не использовал бы WebControls в aspx как бы то ни было. Всего Response.Write.

Между прочим, для упрощения вещей можно сделать проверку параметра в модуле (поскольку это совместно использует код с маршрутизацией, вероятно), и сохраните его к HttpContext.Items и затем представьте их на странице. Это будет работать в значительной степени как MVC без всего звонка и свиста. Это - то, что я сделал много перед ASP.NET дни MVC.

1
ответ дан 24 November 2019 в 01:18
поделиться

Я действительно был рад полностью отказаться от класса страницы в целом и просто обработчика каждый запрос с большим случаем переключателя на основе URL. Evey "страница" становится шаблоном HTML и объектом c#. Шаблонный класс использует regex с делегатом соответствия, который выдерживает сравнение с ключевым набором.

преимущества:

  1. Это действительно быстро, даже после того, чтобы перекомпилировать, нет почти никакой задержки (класс страницы должен быть большим)
  2. , управление действительно детализировано (большой для SEO и обработки DOM для проигрывания хорошо с JS)
  3. , презентация является отдельной от логики
  4. , jQuery имеет полный контроль над неприятностями html

:

  1. простой материал берет немного дольше в этом, единственное текстовое поле требует кода в нескольких местах, но это действительно увеличивается действительно хорошо
  2. , всегда заманчиво просто сделать это с просмотром страницы, пока я не вижу состояния отображения (urgh) затем, я привязываюсь назад к действительности.

Jon, что является нами делающий на ТАК в субботу утром:)?

1
ответ дан 24 November 2019 в 01:18
поделиться

Я думал, что управление asp:Repeater было устаревшим.

движок шаблонов ASP.NET хорош, но можно столь же легко выполнить повторение с для цикла...

<form action="JonSkeetForm.aspx" method="get">
<div>
    <input type="text" ID="text1" runat="server" />
    <input type="text" ID="text2" runat="server" />
    <button type="submit">Submit</button>
    <% foreach( var item in dataSource ) { %>
        <div>Some text</div>   
    <% } %>
</div>
</form>

Формы ASP.NET являются видом хорошо, существует достойная поддержка со стороны Visual Studio, но этот runat = вещь "сервера", это просто неправильно. ViewState к.

я предлагаю, чтобы Вы смотрели на то, что делает ASP.NET MVC настолько большой, кого он отодвигает от подхода Форм ASP.NET, не выбрасывая все это.

можно даже записать собственный материал поставщика сборки для компиляции пользовательских представлений как NHaml. Я думаю, что необходимо здесь искать больше управления и просто доверия времени выполнения ASP.NET для обертывания HTTP и как среда хостинга CLR. При выполнении интегрированного режима затем, Вы сможете управлять Запросом HTTP / ответ также.

1
ответ дан 24 November 2019 в 01:18
поделиться

Вы думали о не устранении POST, а скорее перенаправление к подходящему ПОЛУЧАЮТ URL, когда форма ОТПРАВЛЯЕТСЯ. Таким образом, примите и ДОБЕРИТЕСЬ и POST, но на POST создают ПОЛУЧИТЬ запрос и перенаправление к нему. Это могло быть обработано или на странице или через HttpModule, если бы Вы хотели сделать ее независимой от страницы. Я думаю, что это сделало бы вещи намного легче.

РЕДАКТИРОВАНИЕ: я предполагаю, что у Вас есть EnableViewState = "ложный" набор на странице.

1
ответ дан 24 November 2019 в 01:18
поделиться

Хорошо, Джон, сначала проблема состояния просмотра:

Я не проверял, есть ли какие-либо внутренние код изменился с версии 2.0, но вот как я справился с избавлением от состояния представления несколько лет назад. На самом деле это скрытое поле жестко запрограммировано внутри HtmlForm, поэтому вам следует создать новое и приступить к его визуализации, выполняя вызовы самостоятельно. Обратите внимание, что вы также можете оставить __eventtarget и __eventtarget, если вы придерживаетесь простых старых элементов управления вводом (что, я думаю, вы бы захотели, поскольку это также помогает не требовать JS на клиенте):

protected override void RenderChildren(System.Web.UI.HtmlTextWriter writer)
{
    System.Web.UI.Page page = this.Page;
    if (page != null)
    {
        onFormRender.Invoke(page, null);
        writer.Write("<div><input type=\"hidden\" name=\"__eventtarget\" id=\"__eventtarget\" value=\"\" /><input type=\"hidden\" name=\"__eventargument\" id=\"__eventargument\" value=\"\" /></div>");
    }

    ICollection controls = (this.Controls as ICollection);
    renderChildrenInternal.Invoke(this, new object[] {writer, controls});

    if (page != null)
        onFormPostRender.Invoke(page, null);
}

Итак, вы получаете эти 3 статических MethodInfo и вызываете их, пропуская часть состояния просмотра;)

static MethodInfo onFormRender;
static MethodInfo renderChildrenInternal;
static MethodInfo onFormPostRender;

и вот конструктор типа вашей формы:

static Form()
{
    Type aspNetPageType = typeof(System.Web.UI.Page);

    onFormRender = aspNetPageType.GetMethod("OnFormRender", BindingFlags.Instance | BindingFlags.NonPublic);
    renderChildrenInternal = typeof(System.Web.UI.Control).GetMethod("RenderChildrenInternal", BindingFlags.Instance | BindingFlags.NonPublic);
    onFormPostRender = aspNetPageType.GetMethod("OnFormPostRender", BindingFlags.Instance | BindingFlags.NonPublic);
}

Если я правильно понял ваш вопрос, вы также не хотите использовать POST как действие ваших форм, вот как вы это сделаете:

protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer)
{
    writer.WriteAttribute("method", "get");
    base.Attributes.Remove("method");

    // the rest of it...
}

Думаю, это в значительной степени все. Сообщите мне, как это происходит.

РЕДАКТИРОВАТЬ: Я забыл методы состояния просмотра страницы:

Итак, ваша настраиваемая форма: HtmlForm получает свою новую абстрактную (или нет) страницу: System.Web.UI.Page: P

protected override sealed object SaveViewState()
{
    return null;
}

protected override sealed void SavePageStateToPersistenceMedium(object state)
{
}

protected override sealed void LoadViewState(object savedState)
{
}

protected override sealed object LoadPageStateFromPersistenceMedium()
{
    return null;
}

В этом случае я запечатываю методы, потому что вы не можете запечатать страницу (даже если она не является абстрактной, Скотт Гатри завернет ее в еще одну: P), но вы можете запечатать свою форму.

Если вы правильно поняли свой вопрос, вы также не хотите использовать POST в качестве действия ваших форм, поэтому вот как вы это сделаете:

protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer)
{
    writer.WriteAttribute("method", "get");
    base.Attributes.Remove("method");

    // the rest of it...
}

Думаю, это почти все. Сообщите мне, как это происходит.

РЕДАКТИРОВАТЬ: Я забыл методы состояния просмотра страницы:

Итак, ваша настраиваемая форма: HtmlForm получает свою новую абстрактную (или нет) страницу: System.Web.UI.Page: P

protected override sealed object SaveViewState()
{
    return null;
}

protected override sealed void SavePageStateToPersistenceMedium(object state)
{
}

protected override sealed void LoadViewState(object savedState)
{
}

protected override sealed object LoadPageStateFromPersistenceMedium()
{
    return null;
}

В этом случае я запечатываю методы, потому что вы не можете запечатать страницу (даже если она не является абстрактной, Скотт Гатри завернет ее в еще одну: P), но вы можете запечатать свою форму.

Если вы правильно поняли свой вопрос, вы также не хотите использовать POST в качестве действия ваших форм, поэтому вот как вы это сделаете:

protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer)
{
    writer.WriteAttribute("method", "get");
    base.Attributes.Remove("method");

    // the rest of it...
}

Думаю, это почти все. Сообщите мне, как это происходит.

РЕДАКТИРОВАТЬ: Я забыл методы состояния просмотра страницы:

Итак, ваша настраиваемая форма: HtmlForm получает свою новую абстрактную (или нет) страницу: System.Web.UI.Page: P

protected override sealed object SaveViewState()
{
    return null;
}

protected override sealed void SavePageStateToPersistenceMedium(object state)
{
}

protected override sealed void LoadViewState(object savedState)
{
}

protected override sealed object LoadPageStateFromPersistenceMedium()
{
    return null;
}

В этом случае я запечатываю методы, потому что вы не можете запечатать страницу (даже если она не является абстрактной, Скотт Гатри завернет ее в еще одну: P), но вы можете запечатать свою форму.

2
ответ дан 24 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: