Behnam Esmaili によって言及された質問を調査し、さらに、さらに、さらに読んでください :-) これが私が思いついたものです。
/areaname/contentfolder/
各受信要求のパスをチェックする新しい IHttpModule を作成しましareaname
たcontentfolder
。もっともらしいコンテンツ フォルダー名のセットをハードコードすることにしましたが、各エリア登録ですべてのコンテンツ フォルダー名をどこかに登録し、それを使用することができます。
注: オンラインの Microsoft ドキュメントウォークスルー: カスタム HTTP モジュールの作成と登録では、HTTPModule クラスを App_Code フォルダーに配置することをお勧めします。しないでください!そのフォルダー内のクラスは、ASP.Net によってランタイム コンパイルされます。その結果、temp .Net フォルダー内にクラスのバイナリ コピーが作成されます。これにより、ASP.Net が HTTPModule クラスを読み込もうとするとあいまいさが生じます。選択した別のフォルダーにクラスを配置します。
すべての地域名を検索するために、AppDomain.CurrentDomain.GetAssemblies()
のすべてのサブクラスを使用して検索することにしSystem.Web.Mvc.AreaRegistration
ました。AreaName
それぞれのインスタンスを作成し、そのプロパティの値を取得します。
完全なソース コード:
public class HTTPModuleAreaContent : IHttpModule
{
private List<string> allAreaNames = null;
public HTTPModuleAreaContent()
{
}
public String ModuleName
{
get { return "HTTPModuleAreaContent"; }
}
public void Init(HttpApplication application)
{
application.BeginRequest +=
(new EventHandler(this.BeginRequest));
}
private void GetAreaNames(HttpContext context)
{
allAreaNames = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(ass => ass.GetTypes())
.Where(t => t.IsSubclassOf(typeof(AreaRegistration)))
.Select(t => ((AreaRegistration)Activator.CreateInstance(t)).AreaName)
.ToList();
}
private void BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
if (allAreaNames == null)
GetAreaNames(context);
string filePath = context.Request.FilePath.ToUpper();
string areaName = allAreaNames
.FirstOrDefault(an => filePath.StartsWith('/' + an + '/', StringComparison.OrdinalIgnoreCase));
if (string.IsNullOrEmpty(areaName))
return;
string areaNameUpper = areaName.ToUpper();
if (filePath.StartsWith('/' + areaNameUpper + "/STYLES/")
|| filePath.StartsWith('/' + areaNameUpper + "/SCRIPT/")
|| filePath.StartsWith('/' + areaNameUpper + "/SCRIPTS/")
|| filePath.StartsWith('/' + areaNameUpper + "/JS/")
|| filePath.StartsWith('/' + areaNameUpper + "/JAVASCRIPT/")
|| filePath.StartsWith('/' + areaNameUpper + "/JAVASCRIPTS/")
|| filePath.StartsWith('/' + areaNameUpper + "/CONTENT/")
|| filePath.StartsWith('/' + areaNameUpper + "/IMAGES/")
)
context.RewritePath("/Areas/" + context.Request.Path);
}
public void Dispose() { }
}
編集:どうやら、上記の解決策は、ドメインのルート以外で食べたアプリケーションでは機能しません。いくつかの作業の後、代わりに次の解決策を思いつきました。
public class HTTPModuleAreaContent : IHttpModule
{
private List<string> allAreaNames = null;
private HashSet<string> folderNamesToRewrite = new HashSet<string>();
public HTTPModuleAreaContent()
{
}
public String ModuleName
{
get { return "HTTPModuleAreaContent"; }
}
public void Init(HttpApplication application)
{
application.BeginRequest +=
(new EventHandler(this.BeginRequest));
folderNamesToRewrite.Add("STYLES");
folderNamesToRewrite.Add("SCRIPT");
folderNamesToRewrite.Add("SCRIPTS");
folderNamesToRewrite.Add("JS");
folderNamesToRewrite.Add("JAVASCRIPT");
folderNamesToRewrite.Add("JAVASCRIPTS");
folderNamesToRewrite.Add("CONTENT");
folderNamesToRewrite.Add("IMAGES");
}
private void GetAreaNames(HttpContext context)
{
allAreaNames = AppDomain.CurrentDomain.GetAssemblies().SelectMany(ass => ass.GetTypes()).Where(t => t.IsSubclassOf(typeof(AreaRegistration))).Select(t => ((AreaRegistration)Activator.CreateInstance(t)).AreaName).ToList();
}
private void BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
if (allAreaNames == null)
GetAreaNames(context);
string filePath = context.Request.FilePath;
string areaName = allAreaNames.FirstOrDefault(an => Regex.IsMatch(filePath, '/' + an + '/', RegexOptions.IgnoreCase | RegexOptions.CultureInvariant));
if (string.IsNullOrEmpty(areaName))
return;
string areaNameUpper = areaName.ToUpperInvariant();
Regex regex = new Regex('/' + areaNameUpper + "/([^/]+)/", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
Match m = regex.Match(filePath);
if (m.Success && m.Groups.Count > 1)
{
string folderName = m.Groups[1].Value;
string folderNameUpper = folderName.ToUpperInvariant();
if (folderNamesToRewrite.Contains(folderNameUpper))
context.RewritePath(regex.Replace(context.Request.Path, string.Format("/Areas/{0}/{1}/", areaName, folderName), 1));
}
}
public void Dispose() { }