有什么很酷的功能和方法 您 添加到您的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);
}
- 会话相关的东西,BasePage中映射到会话的一些复杂对象,并将其作为属性公开。
- 做一些像填充碎屑垫物体的东西。
但最重要的是: 不要让你的基页成为一个帮助类。不要添加像 ParseId()
那太荒谬了。
另外,根据第一篇文章:制作类似的东西 IsAuthorized
抽象。这样,如果有人忘记了某些虚拟方法,就不会创建巨大的安全漏洞。
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);
}
}
}
}
连同已经提到的元数据(主要是 在ASP.NET 4.0中已过时 与新的 Page.MetaDescription 和 Page.MetaKeywords 我还有一些方法可以为我的页面添加其他标题链接,例如用于添加页面特定CSS的特定标题链接,或者诸如cannonical链接,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);
}
}
通过覆盖来进行文化初始化 InitializeCulture()
方法(从cookie或DB设置文化和ui文化)。
我的一些应用程序是可品牌化的,然后在这里我做了一些“品牌”的东西。
我用这个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;
}
将授权代码放在基页中通常不是一个好主意。问题是,如果您忘记从基页派生需要授权的页面会发生什么?你会有一个安全漏洞。
使用HttpModule要好得多,这样您就可以拦截所有页面的请求,并确保在HttpHandler有机会运行之前授权用户。
此外,正如其他人所说,并且为了与OO原则保持一致,最好只在基页中使用与页面本身相关的方法。如果他们没有引用“this”,那么他们应该是一个帮助类 - 或者可能是扩展方法。
当我需要某些属性和每个页面时,我从System.Web.UI.Page继承。这对于实现登录的aweb应用程序很有用。在成员资格页面中,我使用自己的基类来访问属性,如UserID,UserName等。这些属性包装会话变量
以下是我使用自定义基类的一些示例(无代码):
- 添加页面过滤器(例如将“{theme}”替换为“〜/ App_Theme / [currentTheme]”),
- 根据站点地图添加属性并处理自动标题页面,
- 注册专门的日志记录(可能通过不同方式重做),
- 使用毯式重定向器添加通用输入(Form / Querystring)验证的方法:AddRequiredInput(“WidgetID”,PageInputType.QueryString,typeof(string)),
- 站点地图帮助程序,允许将静态“编辑类”更改为与“编辑秋季'10科学101”相关的上下文
- ViewState Helpers,允许我将页面上的变量注册到名称,并让它自动从视图状态或默认值填充该变量,并在请求结束时将值保存回viewstate。
- 自定义404重定向器,我可以在其中传递异常或消息(或两者),它将转到我已预定义的页面,以便很好地显示和记录它。
我个人最喜欢#5因为a)更新SiteMap是丑陋的,我不喜欢弄乱页面,使其更具可读性; b)它使SiteMap更加用户友好。
,
请参考 获取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"; }
}