在研究了Behnam Esmaili提到的问题之后,进一步阅读,进一步阅读和进一步阅读:-)这就是我想出的。
我创建了一个新的IHttpModule用于检查/areaname/contentfolder/
每个进来的请求,其中areaname
是任何应用程序的领域名称的路径,contentfolder
是任何可能的内容的文件夹名称的选择列表。我选择了硬编码一组合理的内容文件夹名称,但是您可以让每个区域注册将其所有内容文件夹名称注册到某处并使用它。
注意:联机Microsoft文档Walkthrough: Creating and Registering a Custom HTTP Module建议您将HTTPModule类放在App_Code文件夹中。别!该文件夹中的类由ASP.Net进行运行时编译,导致临时.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() { }
检查此解决方案:http://stackoverflow.com/questions/5130226/relative-content-path-in-mvc3-areas –