1

I want to get a link to image resource in a MVC view that is part of an Orchard module.

Googling a bit resulted in the following approach:

https://stackoverflow.com/a/9256515/3936440

and its using @Html.ResourceUrl() in views to get the resource URL.

I wonder where the ResourceUrl() comes from as its not documented in MSDN and i cannot use it in my projects either.

Did someone used that approach already and can shed some light on whats missing here?

Update:

I figured it out. The following code works in connection with Orchard modules.

First you need to add a resource manifest to the Orchard module like so

public class ResourceManifest : Orchard.UI.Resources.IResourceManifestProvider
{
  public void BuildManifests(Orchard.UI.Resources.ResourceManifestBuilder aBuilder)
  {
    Orchard.UI.Resources.ResourceManifest lManifest = aBuilder.Add();

    string lModulePath = "~/Modules/YourModuleName";

    lManifest.DefineResource("ProfilePicture", "User1").SetUrl(lModulePath + "/Images/User1.png");
  }
}

Then you extend the Html object:

// This class adds so called "extension methods" to class System.Web.Mvc.HtmlHelper
public static class HtmlHelperExtensions
{
  // This method retrieves the URL of a resource defined in ResourceManifest.cs via the Orchard resource management system
  public static string ResourceUrl(this System.Web.Mvc.HtmlHelper aHtmlHelper, string aResourceType, string aResourceName)
  {
    // note:
    //  resolving Orchard.UI.Resources.IResourceManager via work context of orchard because
    //    - calling System.Web.Mvc.DependencyResolver.Current.GetService() does not work as it always returns null at this point
    //    - constructor parameter injection is not allowed in static classes
    //    - setting the resource manager from another class that uses constructor parameter injection does not work as it causes a "circular component dependency "
    Orchard.WorkContext lWorkContext = Orchard.Mvc.Html.HtmlHelperExtensions.GetWorkContext(aHtmlHelper);

    Orchard.UI.Resources.IResourceManager lResourceManager = (Orchard.UI.Resources.IResourceManager)lWorkContext.Resolve<Orchard.UI.Resources.IResourceManager>();
    if (lResourceManager != null)
    {
      Orchard.UI.Resources.RequireSettings lSettings = new Orchard.UI.Resources.RequireSettings { Type = aResourceType, Name = aResourceName, BasePath = aResourceType };

      Orchard.UI.Resources.ResourceDefinition lResource = lResourceManager.FindResource(lSettings);
      if (lResource != null)
      {
        Orchard.UI.Resources.ResourceRequiredContext lContext = new Orchard.UI.Resources.ResourceRequiredContext { Resource = lResource, Settings = lSettings };

        string lAppBasePath = System.Web.HttpRuntime.AppDomainAppVirtualPath;

        return lContext.GetResourceUrl(lSettings, lAppBasePath);
      }
    }

    return null;
  }
}

and then you can write:

<img src="@Html.ResourceUrl("ProfilePicture", "User1")" />

in an Orchard module view to get appropriate image link for User1.

I hope this helps.

Community
  • 1
  • 1
ViRuSTriNiTy
  • 5,017
  • 2
  • 32
  • 58
  • Nah, i didn't understand what the author wrote on first reading, ResourceUrl() is a so called extension method of the System.Web.Mvc.HtmlHelper class. Problem solved. – ViRuSTriNiTy Feb 16 '15 at 12:25
  • This looks overkill. What's wrong with putting the image in the Content/Images folder of the module, and then use Url.Content? – Bertrand Le Roy Feb 17 '15 at 01:59
  • @Bertrand Le Roy Simply putting the images in a folder as you suggested does not work in connection with the routes i provide for the module. Thus i came up with the centralized resource approach to avoid writing ~/Modules/YourModuleName/Images/MyImage over and over again. – ViRuSTriNiTy Feb 17 '15 at 10:08
  • How does it not work? Registered resources are for resources that must be re-usable across modules, not to simplify route resolution. – Bertrand Le Roy Feb 19 '15 at 00:47

1 Answers1

1

ResourceUrl() is a custom HtmlHelper extension.

The code that you need to implement it is included in the answer you have linked.

You simply need to create a static class that contains the method code.

Asp.net article on how to create custom html helpers

PS: Make sure you import your namespace into the view with @using YourNamespace or add it to the System.Web.Mvc.HtmlHelper class.

hutchonoid
  • 32,982
  • 15
  • 99
  • 104