Относительный путь контента в областях MVC3

Я нашел этот вопрос Нельзя использовать относительные пути с областями в ASP.NET MVC 2, что является той же проблемой, что и у меня. Это все еще имеет место в MVC3?

Есть ли способ сохранить файлы содержимого в области относительно области?

Чтобы файл макета в области мог иметь что-то вроде

Не нужно либо делать полностью связанную ссылку, требующую каталога областей, а также названия области или решения вышеуказанного вопроса, требующего проверки для каждой области по каждому запросу.

обновление/изменить

Я решил использовать оба решения в вышеупомянутом вопросе и один ниже (html helper) - в зависимости от проекта/ситуации. Моя реализация выше использует app.setting для хранения имен областей и расширений, чтобы я мог просто иметь модуль как часть моей библиотеки.

var context = HttpContext.Current;
var path = context.Request.Path;
var list = ...       //code that gets from app.config and then saves it
var extensions = ... // to the cache as non-removable with a dependency on web.config
foreach (var area in list)
{
   if (!path.Contains(area + "/")) continue;
   foreach (var extension in extensions)
   {
      if (path.EndsWith("." + extension))
      {
         context.RewritePath(path.Replace(area + "/", "Areas/" + area + "/"));
      }

    }
 }

Ответы

Ответ 1

Вы можете попробовать создать расширение на HtmlHelper, чтобы решить эту проблему:

public static string Image(this HtmlHelper html, string imagePath)
{
    var area = html.ViewContext.RouteData.Values["area"];
    if (!string.IsNullOrEmpty(area))
        area = "Areas/" + area + "/";
    return VirtualPathUtility.ToAbsolute("~/" + area + "Content/img/" + imagePath);
}

поэтому, на ваш взгляд, вы можете использовать:

<img src="@Html.Image("myimage.png")" alt="..." />

Я не пробовал код, так что поправьте меня, если я ошибаюсь.

Ответ 2

Мне лично нравится маршрут метода расширения, основанный на первом ответе, я придумал это и проверил, что он работает... Вместо использования @Url.Content используйте @Url.ContentArea и не нужно вставлять '~/', '/' или '../' и т.д.

Помощник выполняет некоторую проверку, чтобы автоматически удалить их, поэтому просто используйте это как...

@Url.ContentArea("Content/style.css") or @Url.ContentArea("Images/someimage.png") :)

Когда вы создаете это расширение URL-адреса, ваш выбор, но я создал папку "Помощники" от корня сети, тогда я включаю @using YourWebNameSpace.Helpers; в мой _Layout.cshtml (бритву/главную страницу) в любом 'Area' Я нахожусь.

Вы можете использовать @Url.Content для ссылок за пределами текущей области (в основном вы можете смешивать на основе необходимого ресурса и его местоположения).

namespace YourWebNamespace.Helpers
{
    public static class UrlHelperExtensions
    {
        public static string ContentArea(this UrlHelper url, string path)
        {
            var area = url.RequestContext.RouteData.DataTokens["area"];

            if (area != null)
            {
                if (!string.IsNullOrEmpty(area.ToString()))
                    area = "Areas/" + area;

                // Simple checks for '~/' and '/' at the
                // beginning of the path.
                if (path.StartsWith("~/"))
                    path = path.Remove(0, 2);

                if (path.StartsWith("/"))
                    path = path.Remove(0, 1);

                path = path.Replace("../", string.Empty);

                return VirtualPathUtility.ToAbsolute("~/" + area + "/" + path);
            }

            return string.Empty;
        }
    }
}

на главной странице или на любой странице (только для этого примера)...

@using YourWebNamespace.Helpers

<html lang="en">
<head>

    <link href="@Url.ContentArea("Content/reset.css")" media="screen" rel="stylesheet" type="text/css" />

    <link href="@Url.ContentArea("Content/style.css")" media="screen" rel="stylesheet" type="text/css" />

</head>
<body>

Ответ 3

У меня была аналогичная проблема в таблице стилей, которую я решил, просто вставив оба относительных пути:

#searchbox {
    ...
    background: url("../Content/magglass.png") no-repeat;
    background: url("../../Content/magglass.png") no-repeat;
    ...
}

Ответ 4

Я попробовал UrlHelperExtensions выше для некоторых изображений, которые я использую на своей главной странице в качестве данных для прокручивающего баннера jQuery. Мне пришлось добавить следующее условие else, чтобы помощник возвращал этот путь, когда не было области:

        else
        {
            if (path.StartsWith(@"~/"))
            {
                var result = VirtualPathUtility.ToAbsolute(path);
                return result;
            }
        }

        return string.Empty;

На моей странице просмотра я использовал:

<img src="@Url.ContentArea("~/images/ScrollPicture1.png")" alt="Gallery picture 1" />

Спасибо за публикацию этого решения. Отлично работает с моими исправлениями для изображений.

Ответ 5

У меня были подобные проблемы с моим веб-приложением ASP.NET MVC 3, и я исправил запись вместо

<img src="mypath/myimage.png" alt="my alt text" />

<img src='@Url.Content("mylink")' alt="my alt text" />

где последняя моя ссылка - это путь, например ~/mypath. Я использовал его, чтобы связать свои файлы javascript, однако я не пробовал его с изображениями или ссылками, поэтому вы должны попробовать себя...