2

我目前正在创建一个 MVC4 Web 应用程序。此应用程序显示产品,包括图像。我有一家公司来审查该网站的 SEO 方面,他们回来后就产品图片提出了建议。

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

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

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

我有2个问题是:

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

1 回答 1

2

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

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

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

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

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

此路由将匹配您提供的示例 url。然而,在他们使用实际文件名的情况下,这条路线永远不会被击中,正如我上面解释的那样。然而,由于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>
}

以后遇到这样的问题,还是先想办法解决。当您提出问题时,请务必告诉我们您已经尝试过什么,这样我们就可以帮助您度过下一个难关并为您指明正确的方向,而不是仅仅要求我们提供代码来解决您的问题。如果您不知道从哪里开始,请尝试搜索或询问更抽象的问题。谁知道呢,他们甚至可能同时回答您的其他问题。:)

And lastly, this solution is really complicated. I don't even know how your mapping function is going to work, but I know this is complicated. It also adds a layer of complexity when debugging because now the urls you have don't directly relate to the file name on disk, and that time will add up later on. Of course there are reasons why I might favor this mapping, most notably if you intend to change the url structure in the future for further SEO changes, but then you're breaking urls on the internet and damn you for that. So really, I suggest just changing all of your file names if that is feasible.

于 2012-12-19T03:45:36.473 回答