Относительный путь контента в областях 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 + "/"));
      }

    }
 }

5 ответов

Решение

Вы можете попробовать создать расширение на 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="..." />

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

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

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

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

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

Вы все еще можете использовать @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;
        }
    }
}

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

@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>

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

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

Я попытался использовать 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" />

Спасибо за размещение этого решения. Прекрасно работает с моим исправлением для изображений.

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

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

этот:

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

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

Другие вопросы по тегам