Идеи класса ASP.net "BasePage"

Какая классная функциональность и методы вы добавили в классы ASP.net BasePage : System.Web.UI.Page?

Примеры

Здесь я использую для аутентификации, и я хотел бы услышать ваше мнение по этому поводу:

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

    // Authentication code omitted... Essentially same as below.

    if (_RequiresAuthentication && !(IsAuthorized))
    {
        RespondForbidden("You do not have permissions to view this page.", UnauthorizedRedirect);
        return;
    }
}

// This function is overridden in each page subclass and fitted to each page's
// own authorization requirements.
// This also allows cascading authorization checks,
// e.g: User has permission to view page? No - base.IsAuthorized - Is user an admin?
protected virtual bool IsAuthorized
{
    get { return true; }
}

Мой класс BasePage содержит экземпляр этого класса:

public class StatusCodeResponse {

    public StatusCodeResponse(HttpContext context) {
        this._context = context;
    }

    /// <summary>
    /// Responds with a specified status code, and if specified - transfers to a page.
    /// </summary>
    private void RespondStatusCode(HttpContext context, System.Net.HttpStatusCode status, string message, string transfer)
    {
        if (string.IsNullOrEmpty(transfer))
        {
            throw new HttpException((int)status, message);
        }

        context.Response.StatusCode = (int)status;
        context.Response.StatusDescription = message;
        context.Server.Transfer(transfer);
    }

    public void RespondForbidden(string message, string transfer)
    {
        RespondStatusCode(this._context, System.Net.HttpStatusCode.Forbidden, message, transfer);
    }

    // And a few more like these...

}

В качестве побочной заметки это может быть выполнено с использованием методов расширения для объекта HttpResponse.

И еще один метод, который я считаю весьма удобным для разбора аргументов querystring int:

public bool ParseId(string field, out int result)
{
    return (int.TryParse(Request.QueryString[field], out result) && result > 0);
}

Ответ 1

  • Связанный с сессией материал, некоторый сложный объект в BasePage, который сопоставляется с сеансом, и раскрывает его как свойство.
  • Выполнение таких действий, как заполнение объекта крошилки.

Но самое главное: не превращать вашу базовую страницу в некоторый вспомогательный класс. Не добавляйте такие вещи, как ParseId(), это просто смешно.


Кроме того, на основе первого сообщения: создайте материал, например IsAuthorized abstract. Таким образом, вы не создаете гигантские дыры в безопасности, если кто-то забывает, что существует какой-то виртуальный метод.

Ответ 2

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace MySite
{
    /// <summary>
    /// Base class with properties for meta tags for content pages
    /// http://www.codeproject.com/KB/aspnet/PageTags.aspx
    /// http://weblogs.asp.net/scottgu/archive/2005/08/02/421405.aspx
    /// </summary>
    public partial class BasePage : System.Web.UI.Page
    {
        private string keywords;
        private string description;


        /// <SUMMARY>
        /// Gets or sets the Meta Keywords tag for the page
        /// </SUMMARY>
        public string Meta_Keywords
        {
            get
            {
                return keywords;
            }
            set
            {
                // Strip out any excessive white-space, newlines and linefeeds
                keywords = Regex.Replace(value, "\\s+", " ");
            }
        }

        /// <SUMMARY>
        /// Gets or sets the Meta Description tag for the page
        /// </SUMMARY>
        public string Meta_Description
        {
            get
            {
                return description;
            }
            set
            {
                // Strip out any excessive white-space, newlines and linefeeds
                description = Regex.Replace(value, "\\s+", " ");
            }
        }


        // Constructor
        // Add an event handler to Init event for the control
        // so we can execute code when a server control (page)
        // that inherits from this base class is initialized.
        public BasePage()
        {
            Init += new EventHandler(BasePage_Init); 
        }


        // Whenever a page that uses this base class is initialized,
        // add meta keywords and descriptions if available
        void BasePage_Init(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(Meta_Keywords))
            {
                HtmlMeta tag = new HtmlMeta();
                tag.Name = "keywords";
                tag.Content = Meta_Keywords;
                Header.Controls.Add(tag);
            }

            if (!String.IsNullOrEmpty(Meta_Description))
            {
                HtmlMeta tag = new HtmlMeta();
                tag.Name = "description";
                tag.Content = Meta_Description;
                Header.Controls.Add(tag);
            }
        }
    }
}

Ответ 3

Наряду с уже упомянутыми метаданными (в основном устарел в ASP.NET 4.0 с новым Page.MetaDescription и Page.MetaKeywords свойства), у меня также были методы добавления другого заголовка ссылки на мою страницу, такие как конкретные для добавления CSS для страницы, или такие вещи, как каннонические ссылки, ссылки на RSS и т.д.:

/// <overloads>
/// Adds a CSS link to the page. Useful when you don't have access to the
///  HeadContent ContentPlaceHolder. This method has 4 overloads.
/// </overloads>
/// <summary>
/// Adds a CSS link.
/// </summary>
/// <param name="pathToCss">The path to CSS file.</param>
public void AddCss(string pathToCss) {
    AddCss(pathToCss, string.Empty);
}

/// <summary>
/// Adds a CSS link in a specific position.
/// </summary>
/// <param name="pathToCss">The path to CSS.</param>
/// <param name="position">The postion.</param>
public void AddCss(string pathToCss, int? position) {
    AddCss(pathToCss, string.Empty, position);
}

/// <summary>
/// Adds a CSS link to the page with a specific media type.
/// </summary>
/// <param name="pathToCss">The path to CSS file.</param>
/// <param name="media">The media type this stylesheet relates to.</param>
public void AddCss(string pathToCss, string media) {
    AddHeaderLink(pathToCss, "text/css", "Stylesheet", media, null);
}

/// <summary>
/// Adds a CSS link to the page with a specific media type in a specific
/// position.
/// </summary>
/// <param name="pathToCss">The path to CSS.</param>
/// <param name="media">The media.</param>
/// <param name="position">The postion.</param>
public void AddCss(string pathToCss, string media, int? position) {
    AddHeaderLink(pathToCss, "text/css", "Stylesheet", media, position);
}

/// <overloads>
/// Adds a general header link. Useful when you don't have access to the
/// HeadContent ContentPlaceHolder. This method has 3 overloads.
/// </overloads>
/// <summary>
/// Adds a general header link.
/// </summary>
/// <param name="href">The path to the resource.</param>
/// <param name="type">The type of the resource.</param>
public void AddHeaderLink(string href, string type) {
    AddHeaderLink(href, type, string.Empty, string.Empty, null);
}

/// <summary>
/// Adds a general header link.
/// </summary>
/// <param name="href">The path to the resource.</param>
/// <param name="type">The type of the resource.</param>
/// <param name="rel">The relation of the resource to the page.</param>
public void AddHeaderLink(string href, string type, string rel) {
    AddHeaderLink(href, type, rel, string.Empty, null);
}

/// <summary>
/// Adds a general header link.
/// </summary>
/// <param name="href">The path to the resource.</param>
/// <param name="type">The type of the resource.</param>
/// <param name="rel">The relation of the resource to the page.</param>
/// <param name="media">The media target of the link.</param>
public void AddHeaderLink(string href, string type, string rel, string media)
{
    AddHeaderLink(href, type, rel, media, null);
}

/// <summary>
/// Adds a general header link.
/// </summary>
/// <param name="href">The path to the resource.</param>
/// <param name="type">The type of the resource.</param>
/// <param name="rel">The relation of the resource to the page.</param>
/// <param name="media">The media target of the link.</param>
/// <param name="position">The postion in the control order - leave as null
/// to append to the end.</param>
public void AddHeaderLink(string href, string type, string rel, string media, 
                          int? position) {
  var link = new HtmlLink { Href = href };

  if (0 != type.Length) {
    link.Attributes.Add(HtmlTextWriterAttribute.Type.ToString().ToLower(), 
                        type);
  }

  if (0 != rel.Length) {
    link.Attributes.Add(HtmlTextWriterAttribute.Rel.ToString().ToLower(),
                        rel);
  }

  if (0 != media.Length) {
    link.Attributes.Add("media", media);
  }

  if (null == position || -1 == position) {
    Page.Header.Controls.Add(link);
  }
  else
  {
    Page.Header.Controls.AddAt((int)position, link);
  }
}

Ответ 4

Размещение кода авторизации на базовой странице, как правило, не является хорошей идеей. Проблема в том, что произойдет, если вы забудете получить страницу, требующую авторизации с базовой страницы? У вас будет дыра в безопасности.

Гораздо лучше использовать HttpModule, чтобы вы могли перехватывать запросы для всех страниц и убедиться, что пользователи авторизованы даже до того, как HttpHandler имеет возможность запускать.

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

Ответ 5

Инициализация культуры путем переопределения метода InitializeCulture() (установить культуру и культуру ui из файла cookie или DB).

Некоторые из моих приложений привлекательны, а затем я тоже делаю некоторые "брендинговые" вещи.

Ответ 6

Я использую этот methot и спасибо за ваш,

/// <summary>
        /// Displays the alert.
        /// </summary>
        /// <param name="message">The message to display.</param>
        protected virtual void DisplayAlert(string message)
        {
            ClientScript.RegisterStartupScript(
                            GetType(),
                            Guid.NewGuid().ToString(),
                            string.Format("alert('{0}');", message.Replace("'", @"\'")),
                            true
                        );
        }

        /// <summary>
        /// Finds the control recursive.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>control</returns>
        protected virtual Control FindControlRecursive(string id)
        {
            return FindControlRecursive(id, this);
        }

        /// <summary>
        /// Finds the control recursive.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="parent">The parent.</param>
        /// <returns>control</returns>
        protected virtual Control FindControlRecursive(string id, Control parent)
        {
            if (string.Compare(parent.ID, id, true) == 0)
                return parent;

            foreach (Control child in parent.Controls)
            {
                Control match = FindControlRecursive(id, child);

                if (match != null)
                    return match;
            }

            return null;
        }

Ответ 7

Я наследую System.Web.UI.Page, когда мне нужны определенные свойства и каждая страница. Это хорошо для приложения aweb, которое реализует логин. На страницах членства я использую свой собственный базовый класс для доступа к свойствам, таким как UserID, UserName и т.д. Эти свойства включают переменные сеанса

Ответ 8

Вот несколько примеров (без кода), которые я использую для базового класса:

  • Добавление фильтра страницы (например, заменить "{theme}" на "~/App_Theme/[currentTheme]" ),
  • Добавление свойства и обработка страниц Auto Titling на основе карты сайта,
  • Регистрация специализированного ведения журнала (возможно, можно переделать с помощью различных средств),
  • Добавление методов для проверки обобщенных входных данных (Form/Querystring) с использованием редиректора: AddRequiredInput ( "WidgetID", PageInputType.QueryString, typeof (string)),
  • Карта сайта Помощники, позволяющие такие вещи, как изменение статического "Редактировать класс" во что-то, связанное с контекстом "Edit Fall" 10 Science 101 "
  • Помощники ViewState, позволяющие мне регистрировать переменную на странице до имени и автоматически заполнять эту переменную из окна просмотра или по умолчанию и сохранять значение обратно в представлении в конце запроса.
  • Custom 404 Redirector, где я могу передать исключение или сообщение (или и то, и другое), и он перейдет на страницу, которую я предопределил, чтобы хорошо отобразить и зарегистрировать ее.

Мне лично нравится # 5 больше всего потому, что: а) обновление SiteMap уродливое, и я предпочитаю не загромождать страницу, что делает ее более читаемой, б) она делает SiteMap гораздо более удобным для пользователя.

Ответ 9

Пожалуйста, обратитесь Получение информации о странице на странице базы данных ASP.Net

public abstract string AppSettingsRolesName { get; }

List<string> authorizedRoles = new List<string>((ConfigurationManager.AppSettings[AppSettingsRolesName]).Split(','))
if (!authorizedRoles.Contains(userRole))
{
Response.Redirect("UnauthorizedPage.aspx");
}

В производной странице

public override string AppSettingsRolesName 
{
  get { return "LogsScreenRoles"; }
}