Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 在ASP.NET MVC中路由后未找到CSS和图像文件_Asp.net Mvc 3_Asp.net Mvc Routing - Fatal编程技术网

Asp.net mvc 3 在ASP.NET MVC中路由后未找到CSS和图像文件

Asp.net mvc 3 在ASP.NET MVC中路由后未找到CSS和图像文件,asp.net-mvc-3,asp.net-mvc-routing,Asp.net Mvc 3,Asp.net Mvc Routing,在我的ASP.NET MVC(3)应用程序中,我在global.asax.cs中设置了以下路径: routes.MapRoute( "UniqueId", "{uniqueId}", new { controller = "Book", action = "DownloadBook" }, new { uniqueId = "[0-9a-zA-Z]{5}" } ); 下载文件操作方法为: public ActionResult DownloadBook(stri

在我的ASP.NET MVC(3)应用程序中,我在global.asax.cs中设置了以下路径:

routes.MapRoute(
    "UniqueId",
    "{uniqueId}",
    new { controller = "Book", action = "DownloadBook" },
    new { uniqueId = "[0-9a-zA-Z]{5}" }
);
下载文件操作方法为:

public ActionResult DownloadBook(string uniqueId)
{
    string path = Server.MapPath(String.Format("~/App_Data/Books/{0}/index.htm", uniqueId));
    if (System.IO.File.Exists(path))
    {
        return File(path, "text/html");
    }
    return new EmptyResult();
}
该方法正确地为/App_Data/Books目录子目录中的index.htm文件提供服务,该文件的名称与路由中定义的uniqueId对应。但是,无法找到index.htm文件中的CSS和图像文件,因为浏览器试图在原始URL位置(例如)中找到它们

我能做些什么吗?我可能忽略了什么

编辑(另请参见我问题答案中的评论):
这些书存储为HTML文件(而不是MVC视图,这将减少引用CSS和图像的问题),因为:
1.它们将由用户上传。
2.我想将index.htm文件及其使用的资源存储在HTML5 appcache中,以便脱机使用


编辑2我已经找到了自己问题的解决方案,想知道您对此有何看法。请在下面的答案中查看我自己的答案。

这一定是因为您以错误的方式(相对地)引用了您的文件,这意味着它将根据当前页面的根提供服务

例:




与此相反,使用以下sytax链接CSS文件和图像

<link rel="Stylesheet" href="<%=Url.Content("~/Styles/site.css")%>" />


这应该可以很好地工作,并且可以从任何页面正确地进行评估,无论它位于何处。

您可以做一些事情,但这更像是一种黑客行为。为css链接放置占位符,然后在提供文件时,执行替换,类似这样的操作

public ActionResult DownloadBook(string uniqueId)
{
string path = Server.MapPath(String.Format("~/App_Data/Books/{0}/index.htm", uniqueId));
if (System.IO.File.Exists(path))
{
   var file=File.ReadAllText(path);
   //this needs a bit more refining, it's just a proof of concept
     //you can use Razor templating, there is a library for that
    file=file.Replace("{CssHref}",UrlHelper.GenerateContentUrl("~/Content/site.css",HttpContext));
   return Content(file);
}
return new EmptyResult();
}

我想我可能已经找到了一个非常优雅的解决方案,但我想听听你对这个问题的看法。在试图将浏览器发送到正确的位置时,我一直在关注“经典”URL重写,当它试图获取App_Data子文件夹中index.htm文件引用的CSS文件和图像文件时(这已成为一个长句,我希望它有意义;-)


首先,我尝试在应用程序的global.asax.cs的BeginRequest事件处理程序中使用Context.RewritePath。这给了一些意想不到的副作用。然后,我创建了一个自定义路由类,它涵盖了我在上面的问题中描述的原始路由以及CSS和图像文件请求的URL重写。自定义路由使用以下事实:在这些请求期间,Request.urlReferer属性包含index.htm文件位置的URL。由于这将成为一个很长的故事,我参考了我在这个主题上写的一篇文章来了解技术细节。我希望这些信息能为其他人节省一些宝贵的时间。

index.htm文件中的CSS参考是:(index.htm文件及其资源位于同一文件夹中)。因为我提供的是一个html文件,所以我不能使用您描述的.NET语法来引用CSS文件。如果能够指示浏览器从index.htm文件实际所在的目录(~/App_Data/Books/)而不是从请求URL(localhost/3Yru3)检索CSS和图像文件,那就太好了。但这肯定是不可能的,因为App_数据文件夹不能直接引用。这就是我当初选择它的原因。我只希望用户能够在查询字符串中使用像3Yru3这样的唯一ID下载书籍。实际上,您可以使用Mohammed建议的绝对路径语法,即使它来自HTML页面。另一种选择是将HTML页面转换为aspx/Razor页面,然后您可以使用任何建议的答案。需要注意的是,浏览器将CSS文件中的图像和其他资源解释为相对于该CSS文件位置的路径。它不是相对于页面的URL,而是相对于CSS文件的路径。因此,无论您以何种方式成功地包含到CSS文件的链接,CSS文件中的图像/其他内容都将起作用。@Charlie感谢您的评论。我不能像你建议的那样将index.htm页面转换为ASPX或Razor页面,因为我希望它存储在HTML5 appcache中(以使其脱机可用)。如果我找不到一个“黑客”较少的解决方案,我可能会尝试一下。它包含一些创造性的想法。另一个解决方案是将书籍html实际存储为书籍控制器的视图。它们不能通过浏览器直接访问,它们将被视图引擎解析。这也是最简单的解决方案好的建议,但这将不允许我将书添加到HTML5应用缓存,如果我是正确的?另见我在另一个答案中对查理评论的回应。我将更新我的问题以反映我的额外需求。如果我理解正确,html5 appcache是客户端的东西。因此,服务器将如何为页面提供服务并不重要,只要它还发送缓存清单。有不同的东西,缓存处理接收到的html文档,服务器生成html文档。我不知道上传部分,如果你可以直接在视图文件夹中上传文件,那需要测试
<link rel="Stylesheet" href="<%=Url.Content("~/Styles/site.css")%>" />
public ActionResult DownloadBook(string uniqueId)
{
string path = Server.MapPath(String.Format("~/App_Data/Books/{0}/index.htm", uniqueId));
if (System.IO.File.Exists(path))
{
   var file=File.ReadAllText(path);
   //this needs a bit more refining, it's just a proof of concept
     //you can use Razor templating, there is a library for that
    file=file.Replace("{CssHref}",UrlHelper.GenerateContentUrl("~/Content/site.css",HttpContext));
   return Content(file);
}
return new EmptyResult();
}