通过mvc路由图像路径

时间:2012-12-18 21:45:05

标签: asp.net-mvc asp.net-mvc-4 asp.net-mvc-routing

我目前正在创建一个MVC4 Web应用程序。此应用程序显示包括图像的产品我有一家公司要检查网站的搜索引擎优化方面,他们已经提出了有关产品图片的建议。

目前我的图片路径是:folder / images / productimage / PROD_98713204_LARGE.gif

他们推荐了以下内容:/ folder / images / productimage / 98713204-160x260-0-0_My + Product = name.gif

我遇到的问题是我在网站上有大量图片,所以很难重命名所有包含产品名称等等。所以我考虑过在MVC中使用路由功能,输出推荐的html标记,但从文件系统中选择上面显示的当前图像路径。

我有两个问题:

  • 使用此类路由管理图像路径是否会影响性能?我的网站将有大量的流量负载和大量图像,所以这是一个问题。
  • 有人能给我一个我需要配置以实现上述目的的路线示例吗?

1 个答案:

答案 0 :(得分:1)

为了执行路由选项,您必须提供一些关于URL如何映射到实际图像的规范。我们谈论了多少张图片? 1000欧万?一百万?如果你的数量少于100,000,那么我可能会继续使用你已编写的规范来重新命名所有文件,然后使用规范从现在开始在进入文件系统的路上命名文件。 / p>

该系统的优点在于它限制了数据更改的范围,您只需要影响系统的一个点(当文件正在进入时)。在性能方面,将字符串映射到另一个字符串的开销可能可以忽略不计,即使对于大量请求也是如此。短字符串的字符串操作非常快,但无论如何,如果请求开始花费太长时间并专注于主要难点,则应该描述整个请求。当然,如果你只是重命名文件,你可以确定你不必担心任何这种分析。

至于创建一个映射URL的路由,首先必须让ASP.NET将请求交给你的代码。默认情况下,ASP.NET首先检查文件是否存在于url指定的位置,如果存在,它只是根据IIS中注册的处理程序处理文件。我的建议是保留这些设置,因为它们在您更改系统时会对系统进行非常大的更改。对于图像,处理程序只是尝试将文件发送到客户端。

如果磁盘上不存在该文件,则它会通过迭代路径集合来查找请求的处理程序,这是您通常在Global.asax中注册路由的事情。既然你没有告诉我们你的尝试,我会假设你知道路线是如何工作的。你可以通过路线变得非常狡猾,但我会坚持一些简单的事情:

routes.MapRoute(
    name: "images",
    url: "{folder}/images/productimage/{unmappedFileName}",
    defaults: new { controller = "Home", action = "Images" }
);

此路线将与您提供的示例网址相匹配。但是,在他们使用实际文件名的情况下,这条路线永远不会被击中,正如我上面所解释的那样。由于 SEOed 文件名不存在,因此该路由将被命中并且它将尝试在Home控制器上运行Images操作(我在此列出我的整个Home控制器以消除关于这些位置的任何混淆零件去):

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Images(string unmappedFileName)
    {
        if (String.IsNullOrWhiteSpace(unmappedFileName))
        {
            return HttpNotFound();
        }

        var fileName = MapFileName(unmappedFileName);
        var diskLocation = GetDiskLocation(fileName);
        return File(diskLocation, "image/png");
    }

    private string MapFileName(string unmappedFileName)
    {
        return unmappedFileName + ".png";
    }

    private string GetDiskLocation(string fileName)
    {
        var fullPath = String.Format("~/Content/themes/base/images/{0}", fileName);
        var diskLocation = Server.MapPath(fullPath);
        return diskLocation;
    }
}

显然,您需要将文件名映射更新为您决定的任何规范。我正在使用这里的内容,因为当您创建一个新的MVC4项目时,该文件夹中有一堆示例文件。

显示它有效的一种简单方法是在Home文件夹中实现Index视图,如下所示:

{
    ViewBag.Title = "Index";

    var imagesDirectory = Server.MapPath("~/Content/themes/base/images/");
    var imageFileNames = Directory.GetFiles(imagesDirectory).Select(m => m.Replace(imagesDirectory, "").Replace(".png", ""));
}

<h2>Index</h2>

@foreach (var imageFileName in imageFileNames)
{
    <div>@Html.ActionLink(imageFileName, "Images", new { unmappedFileName = imageFileName })</div>
}

将来遇到这样的问题时,你应该先试着弄明白。当你提出问题时,一定要告诉我们你尝试了什么,这样我们就可以让你超越下一个驼峰并指出正确的方向,而不仅仅是要求我们提供解决问题的代码。如果您不知道从哪里开始,请尝试搜索或询问a more abstract question。谁知道,他们甚至可能同时回答你的其他问题。 :)

最后,这个解决方案非常复杂。我甚至不知道你的映射函数是如何工作的,但我知道这很复杂。它还在调试时增加了一层复杂性,因为现在你的url与磁盘上的文件名没有直接关系,而且这个时间会在以后加起来。当然,我有理由支持这种映射,最值得注意的是,如果你打算在将来更改url结构以进行进一步的 SEO 更改,但是那时你在互联网上打破网址并且该死的你为了那个原因。实际上,如果可行,我建议只更改所有文件名。