Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I found this question Can't use relative paths with areas in ASP.NET MVC 2 which is the same issue I am having. Is this still the case in MVC3?

Is there a way to keep content files in an area relative to the area?

So that a layout file in an area can have something like

Without having to either make a fully qualified link, requiring the areas directory and the area name or the solution of the above question which requires a check for each area on each request.

update/edit

I've decided to use both the solution in the above question and the one below (html helper) - depending on the project/situation. My implementation of the above uses app.setting to store the area names and the extensions so that I can just have the module as part of my library.

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 + "/"));
      }

    }
 }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
477 views
Welcome To Ask or Share your Answers For Others

1 Answer

I personally like the extension method route, based on the first answer I came up with this and tested that it works ... Instead of using @Url.Content, use @Url.ContentArea and no need to put in '~/', '/' or '../', etc..

The helper does some checking to automatically remove these, so just use is like this ...

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

When you create this Url Helper Extension, your choice, but I created a 'Helpers' folder off the root of the web then I include the @using YourWebNameSpace.Helpers; in my _Layout.cshtml (razor/masterpage) in whatever 'Area' I am in.

You can still use @Url.Content for references outside the current area (basically you can mix based on the resource needed and its location).

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;
        }
    }
}

in your master page, or any page (Razor only for this example) ...

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...