• asp.net Forums 之HttpHandler和HttpModule


    我们先说说IHttpHandler和IHttpModule这两个接口。
    微软的解释为:
    IHttpHandler: 定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。 
    IHttpModule: 向继承类提供模块初始化和处置事件。 
    有点看不懂,微软的解释一向如此。

    那我们来看看代码:
    public interface IHttpHandler
    {
     bool IsReusable { get; }
     void ProcessRequest(HttpContext context);
    }
    IsReusable获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
    ProcessRequest()方法是处理请求的,System.Web.HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。

    public interface IHttpModule
    {
     void Dispose();
     void Init(HttpApplication context);
    }

    Dispose()方法用于释放资源。
    Init()方法初始化这个HttpApplication,你可以在这时注册各类事件,如:Application_BeginRequest,Application_AuthenticateRequest,Application_OnError等。

    那IHttpHandler与IHttpModule有什么区别呢:
    1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行的,一些是在Handler之后运行的
    2.对请求的处理上:
    IHttpModule是属于大小通吃类型,无论客户端请求的是什么文件,都会调用到它;例如aspx,rar,html的请求.
    IHttpHandler则属于挑食类型,只有ASP.net注册过的文件类型(例如aspx,asmx等等)才会轮到调用它.
    3.IHttpHandler按照你的请求生成响应的内容,IHttpModule对请求进行预处理,如验证、修改、过滤等等,同时也可以对响应进行处理    HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。
        HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

    接下来,我们再来看看ANF中的IHttpModule和IHttpHandler。
    ForumsHttpModule类是ANF中自定义的HttpModule,它位于AspNetForums命名空间下。
    在这个HttpModule中,自定义了

    代码
    /// <summary>
    /// 应用程序初始化
    /// </summary>
    /// <param name="application"></param>
    public void Init(HttpApplication application)
    {
    // Wire-up application events
    //
    application.BeginRequest += new EventHandler(this.Application_BeginRequest);
    application.AuthenticateRequest
    += new EventHandler(Application_AuthenticateRequest);
    application.Error
    += new EventHandler(this.Application_OnError);
    application.AuthorizeRequest
    += new EventHandler(this.Application_AuthorizeRequest);

    #if DEBUG
    application.ReleaseRequestState
    += new EventHandler(this.Application_ReleaseRequestState);
    #endif

    ForumConfiguration forumConfig
    = ForumConfiguration.GetConfig();
    if (forumConfig != null
    && forumConfig.IsBackgroundThreadingDisabled == false)
    {
    if (emailTimer == null)
    emailTimer
    = new Timer(new TimerCallback(ScheduledWorkCallbackEmailInterval), application.Context, EmailInterval, EmailInterval);

    if (forumConfig.IsIndexingDisabled == false
    && statsTimer == null)
    {
    statsTimer
    = new Timer(new TimerCallback(ScheduledWorkCallbackStatsInterval), application.Context, StatsInterval, StatsInterval);
    }
    }
    }


    应用程序错误处理 Application_OnError

    代码
    private void Application_OnError(Object source, EventArgs e)
    {
    ForumConfiguration forumConfig
    = ForumConfiguration.GetConfig();
    string defaultLanguage = forumConfig.DefaultLanguage;
    HttpApplication application
    = (HttpApplication) source;
    HttpContext context
    = application.Context;
    ForumException forumException;
    string html;
    StreamReader reader;
    // 增加异常信息不同级别显示--开始
    // 如果为管理员,显示异常详细信息 by venjiang 2004-11-3
    // 发布时注释此代码
    // if(Users.GetUser().IsAdministrator)
    // {
    // context.Response.Write(context.Server.GetLastError().Message);
    // return;
    // }

    // 增加异常信息不同级别显示--结束

    if (context.Server.GetLastError().GetBaseException() is ForumException)
    {
    forumException
    = (ForumException) context.Server.GetLastError().GetBaseException();

    switch (forumException.ExceptionType)
    {
    case ForumExceptionType.DataProvider:

    // We can't connect to the data store
    //
    reader = new StreamReader(context.Server.MapPath("~/Languages/" + defaultLanguage + "/errors/DataStoreUnavailable.htm"));
    html
    = reader.ReadToEnd();
    reader.Close();

    html
    = html.Replace("[DATASTOREEXCEPTION]", forumException.Message);
    context.Response.Write(html);
    context.Response.End();
    break;

    case ForumExceptionType.UserInvalidCredentials:
    forumException.Log();
    break;

    case ForumExceptionType.AccessDenied:
    forumException.Log();
    break;

    case ForumExceptionType.AdministrationAccessDenied:
    forumException.Log();
    break;

    case ForumExceptionType.ModerateAccessDenied:
    forumException.Log();
    break;

    case ForumExceptionType.PostDeleteAccessDenied:
    forumException.Log();
    break;

    case ForumExceptionType.PostProblem:
    forumException.Log();
    break;

    case ForumExceptionType.UserAccountBanned:
    forumException.Log();
    break;

    // LN 6/9/04: New exception added
    case ForumExceptionType.ResourceNotFound:
    //context.Response.Write(context.Server.GetLastError().Message);
    forumException.Log();
    break;

    case ForumExceptionType.UserUnknownLoginError:
    forumException.Log();
    break;
    }
    }
    else
    {
    forumException
    = new ForumException(ForumExceptionType.UnknownError, context.Server.GetLastError().Message, context.Server.GetLastError());
    forumException.Log();
    }

    if (forumException.ExceptionType == ForumExceptionType.UnknownError)
    {
    if ((context.IsCustomErrorEnabled) && (!context.Request.Url.IsLoopback))
    ForumContext.RedirectToMessage(context, forumException);
    }
    else
    {
    //context.Response.Write(context.Server.GetLastError().Message);
    ForumContext.RedirectToMessage(context, forumException);
    }
    }

    当安全模块已建立用户标识时发生 Application_AuthenticateRequest

    代码
    private void Application_AuthenticateRequest(Object source, EventArgs e)
    {
    HttpContext context
    = HttpContext.Current;
    Provider p
    = null;
    ExtensionModule module
    = null;

    // Only continue if we have a valid context
    //
    if ((context == null) || (context.User == null))
    return;


    try
    {
    // Logic to handle various authentication types
    //
    switch (context.User.Identity.AuthenticationType.ToLower())
    {
    // Microsoft passport
    case "passport":
    p
    = (Provider) ForumConfiguration.GetConfig().Extensions["PassportAuthentication"];
    module
    = ExtensionModule.Instance(p);

    module.ProcessRequest();
    break;

    // Windows
    case "negotiate":
    p
    = (Provider) ForumConfiguration.GetConfig().Extensions["WindowsAuthentication"];
    module
    = ExtensionModule.Instance(p);

    module.ProcessRequest();
    break;

    default:
    ForumContext.Current.UserName
    = context.User.Identity.Name;
    break;

    }

    }
    catch (Exception ex)
    {
    ForumException forumEx
    = new ForumException(ForumExceptionType.UnknownError, "Error in AuthenticateRequest", ex);
    forumEx.Log();

    throw forumEx;
    }

    // 获取用户角色
    Roles roles = new Roles();
    roles.GetUserRoles();
    }

    验证用户授权 Application_AuthorizeRequest

    代码
    private void Application_AuthorizeRequest(Object source, EventArgs e)
    {
    HttpApplication application
    = (HttpApplication) source;
    HttpContext context
    = application.Context;

    // Track anonymous users
    //
    Users.TrackAnonymousUsers();

    // Do we need to force the user to login?
    //
    if (Users.GetUser().ForceLogin)
    {
    Moderate.ToggleUserSettings(ModerateUserSetting.ToggleForceLogin, Users.GetUser(),
    0);
    context.Response.Redirect(Globals.GetSiteUrls().Logout,
    true);
    }


    }

    响应应用程序请求开始事件 Application_BeginRequest

    代码
    private void Application_BeginRequest(Object source, EventArgs e)
    {
    if (HttpContext.Current.Request.Path.IndexOf('\\') >= 0 ||
    Path.GetFullPath(HttpContext.Current.Request.PhysicalPath)
    != HttpContext.Current.Request.PhysicalPath)
    {
    throw new HttpException(404, "not found");
    }

    //2005-6-25
    //阻止IP访问

    //

    try
    {
    HttpApplication application
    = (HttpApplication) source;
    HttpContext context
    = application.Context;

    if (application == null
    || context == null)
    return;

    // Url Rewriting

    string newPath = null;
    string path = context.Request.Path;
    string query = context.Request.Url.Query;
    bool isReWritten = RewriteUrl(path, query, out newPath);

    if (isReWritten && newPath != null)
    context.RewritePath(newPath);

    ForumContext frmContext
    = CreateForumContext(context);
    frmContext.CurrentUrl
    = context.Request.RawUrl.ToString();


    // 2005/04/07
    //safe to set url rewrite data;
    if (isReWritten && newPath != null)
    {
    frmContext.IsUrlReWritten
    = true;
    }

    // Capture any pingback information
    //
    CaptureForumPingback();

    // Are the forums disabled?
    //
    if ((Globals.GetSiteSettings().ForumsDisabled) && (HttpContext.Current.Request.Url.Host != "localhost"))
    {
    ForumConfiguration forumConfig
    = ForumConfiguration.GetConfig();
    string defaultLanguage = forumConfig.DefaultLanguage;

    // Forums is disabled
    //
    StreamReader reader = new StreamReader(context.Server.MapPath("~/Languages/" + defaultLanguage + "/errors/ForumsDisabled.htm"));
    string html = reader.ReadToEnd();
    reader.Close();

    context.Response.Write(html);
    context.Response.End();

    }
    }
    catch (Exception ex)
    {
    ForumException forumEx
    = new ForumException(ForumExceptionType.UnknownError, "Unknown error in BeginRequest", ex);
    forumEx.Log();
    }

    if (HttpContext.Current.Request.Path.ToLower().IndexOf("msgs/default") < 0)
    {
    if (BlockedIpAddresses.AddressIsBlocked(Globals.IPAddress))
    throw new ForumException(ForumExceptionType.BlockedIpAddress);
    }


    }

    等事件。
    在Web.Config文件中配置

    <!-- 指定应用程序HttpModule -->
    <httpModules>
    <add name="AspNetForums" type="AspNetForums.ForumsHttpModule, AspNetForums.Components" />
    </httpModules>

    AvatarHttpHandler类是ANF中的自定义HttpHandler,它位于AspNetForums.Components.HttpHandler命名空间下。
    这个HttpHandler主要用于处理用户头像的处理。

    代码
    public void ProcessRequest(HttpContext context)
    {
    try
    {
    Avatar userAvatar
    = Resources.GetAvatar(int.Parse(context.Request.QueryString["UserID"]));

    context.Response.ContentType
    = userAvatar.ContentType;
    context.Response.OutputStream.Write(userAvatar.Content,
    0, userAvatar.Length);

    context.Response.Cache.SetCacheability(HttpCacheability.Public);
    // Terry Denham 7/16/2004
    // changing default cache for avatars from 1 day to 30 minutes
    context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
    context.Response.Cache.SetAllowResponseInBrowserHistory(
    true);
    context.Response.Cache.SetValidUntilExpires(
    true);
    context.Response.Cache.VaryByParams[
    "UserID"] = true;
    }
    catch
    {
    }

    }


    在Web.Config文件中的配置。

    代码
    <!-- 指定应用程序HttpHandlers -->
    <httpHandlers>
    <add verb="GET" path="avatar.aspx" type="AspNetForums.Components.HttpHandler.AvatarHttpHandler, AspNetForums.Components" />
    <add verb="GET" path="vcard.aspx" type="AspNetForums.Components.HttpHandler.VCardHttpHandler, AspNetForums.Components" />

     注: 本文引用了网络上的一些资料。

  • 相关阅读:
    channel 功能解析
    Docker 使用 Jenkins 镜像创建容器(转)
    使用Gson将Object转String出现u003d 的原因
    Gradle基础
    JAVA HashMap 和 HashSet 的区别
    ViewStub基本用法
    String类的内存分配
    区块链--资产数字化之路
    选择排序
    冒泡排序
  • 原文地址:https://www.cnblogs.com/Jesong/p/1751598.html
Copyright © 2020-2023  润新知