转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 站长学院 >> Web开发 >> 正文
在 WinForm 中完整支持在多级目录中保存的 ASP.NET (转)         ★★★★

在 WinForm 中完整支持在多级目录中保存的 ASP.NET (转)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1751 更新时间:2009/4/23 10:45:51
Request() {
    // wait for at least some input
    if (WaitForRequestBytes() == 0) { // 等待客户端请求数据
      WriteErrorAndClose(400); // 发送 HTTP 400 错误给客户端
      return;
    }

    Request request = new Request(_host, this);
    request.Process();
  }

  private int WaitForRequestBytes() {
    int availBytes = 0;

    try {
      if (_socket.Available == 0) {
        // poll until there is data
        _socket.Poll(100000 /* 100ms */, SelectMode.SelectRead); // 等待客户端数据 100ms 时间
        if (_socket.Available == 0 && _socket.Connected)
          _socket.Poll(10000000 /* 10sec */, SelectMode.SelectRead);
      }

      availBytes = _socket.Available;
    }
    catch {
    }

    return availBytes;
  }


    [6] Request 在接收到 Connection 的请求后,将从客户端读取请求内容,并按照 HTTP 协议进行分析。因为本文不是做 HTTP 协议的分析工作,所以这部分代码就不详细讨论了。
    在 Request.ParseRequestLine 函数分析 HTTP 请求获得请求页面路径后,会调用前面提到过的 Host.IsVirtualPathInApp 函数判断此路径是否在 Web 服务器提供的虚拟路径下级,并且返回此虚拟路径是否指向 ASP.NET 的客户端脚本。如果 Web 请求的虚拟路径以 "/" 结尾,则调用 Request.ProcessDirectoryListingRequest 方法返回列目录的响应;否则调用 HttpRuntime.ProcessRequest 方法完成实际的 ASP.NET 请求处理工作。
    HttpRuntime 通过 Request 的基类 HttpWorkerRequest 提供的统一接口,采用 IoC 的策略获取最终页面的所在。与我前面文章中使用的 SimpleWorkerRequest 实现最大不同在于 Request.MapPath 完成了一个较为完整的虚拟目录到物理目录映射机制。
    SimpleWorkerRequest.MapPath 实现相对简陋:
以下内容为程序代码:

public override string SimpleWorkerRequest.MapPath(string path)
{
  if (!this._hasRuntimeInfo)
  {
    return null;
  }

  string physPath = null;
  string appPhysPath = this._appPhysPath.Substring(0, (this._appPhysPath.Length - 1)); // 去掉末尾斜杠

  if (((path == null) || (path.Length == 0)) || path.Equals("/"))
  {
    physPath = appPhysPath;
  }

  if (path.StartsWith(this._appVirtPath))
  {
    physPath = appPhysPath + path.Substring(this._appVirtPath.Length).Replace(''''/'''', ''''\'''');
  }

  InternalSecurityPermissions.PathDiscovery(physPath).Demand();

  return physPath;
}

    Request.MapPath 的实现则相对要完善许多,考虑了很多 SimpleWorkerRequest 无法处理的情况,使得 Request 的适应性更强。
以下内容为程序代码:

public override String Request.MapPath(String path) {
  String mappedPath = String.Empty;

  if (path == null || path.Length == 0 || path.Equals("/")) {
    // asking for the site root
    if (_host.VirtualPath == "/") {
      // app at the site root
      mappedPath = _host.PhysicalPath;
    }
    else {
      // unknown site root - don''''t point to app root to avoid double config inclusion
      mappedPath = Environment.SystemDirectory;
    }
  }
  else if (_host.IsVirtualPathAppPath(path)) {
    // application path
    mappedPath = _host.PhysicalPath;
  }
  else if (_host.IsVirtualPathInApp(path)) {
    // inside app but not the app path itself
    mappedPath = _host.PhysicalPath + path.Substring(_host.NormalizedVirtualPath.Length);
  }
  else {
    // outside of app -- make relative to app path
    if (path.StartsWith("/"))
      mappedPath = _host.PhysicalPath + path.Substring(1);
    else
      mappedPath = _host.PhysicalPath + path;
  }

  mappedPath = mappedPath.Replace(''''/'''', ''''\'''');

  if (mappedPath.EndsWith("\") && !mappedPath.EndsWith(":\"))
    mappedPath = mappedPath.Substring(0, mappedPath.Length-1);

  return mappedPath;
}


    关于 Cassini 的进一步讨论,可以参考 www.asp.net 上的讨论专版。

    [7] 在 HttRuntime 完成具体的 ASP.NET 页面处理工作后,会通过 Request.SendResponseFromXXX 系列函数,将页面结果返回给客户端。

    虽然 SimpleWorkerRequest.MapPath 方法实现简单,但理论上完全可以处理多级目录的情况。之所以在使用 SimpleWorkerRequest 时,无法处理嵌套目录,是因为 SimpleWorkerRequest 在构造函数中错误地分解了请求的页面所在虚拟目录等信息。
    SimpleWorkerRequest 的两个构造函数,在将请求页面虚拟路径(如"/help/about.aspx")保存后,都调用了 ExtractPagePathInfo 方法对页面路径做进一步的分解工作。
以下内容为程序代码:

private void SimpleWorkerRequest.ExtractPagePathInfo()
{
  int idx = this._page.IndexOf(''''/'''');
  if (idx >= 0)
  {
    this._pathInfo = this._page.Substring(idx);
    this._page = this._page.Substring(0, idx);
  }
}

    this._pathInfo 是为实现 HttpWorkerRequest.GetPathInfo 提供的存储字段。而 GetPathInfo 将返回 URL 中在页面后的路径信息,例如对 "path/virdir/page.html/tail" 将返回 "/tail"。早期的许多 HTTP 客户端程序,如 Delphi 中 WebAction 的分发,都利用了这个路径信息的特性,在 Web 页面或 ISAPI 一级之后,再次进行请求分发。但因为 SimpleWorkerRequest 实现上或者设计上的限制,导致在处理 PathInfo 时会将 "/help/about.aspx" 类似的多级 url 错误切断。最终返回给 HttpRuntime 的 this._path 将变成空字符串,而 this._pathInfo 被设置为 "/help/about.aspx",而单级路径如 "about.aspx" 不受影响。
    知道了这个原理后,就可以对 SimpleWorkerRequest 稍作修改,重载受到 ExtractPagePathInfo 影响的几个方法,即可完成对多级目录结构下页面的支持。如果需要进一步的映射支持,如同时支持多个虚拟子目录,可以参照 Cassini 的 Request 实现 MapPath 等方法。
以下内容为程序代码:

public class Request : SimpleWorkerRequest
{
  private string _appPhysPath;
  private string _appVirtPath;

  private string _page;
  private string _pathInfo;

  public Request(string page, string query, TextWriter output) : base(page, query, output)
  {
    this._appPhysPath = Thread.GetDomain().GetData(".appPath").ToString();
    this._appVirtPath = Thread.GetDomain().GetData(".hostingVirtualPath").ToString();

    this._page = page;

    // TODO: 从 page 中进一步解析 Path Info
  }

  public override string GetPathInfo()
  {
    if (this._pathInfo == null)
    {
      return string.Empty;
    }
    return this._pathInfo;
  }

  private string GetPathInternal(bool includePathInfo)
  {
    string path = (_appVirtPath.Equals("/") ? _page : _appVirtPath + _page);

    if (includePathInfo && (_pathInfo != null))
    {
      return path + this._pathInfo;
    }
    else
    {
      return path;
    }
  }

  public override string GetUriPath()

上一页  [1] [2] [3]  下一页


[C语言系列]C# WinForm 中Label自动换行 解决方法  [电脑应用]c# winform 打包部署 自定义界面 或设置开机启动
[电脑应用]C# WinForm 关闭登陆窗体,打开主窗体的实现  [C语言系列]winform datagridview如何获取选中行的索引
[C语言系列]c# _winform实现网页上用户自动登陆,模拟网站登录  [C语言系列]C#的winform中实现tabPage的隐藏 .
[C语言系列]C# WinForm中Application.StartupPath与AppDomain…  [系统软件]WinForm 程序实现XP风格
[常用软件]双剑合璧 在Win XP下刻录音乐CD  [VB.NET程序]使用VB.Net做一个配置web.config功能的WinForm(原…
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Web开发  · 网页制作
    · 平面设计  · 网站运营
    · 网站推广  · 搜索优化
    · 建站心得  · 站长故事
    · 互联动态
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台