CSSファイルでのASP.NET MVC URL自動解決
-
04-07-2019 - |
質問
通常のWebFormsシナリオでは、ルート相対URL(例:〜/ folder / file.txt) inside などのCSSファイル:
.form { background-image: url(~/Content/Images/form_bg.gif); }
指定すると、実行時に自動的に解決されます
<head runat="server">
参照ページ内。
ただし、ASP.NET MVC Beta1 Webサイトではもう発生していません。
ハッキングやCSSローダーファイルに頼らずにこの機能を有効にできる方法はありますか?たぶんHttpModulesのようなものですか?
または、ウェブサイトを正しく設計していませんか?良いデザインとは何ですか?
元のASP.NET WebFormsには既にこの機能があるため、可能であれば既存の機能を利用したいと思います。しかし、あまり手がかりがありません。
このWebアプリケーションは、〜ルートフォルダーが明らかでないいくつかの環境にデプロイされます。
編集:ファイルのコンテンツ自体のURLではなく、ファイルのURLそのものです。
解決
自動ルート検索の〜
文字は気にしません。ルートディレクトリがデプロイメント間で異なる場合でも同じソリューションが機能することを望んでいますが、CSSドキュメント内では相対パスを使用しても問題はないはずです。 CSSドキュメントのパス(例の画像URLへのパス)は、CSSファイルを読み込むページのパスに関係なく、常にCSSファイルの場所に相対的です。したがって、画像が〜/ Content / Images
にあり、スタイルシートが〜/ Content / Stylesheets
にある場合、常に background-imageを使用できます。 :url(../ Images / form_bg.gif);
そして、スタイルシートをロードするページの場所に関係なく動作します。
これが機能しない理由はありますか?
他のヒント
過去に使用した1つのトリックは、CSSファイルに実際に.ASPX拡張子を付け、ページ署名にContentTypeプロパティを設定することでした:
<%@ Page Language="C#" ContentType="text/css" %>
body {
margin: 0;
padding: 0;
background: #C32605 url(<%= ResolveUrl("~/Content/themes/base/images/BodyBackground.png") %>) repeat-x;
font-family: Verdana, Arial, sans-serif;
font-size: small;
color: #d7f9ff;
}
これにより、CSSファイルがASP.NETフレームワークを通過し、サーバー側のコードが相対パスに置き換えられます。
ここ are 一部 リソース IHttpModuleの実装に関するアプリへのWebリクエストをインターセプトします...
ファイルタイプを確認するために1つを作成/調整します(例:擬似コード:if(リクエストが&quot; .css&quot;で終わる)...)
その後、正規表現を使用して&quot;〜/&quot;のすべてのインスタンスを置き換えます。 System.Web.VirtualPathUtility.ToAbsolute(&quot;〜/&quot;)
これがパフォーマンスにどのように影響するかわかりません。この種のフィルターを介してすべてのリクエストを実行しますが、おそらくweb.configファイルやMVC URLルートをいじってすべての.cssリクエストを処理できます。この種類のフィルターは、他のファイルではスキップします。
考えてみてください。ASP.NETMVCアプリ内で、すべてのCSS参照をこの種の前処理を実行する特別なcontroller.actionに向けることで、おそらく同じ効果を実現できます。ただし、IHttpModuleほどパフォーマンスが高いとは思いません。
テキストファイルやjavascriptなどのファイルから〜/ を解析しようとしている場合は、フィルターを割り当てるハンドラーを記述し、それを使用してそれらのパスを検索します...例えば...
public class StringParsingFilter : MemoryStream {
public Stream OriginalStream {
get { return this.m_OriginalStream; }
set { this.m_OriginalStream = value; }
}
private System.IO.Stream m_OriginalStream;
public StringParsingFilter() : base() {
this.m_OriginalStream = null;
}
public override void Flush() {
this.m_OriginalStream.Flush();
}
public override void Write(byte[] buffer, int offset, int count) {
//otherwise, parse for the correct content
string value = System.Text.Encoding.Default.GetString(buffer);
string contentType = HttpContext.Current.Response.ContentType;
//Do any parsing here
...
//write the new bytes to the stream
byte[] bytes = System.Text.Encoding.Default.GetBytes(value);
this.m_OriginalStream.Write(bytes, offset, count + (bytes.Length - buffer.Length));
}
}
そして、次のように、このフィルターをいつ割り当てるかを知るためのカスタムハンドラーを作成します...
public class FilterControlModule : IHttpModule {
public void Init(HttpApplication context) {
HttpApplication oAppContext = context;
oAppContext.BeginRequest += new EventHandler(_HandleSettingFilter);
}
private void _HandleSettingFilter(object sender, EventArgs e) {
//You might check the file at this part to make sure
//it is a file type you want to parse
//if (!CurrentFile.isStyleSheet()) { return; }
...
//assign the new filter
StringParsingFilter filter = new StringParsingFilter();
filter.OriginalStream = HttpContext.Current.Response.Filter;
HttpContext.Current.Response.Filter = (Stream)filter;
}
}
「IHttpModulesを検索」と言う方が実際は簡単だったかもしれません。これは、ASP.netファイル以外のパスのファイルを解析するために使用したコードです。
ASP.net ISAPIを、処理されるすべてのファイルのワイルドカードに設定して、ファイルを解析できるように、IISの設定をいくつか変更する必要もあります。さらにこのWebサイトで、IIS6を使用している場合...
これを使用して任意のファイルタイプを変更することもできます。そのため、画像にいくつかのフィルター、javascriptまたはスタイルシートにいくつかのフィルターを割り当てることができます...
URLリライタを使用して、リクエストの受信時にURLを修正できますが、この場合、ハックほどエレガントであるかどうかはわかりません。
必要なすべてのパスを提供するPathHelper utilクラスを作成しました。 例
<link href="<%=PathHelper.CssUrl("FormulaIndex.css")%>" rel="Stylesheet" type="text/css"/>
System.Web.VirtualPathUtility.ToAbsolute()と独自の規則(content / css / yourFile.css)を使用して、正しい完全なURLを提供します。
js、xml、t9n、picsについても同じことをしました... その中心的で再利用可能なので、すべてのWebサイトおよびページで、scriptsフォルダーのcontent / jsからScriptsへの移動をキャッチするために1行だけ変更する必要がありました。
あなたが私に尋ねるなら、モロニックな動きですが、現在のベータでは現実です:(