HttpModule - получить HTML-контент или элементы управления для изменений - PullRequest
3 голосов
/ 02 декабря 2008

Попробовал что-то вроде этого:

HttpApplication app = s as HttpApplication; //s is sender of the OnBeginRequest event
System.Web.UI.Page p = (System.Web.UI.Page)app.Context.Handler;
System.Web.UI.WebControls.Label lbl = new System.Web.UI.WebControls.Label();
lbl.Text = "TEST TEST TEST";
p.Controls.Add(lbl);    

при запуске я получаю «Ссылка на объект не установлена ​​на экземпляр объекта». для последней строки ...

Как мне вставить две строки текста (asp.net/html) при определенных действиях в исходном файле? И как мне определить расширение файла (я хочу применить это только к файлам aspx ...?

Ответы [ 4 ]

6 голосов
/ 04 июня 2010

Это проще, чем вы думаете:

    public void Init(HttpApplication app)
    {
        app.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    }

    private void OnPreRequestHandlerExecute(object sender, EventArgs args)
    {
        HttpApplication app = sender as HttpApplication;
        if (app != null)
        {
            Page page = app.Context.Handler as Page;
            if (page != null)
            {
                page.PreRender += OnPreRender;
            }
        }
    }

    private void OnPreRender(object sender, EventArgs args)
    {
        Page page = sender as Page;
        if (page != null)
        {
            page.Controls.Clear(); // Or do whatever u want with ur page...
        }
    }

Если событие PreRender недостаточно, вы можете добавить любое событие, которое вам нужно, в PreRequestHandlerExecute EventHandler ...

4 голосов
/ 02 декабря 2008

Я не уверен, но я не думаю, что вы можете использовать HttpModule для изменения дерева управления страницей (пожалуйста, исправьте меня, если я ошибаюсь). Вы МОЖЕТЕ изменить HTML-разметку, однако, вам придется написать «фильтр ответа» для этого. Например, см. http://aspnetresources.com/articles/HttpFilters.aspx, или Google для "httpmodule response filter".

1 голос
/ 03 декабря 2008

Похоже, что решение HttpFilter добивается цели здесь: o)

Если бы я использовал MOSS / .net 2.x +, я мог бы использовать версию Runes или просто добавить свои теги на главную страницу ...

Супер предложения и после тестирования решения я приму решение miies.myopenid.com, так как оно, похоже, решает реальную проблему

0 голосов
/ 02 декабря 2008

Произошли некоторые изменения в том, как вы пишете HttpModules в IIS7 по сравнению с IIS6 или 5, поэтому, возможно, мое предложение недопустимо, если вы используете IIS7.

Если вы используете текущее статическое свойство HttpContext, вы можете получить ссылку на текущий контекст. Класс HttpContext имеет свойства как для запроса (тип HttpRequest), так и для ответа (HttpResponse), и в зависимости от того, где какое событие вы обрабатываете (например, Application.EndRequest?), Вы можете выполнять различные действия над этими объектами.

Если вы хотите изменить содержимое доставляемой страницы, вы, вероятно, захотите сделать это как можно позже, поэтому, вероятно, лучшее место для этого - реагирование на событие EndRequest.

Проверка того, какой тип файла был запрошен, может быть выполнена путем проверки свойства Request.Url, возможно, вместе с классом System.IO.Path. Попробуйте что-то вроде этого:

string requestPath = HttpContext.Current.Request.Url.AbsolutePath;
string extension = System.IO.Path.GetExtension(requestPath);
bool isAspx = extension.Equals(".aspx");

Изменение содержимого сложнее. Вы можете сделать это в одном из событий объекта Context, но я не уверен.

Одним из возможных подходов может быть написание собственного класса, производного от пользовательской страницы, который будет проверять значение в коллекции Context.Items. Если это значение было найдено, вы можете добавить метку к объекту PlaceHolder и установить для текста метки любое значение.

Как-то так должно работать:

Добавьте следующий код в производный класс HttpModule:

public void Init(HttpApplication context)
{
  context.BeginRequest += new EventHandler(BeginRequest);
}

void BeginRequest(object sender, EventArgs e)
{

  HttpContext context = HttpContext.Current;
  HttpRequest request = context.Request;

  string requestPath = HttpContext.Current.Request.Url.AbsolutePath;
  string extension = System.IO.Path.GetExtension(requestPath);
  bool isAspx = extension.Equals(".aspx");

  if (isAspx)
  {
    // Add whatever you need of custom logic for adding the content here
    context.Items["custom"] = "anything here";
  }

}

Затем вы добавляете следующий класс в папку App_Code:

public class CustomPage : System.Web.UI.Page
{
  public CustomPage()
  { }

  protected override void OnPreRender(EventArgs e)
  {
    base.OnPreRender(e);

    if (Context.Items["custom"] == null)
    {
      return;
    }

    PlaceHolder placeHolder = this.FindControl("pp") as PlaceHolder;
    if (placeHolder == null)
    {
      return;
    }

    Label addedContent = new Label();
    addedContent.Text = Context.Items["custom"].ToString();
    placeHolder .Controls.Add(addedContent);

  }

}

Затем вы изменяете свои страницы следующим образом:

public partial class _Default : CustomPage

Обратите внимание, что наследование изменено с System.Web.UI.Page на CustomPage.

И, наконец, вы добавляете объекты PlaceHolder в ваши aspx-файлы, где бы вы ни хотели, чтобы ваш пользовательский контент.

...