日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[翻译]运用文件解析器在任意文件中使用虚拟应用路径(~)

發(fā)布時(shí)間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [翻译]运用文件解析器在任意文件中使用虚拟应用路径(~) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文出處:http://www.codeproject.com
?? Using the FileResolver to allow virtual application paths ( ~ ) in any file

引言
??? 如果不是很熟悉“~”在ASP.NET中的使用,你總是完全地忽略它。我們的開(kāi)發(fā)環(huán)境經(jīng)常是和成品的服務(wù)器是不同的。我們可以在開(kāi)發(fā)的PC上使用一個(gè)虛擬路徑來(lái)測(cè)試我們的應(yīng)用程序,而使用一個(gè)單獨(dú)的頂級(jí)網(wǎng)址來(lái)發(fā)布。
??? 那么,當(dāng)把image或者link加入到頁(yè)面中的時(shí)候,你總是必須知道提供的路徑的類型——相對(duì)、絕對(duì)等等。在ASP.NET中最好的技巧之一就是使用“~”。它實(shí)質(zhì)上是HttpRuntime.AppDomainAppVirtual屬性的一個(gè)快捷方式,引用的是虛擬應(yīng)用程序的根,而不是web服務(wù)器的根。
??? “~”是快捷、簡(jiǎn)潔的,同時(shí)也十分受限制。比如,僅僅在設(shè)置那些Render之前知道怎么解析路徑的控件的一些路徑相關(guān)屬性時(shí),它是有用的。它只是在ASP.NET的預(yù)定義范圍內(nèi)有用,絕對(duì)不能使用在ASP.NET的控管外的文件中。至少目前還是這樣。
??? 我經(jīng)常碰上的問(wèn)題之一是:在非ASP.NET文件(如css文件)中設(shè)定一個(gè)路徑。比如,我想在css文件中設(shè)定一個(gè)樣式的背景(background-image)屬性時(shí),除非我使用一個(gè)相對(duì)路徑,否則將是很頭疼的事情。我通常的解決方法是直接增加背景屬性到頁(yè)面的標(biāo)簽里面而不是一個(gè)css文件里,我是首先承認(rèn)這種做法是不令人滿意的人。
??? 兩個(gè)解決辦法在我的腦海中浮現(xiàn)。在結(jié)合它們之后,我構(gòu)建了一個(gè)可靠的解決方案。我的思路包括使用一個(gè)HTTP處理機(jī)來(lái)截取任何資源請(qǐng)求,諸如css、js文件等等。該處理機(jī)負(fù)責(zé)分析上述的那些資源文件并且將解析后的文件返回給客戶端。

基礎(chǔ)
??? 本文假定你對(duì)HTTP處理機(jī)有初步的了解。

代碼的使用
??? 針對(duì)本文,我打算用css文件來(lái)作為例子,當(dāng)然這個(gè)技術(shù)也可以很容易的應(yīng)用到任何其他需要處理的文件類型上。
??? 假設(shè)當(dāng)前有如下一個(gè)標(biāo)簽在a.aspx頁(yè)面中來(lái)鏈接一個(gè)樣式表。
?<link rel="stylesheet" href="resources/stylesheet.css" />
??? 一旦我實(shí)現(xiàn)了上面所述的解決方案,上面的標(biāo)簽將改成如下:
?<link rel="stylesheet" href="~/resources/stylesheet.css.ashx" />
??? 正如你所見(jiàn)到的,在文件路徑上有一個(gè)小小的附加后綴“.ashx”,這是為了告訴文件解析器,需要解析css文件中任何的虛擬路徑。
??? 另外一個(gè)小小的變化是我們?cè)赾ss文件的路徑上使用了“~”。一會(huì)你將看到HTTP處理機(jī)會(huì)自動(dòng)地解析這個(gè)css文件路徑。然而,它似乎不適用于ASP.NET1.1的場(chǎng)合,因此對(duì)于ASP.NET1.1,你可能必須使用一個(gè)真實(shí)的相對(duì)或絕對(duì)路徑。
??? 那么,讓我們關(guān)注一下文件解析器的代碼。
namespace FileResolverDemoWeb
{
??? public class FileResolver : IHttpHandler
??? {
??????? /// <summary>
??????? /// File cache item used to store file
??????? /// content & date entered into cache
??????? /// </summary>
??????? internal class FileCacheItem
??????? {
??????????? internal string Content;
??????????? internal DateTime DateEntered = DateTime.Now;

??????????? internal FileCacheItem(string content)
??????????? {
??????????????? this.Content = content;
??????????? }
??????? }

??????? private FileCacheItem UpdateFileCache(HttpContext context,
????????????????????????????????????????????????? string filePath)
??????? {
??????????? string content;

??????????? using(FileStream fs = new FileStream(filePath,
???????????????????????????? FileMode.Open, FileAccess.Read))
??????????? {
??????????????? using(StreamReader sr = new StreamReader(fs))
??????????????? {
??????????????????? content = sr.ReadToEnd();
??????????????????? sr.Close();
??????????????? }

??????????????? fs.Close();
??????????? }

??????????? //Get absolute application path
??????????? string relAppPath = HttpRuntime.AppDomainAppVirtualPath;
??????????? if(!relAppPath.EndsWith("/"))
??????????????? relAppPath += "/";

??????????? //Replace virtual paths w/ absolute path
??????????? content = content.Replace("~/", relAppPath);

??????????? FileCacheItem ci = new FileCacheItem(content);

??????????? //Store the FileCacheItem in cache
??????????? //w/ a dependency on the file changing
??????????? CacheDependency cd = new CacheDependency(filePath);
??????????? context.Cache.Insert(filePath, ci, cd);
??????????? return ci;
??????? }

??????? public void ProcessRequest(HttpContext context)
??????? {
??????????? string absFilePath =
??????????????? context.Request.PhysicalPath.Replace(".ashx", "");
???????????
??????????? //If a tilde was used in the page
??????????? //to this file, replace it w/ the app path
??????????? if(absFilePath.IndexOf("~\\") > -1)
??????????????? absFilePath = absFilePath.Replace("~",
????????????????????????????? "").Replace("\\\\", "\\");

??????????? if(!File.Exists(absFilePath))
??????????? {
??????????????? context.Response.StatusCode = 404;
??????????????? return;
??????????? }

??????????? FileCacheItem ci = (FileCacheItem)context.Cache[absFilePath];
??????????? if(ci != null)
??????????? {
??????????????? if(context.Request.Headers["If-Modified-Since"] != null)
??????????????? {
??????????????????? try
??????????????????? {
??????????????????????? DateTime date = DateTime.Parse(
????????????????????????? context.Request.Headers["If-Modified-Since"]);

??????????????????????? if(ci.DateEntered.ToString() == date.ToString())
??????????????????????? {
??????????????????????????? //Don't do anything, nothing
??????????????????????????? //has changed since last request
??????????????????????????? context.Response.StatusCode = 304;
??????????????????????????? context.Response.StatusDescription =
???????????????????????????????????????????????? "Not Modified";
??????????????????????????? context.Response.End();
??????????????????????????? return;
??????????????????????? }
??????????????????? }
??????????????????? catch(Exception){}
??????????????? }
??????????????? else
??????????????? {
??????????????????? //In the event that the browser doesn't
??????????????????? //automatically have this header, add it
??????????????????? context.Response.AddHeader("If-Modified-Since",
??????????????????????????????????????? ci.DateEntered.ToString());
??????????????? }
??????????? }
??????????? else
??????????? {
??????????????? //Cache item not found, update cache
??????????????? ci = UpdateFileCache(context, absFilePath);
??????????? }

??????????? context.Response.Cache.SetLastModified(ci.DateEntered);
??????????? context.Response.ContentType = "text/" +
??????????????????? GetContentType(Path.GetExtension(absFilePath));
??????????? context.Response.Write(ci.Content);
??????????? context.Response.End();
??????? }

??????? /// <summary>
??????? /// Gets the appropriate content type for a specified extension
??????? /// </summary>
??????? private string GetContentType(string ext)
??????? {
??????????? switch(ext.ToLower())
??????????? {
??????????????? case ".css":
??????????????????? return "css";
??????????????????? break;
??????????????? case ".xml":
??????????????????? return "xml";
??????????????????? break;
??????????????? case ".js":
??????????????????? return "javascript";
??????????????????? break;
??????????????? default:
??????????????????? return "plain";
??????????????????? break;
??????????? }
??????? }

??????? #region IHttpHandler Members

??????? public bool IsReusable
??????? {
??????????? get
??????????? {
??????????????? return true;
??????????? }
??????? }

??????? #endregion
??? }
}
??? 我們來(lái)分析一下上面的代碼。
??? CacheItem是一個(gè)獲取css文件中要解析內(nèi)容的一個(gè)內(nèi)部類。它有一個(gè)DateEntered屬性,用于記錄內(nèi)容最后被更新的時(shí)間。它將決定我們是否需要提供一個(gè)新的css文件內(nèi)容給客戶端。
??? ProcessRequest是一個(gè)繼承IHttpHander接口時(shí)必須實(shí)現(xiàn)的方法,方法里包含了大部分處理機(jī)的處理邏輯。在ProcessRequest方法中,我們從HttpContext.Request.PhysicalPath屬性來(lái)獲取要處理的文件。我們做個(gè)初步檢查來(lái)確保文件路徑已經(jīng)被解析。一旦我們獲得文件的映射實(shí)際路徑,我們?cè)贆z查一下確保文件在文件系統(tǒng)中是否存在。
string absFilePath = context.Request.PhysicalPath.Replace(".ashx", "");

//If a tilde was used in the page to this file, replace it w/ the app path
if(absFilePath.IndexOf("~\\") > -1)
??? absFilePath = absFilePath.Replace("~", "").Replace("\\\\", "\\");

if(!File.Exists(absFilePath))
{
??? context.Response.StatusCode = 404;
??? return;
}
??? 一旦文件證實(shí)存在,我們需要檢查頁(yè)面緩存,看看是否有一個(gè)相關(guān)的CacheItem已經(jīng)加入,如果這是這個(gè)css文件的首次請(qǐng)求,那么我們將創(chuàng)建并儲(chǔ)存一個(gè)CacheItem。
??? 如果CacheItem已經(jīng)存在,我們比較DateEntered和來(lái)自請(qǐng)求頭If-Modified-Since的值,如果日期匹配,那么我們知道客戶端有著該文件最新的緩存,如果日期不是匹配的或者沒(méi)有找到請(qǐng)求頭,我們就試著加入請(qǐng)求頭并且將新的內(nèi)容返回給客戶端。
FileCacheItem ci = (FileCacheItem)context.Cache[absFilePath];
if(ci != null)
{
??? if(context.Request.Headers["If-Modified-Since"] != null)
??? {
??????? try
??????? {
??????????? DateTime date = DateTime.Parse(
???????????????? context.Request.Headers["If-Modified-Since"]);

??????????? if(ci.DateEntered.ToString() == date.ToString())
??????????? {
??????????????? //Don't do anything, nothing has
??????????????? //changed since last request
??????????????? context.Response.StatusCode = 304;
??????????????? context.Response.StatusDescription = "Not Modified";
??????????????? context.Response.End();
??????????????? return;
??????????? }
??????? }
??????? catch(Exception){}
??? }
??? else
??? {
??????? //In the event that the browser doesn't
??????? //automatically have this header, add it
??????? context.Response.AddHeader("If-Modified-Since",
??????????????????????????? ci.DateEntered.ToString());
??? }
}
else
{
??? //Cache item not found, update cache
??? ci = UpdateFileCache(context, absFilePath);
}

context.Response.Cache.SetLastModified(ci.DateEntered);
context.Response.ContentType = "text/" +
??????? GetContentType(Path.GetExtension(absFilePath));
context.Response.Write(ci.Content);
context.Response.End();
??? 如果CacheItem沒(méi)有找到,我們需要用一個(gè)新的CacheItem更新緩存。這包括從css文件中讀取內(nèi)容和用真實(shí)路徑代替所有出現(xiàn)的“~”兩個(gè)步驟。之后,我們將新的內(nèi)容封裝到一個(gè)CacheItem中并且儲(chǔ)存它到頁(yè)面緩存中。
private FileCacheItem UpdateFileCache(HttpContext context,
????????????????????????????????????????? string filePath)
{
??? string content;

??? using(FileStream fs = new FileStream(filePath,
????????????????????????? FileMode.Open, FileAccess.Read))
??? {
??????? using(StreamReader sr = new StreamReader(fs))
??????? {
??????????? content = sr.ReadToEnd();
??????????? sr.Close();
??????? }

??????? fs.Close();
??? }

??? //Get absolute application path
??? string relAppPath = HttpRuntime.AppDomainAppVirtualPath;
??? if(!relAppPath.EndsWith("/"))
??????? relAppPath += "/";

??? //Replace virtual paths w/ absolute path
??? content = content.Replace("~/", relAppPath);

??? FileCacheItem ci = new FileCacheItem(content);

??? //Store the FileCacheItem in cache
??? //w/ a dependency on the file changing
??? CacheDependency cd = new CacheDependency(filePath);
??? context.Cache.Insert(filePath, ci, cd);
??? return ci;
}
??? 至此,我們就基本完成了文件解析器。和所有處理機(jī)一樣,它需要在你的web.config中加入一個(gè)附加的條目才能工作。不僅這個(gè)是必要的,而且我們還要做一些小小的設(shè)定來(lái)擴(kuò)展文件解析器,使之支持任何我們所需的文件類型。
<configuration>
??? <system.web>
??????? <httpHandlers>
??????????? <add verb="GET" path="*.css.ashx"
????????????????? type="FileResolverDemoWeb.FileResolver,FileResolverDemoWeb" />
??????????? <add verb="GET" path="*.js.ashx"
????????????????? type="FileResolverDemoWeb.FileResolver,FileResolverDemoWeb" />
??????? </httpHandlers>
??? </system.web>
</configuration>
??? 在這個(gè)場(chǎng)景里面,我解析了css和js文件。

(以下略,翻譯水平有限,歡迎大家指正,如有需要請(qǐng)看原文)
tag: asp.net ~ 文件解析器 路徑

?

轉(zhuǎn)載于:https://www.cnblogs.com/luyuliang/archive/2006/09/23/512588.html

總結(jié)

以上是生活随笔為你收集整理的[翻译]运用文件解析器在任意文件中使用虚拟应用路径(~)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。