如何解决如何修改ASP.NET MVC静态文件的根目录
| 我希望能够重组我的ASP.NET MVC网站结构,使其与Rails的工作方式更加接近(我们在公司同时使用Rails和ASP.net)。 在Rails中,有一个\“ public \”文件夹,它充当站点的根目录。例如,我可以放入\“ test.html \”并使用url http://domain.com/test.html访问该文件,它将提供静态html文件。 在asp.net MVC中,有一个我想充当根用户的\“ Content \”文件夹。因此,我希望能够访问http://domain.com/myfile.html,而不是访问http://domain.com/content/myfile.html。 我知道我可以将文件放在项目的根目录中,但是我需要使用许多文件来做到这一点,包括css,js,html,图像等,并希望在rails和aspnetmvc之间共享一些标准化的资产。 有没有办法做到这一点?解决方法
还有另一种可能的解决方案。您可以使用重写规则来代替您使用代码,而无需使用代码。如果您使用的是IIS 7或更高版本,则可以使用Microsoft的URL重写模块。
像下面这样的规则可能会做到:
<rule name=\"Rewrite static files to content\" stopProcessing=\"true\">
<match url=\"^([^/]+(?:\\.css|\\.js))$\" />
<conditions>
<add input=\"{APPL_PHYSICAL_PATH}content{SCRIPT_NAME}\" matchType=\"IsFile\" />
</conditions>
<action type=\"Rewrite\" url=\"/content/{R:1}\" />
</rule>
该规则从站点根目录检查对css或js文件的请求。然后,它检查内容文件夹中是否存在该文件。如果存在,则重写将返回内容文件夹中的文件。我仅对此进行了一点测试,但似乎可以正常工作。当然,它需要更多的测试以及可能的改进。
, 我能想到的唯一解决方案是使用自定义控制器和路由为您执行此操作。但这不是一个干净的解决方案。
首先,您需要一个带有GetFile操作方法的PublicController类。假定所有文件都直接位于public / content文件夹中。处理文件夹会使事情变得更加复杂。
public class PublicController : Controller
{
private IDictionary<String,String> mimeTypes = new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase)
{{\"css\",\"text/css\"},{\"jpg\",\"image/jpg\"}};
public ActionResult GetFile(string file)
{
var path = Path.Combine(Server.MapPath(\"~/Content\"),file);
if (!System.IO.File.Exists(path)) throw new HttpException(404,\"File Not Found\");
var extension = GetExtension(file); // psuedocode
var mimetype = mimeTypes.ContainsKey(extension) ? mimeTypes[extension] : \"text/plain\";
return File(path,mimetype);
}
}
现在,您只需要一条路线列表底部附近的路线即可,如下所示:
routes.MapRoute(\"PublicContent\",\"{file}\",new {controller = \"Public\",action = \"GetFile\"});
问题是,现在,当您仅输入\'Home \'之类的控制器名称而不是默认设置HomeController上的Index操作方法时,它假定您要从内容目录下载名为\“ Home \”的文件。因此,在文件路由上方,您需要为每个控制器添加一个路由,以便它知道获取Index操作。
routes.MapRoute(\"HomeIndex\",\"Home\",new { controller = \"Home\",action = \"Index\" });
因此,一种解决方法是将路由更改为此:
routes.MapRoute(\"PublicContent\",\"{file}.{extension}\",action = \"GetFile\"});
以及对此的操作方法:
public ActionResult GetFile(string file,string extension)
{
var path = Path.Combine(Server.MapPath(\"~/Content\"),file + \".\" + extension);
if (!System.IO.File.Exists(path)) throw new HttpException(404,\"File Not Found\");
var mimetype = mimeTypes.ContainsKey(extension) ? mimeTypes[extension] : \"text/plain\";
return File(path,mimetype);
}
就像我说的那样,这假设所有文件都在内容目录中,而不在子文件夹中。但是,如果您想执行诸如Content / css / site.css之类的子文件夹,则可以添加以下路线:
routes.MapRoute(\"PublicContent_sub\",\"{subfolder}/{file}.{extension}\",new { controller = \"Public\",action = \"GetFileInFolder\" });
routes.MapRoute(\"PublicContent\",action = \"GetFile\"});
现在,操作方法也必须更改。
public ActionResult GetFile(string file,string extension)
{
return GetFileInFolder(\"\",file,extension);
}
public ActionResult GetFileInFolder(string subfolder,string file,subfolder,mimetype);
}
如果您开始在文件夹结构中深入了解多个级别,那么这将变得越来越难看。但这也许对您有用。我确定您希望在项目属性中选择一个复选框,但是如果有一个复选框,我将不知道。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。