Я решил использовать решение @ thinkzig, хотя и немного по-другому. Используя FileContent из сборки MVC Futures, я просто добавил еще один маршрут для обработки изображений.
routes.MapRoute("Image", "article/{id}/{image}", new { controller = "Article", action = "Image" });
routes.MapRoute("Article", "article/{id}", new { controller = "Article", action = "Index" });
Этот новый метод действия просто создает путь к файлу на основе articleID и имени изображения:
public ActionResult Image(string id, string image)
{
string articlePath = Server.MapPath("~/views/article/");
string filePath = Path.Combine(articlePath, string.Format("{0}/{1}", id, image));
return this.File(filePath, "image");
}
Была еще одна маленькая вещь, с которой мне пришлось бороться. Если пользователь получает доступ к статье без косой черты (http://localhost/article/8AB98
), то браузер считает, что articleID - это файл, и пытается найти папку с неправильным изображением (http://localhost/article/img.png
).
К счастью, в этом случае mvc направляет запрос к действию Article с именем изображения в качестве параметра «id», поэтому я могу просто искать «.» в id, а затем используйте обычное действие Image для его обработки.
в статье Действие:
if (id.Contains("."))
{
return RedirectToImage(id);
}
А затем код перенаправления изображения, который определяет идентификатор и имя файла
private ActionResult RedirectToImage(string id)
{
if (Request.UrlReferrer == null)
{
return Content("invalid request");
}
var referrer = Request.UrlReferrer.ToString();
if (referrer.Contains("?"))
{
referrer = referrer.Split('?')[0];
}
var realId = Path.GetFileName(referrer);
return this.Image(realId, id);
}
Вы заметите, что я полагаюсь на URL-реферер, чтобы получить фактический идентификатор статьи. Если пользователь пытается щелкнуть правой кнопкой мыши по изображению (при просмотре без косой черты) и выбирает «открыть изображение в новой вкладке», то у меня нет возможности узнать, что такое идентификатор статьи, поэтому я просто возвращаю «недопустимый запрос» Строка для пользователя. Это нормально, потому что я на самом деле не пытаюсь поддерживать этих пользователей в такой ситуации: -)