.NET MVC3:防止 404 丢失 CSS 文件?或者在编写 HTML 之前确保文件存在?
我们需要为 ASP.NET MVC3 应用程序提供换肤功能。
到目前为止,我的方法是通过 cookie 和 css 文件的子操作来解决这个问题:
- 客户端使用 www.ourapp.com/as/www.clientapp.com/then-go-to/path 之类的 URL 链接到我们的应用程序/in/ourapp.
- 上面的 url 被路由到一个操作方法,该方法写入一个名为“skin”、值为“www.clientapp.com”的 cookie,然后重定向到 /path/in/ourapp。
- 我们的布局(母版页)在要渲染 css 文件的
部分中有一个
@Html.Action
。 - 子操作检查 cookie 并创建一个视图模型,该视图模型将告诉部分视图要渲染哪些
标记。
css 文件结构基于 cookie 值。因此,我们的 css 内容可能如下所示:
/content
/www.clientapp.com
/style1.css
/style1.css
/www.client2app.com
/style1.css
/style2.css
我愿意听到更好的模式/替代方案,将皮肤应用于布局。但这不是我提出问题的原因。
当前,当文件系统中不存在 css 文件时,此方法存在问题。该请求导致 IIS 返回 404。我们使用自定义页面覆盖 404 页面(不使用 中具有 @Html.Action 的相同布局)。这会导致 IIS 执行一些不必要的额外处理(例如,在 404 页面布局上呈现登录/注销链接、水平导航等的部分和子操作)。
在我看来,有两种方法可以解决这个问题:
- 在配置 css 的子操作中,检查以确保文件存在于磁盘上,然后再告诉视图模型应该渲染它们。这种方法的优点是它应该相当简单。缺点是要对其进行单元测试,必须将文件 I/O 包装在可注入的服务中。该应用程序还将部署到 Azure。我认为Azure可以读取文件系统(这是所需要的),但不能写入它。
- 以某种方式防止 css 文件返回 404。为此,我们是否必须在 global.asax Application_Error 中实现逻辑?或者是否有其他方法可以防止丢失 CSS 文件而触发 404 响应?
哪种方法是正确的?还是还有其他我没有考虑的?
更新
我们最终在自定义 404 错误页面中解决了这个问题,如下所示:
[ActionName("not-found")]
public virtual ActionResult NotFound()
{
// do not return 404 for missing css files
if (Request.RawUrl.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
{
Response.StatusCode = 404;
return new EmptyResult();
}
return View();
}
We have a requirement to provide skinning capabilities to an ASP.NET MVC3 app.
My approach so far has been to tackle this with a cookie and child actions for the css files:
- Client links to our app using a URL like www.ourapp.com/as/www.clientapp.com/then-go-to/path/in/ourapp.
- The above url is routed to an action method that writes a cookie named "skin" with value "www.clientapp.com" and then redirects to /path/in/ourapp.
- Our layout (masterpage) has an
@Html.Action
in the<head>
section where the css files are to be rendered. - The child action inspects the cookie and creates a viewmodel that will tell the partial view which
<link>
tags to render.
The css file structure is based on the cookie value. So our css content might look like this:
/content
/www.clientapp.com
/style1.css
/style1.css
/www.client2app.com
/style1.css
/style2.css
I am open to hearing better patterns / alternatives to the above for applying skins to the layout. However this isn't the reason for my question.
There is currently a problem with this approach when the css files are not present in the filesystem. The request causes IIS to return a 404. We override the 404 page with a custom page (not using the same layout that has the @Html.Action in the <head>
). This causes IIS to do some additional processing which is not necessary (for example partials & child actions to render sign-in/sign out links, horizontal nav, etc, on the 404 page's layout).
The way I see it there are 2 ways to solve this:
- In the child action that configures the css, check to make sure the files exist on disk before telling the viewmodel that they should be rendered. Pro with this approach is that it should be fairly easy. Cons are that to unit test it, would have to wrap file I/O in a service that can be injected. Also the app will be deployed to Azure. I think Azure can read the filesystem (which is what would be needed), but not write to it.
- Somehow prevent a 404 from being returned for css files. To do this, would we have to implement logic in global.asax Application_Error? Or is there another way to prevent missing CSS files from triggering a 404 response?
Which approach is correct? Or is there another that I'm not considering?
Update
We ended up solving this in the custom 404 error page like so:
[ActionName("not-found")]
public virtual ActionResult NotFound()
{
// do not return 404 for missing css files
if (Request.RawUrl.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
{
Response.StatusCode = 404;
return new EmptyResult();
}
return View();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一种选择是不覆盖 CSS 请求的 404 错误。
对于丢失的 CSS 文件,返回 404 状态,但将正文留空。正文对于 CSS 文件并不重要,因为人类看不到它,而浏览器只关心状态。
One option would be to not override 404 errors for CSS requests.
For missing CSS files, return the 404 status, but leave the body empty. The body doesn't matter with a CSS file, since a human doesn't see it, and all the browser cares about is the status.