Search code examples
asp.net-mvcglobal-variablesspark-view-engine

SparkViewEngine: Using Url.Content in global variable in Application.Spark


I am using ASP.NET MVC 2 with SparkViewEngine 1.1 and I get the error message An object reference is required for the non-static field, method, or property 'Spark.Web.Mvc.SparkView.Url.get' when I use the following code in the Application.spark view file

<global baseImagePath='Url.Content(Context,"~/Content/_images")' type="string" />

What I am trying to accomplish is basically define a base image path as a global variable that can be referenced in the page templates.

For example, in Home/Index.spark, which uses the master Application.spark, I would have the following code snippet in the view

<a href="..."><img src="${baseImagePath}" alt="..." /></a>

As a workaround, I can set a hard-coded value when I set baseImagePath by doing <global baseImagePath='"~/Content/_images"' type="string" />, but I want to also be able to resolve the "~" before hand.

Any suggestions?

Thank you!

Edit I am adding my solution here per Rob's suggestions

In Shared/_global.spark, I added <use namespace="System.Web" /> so that I have access to the System.Web namespace.

In Shared/Application.spark, I added

<global baseImagePath='VirtualPathUtility.ToAbsolute("~/Content/_images")' type="string" />

Solution

  • The problem here is that Url.Content(... is accessing the UrlHelper class in System.Web.Mvc from the SparkView instance. The problem is that when the Application.spark is being parsed for globals, you don't yet have an instance of a view because global variables are defined before the generated view class is instantiated. Therefore accessing and instance variable like Url from the view is not possible.

    From the looks of it though, you're just trying to get an absolute path from a relative one. For this you could potentially just use the static VirtualPathUtility class from System.Web.

    There are a number of methods on there like ToAbsolute(...) that make life easier. Alternatively, you could get it from the HttpContext.Current.Server.MapPath(...) method if you have the current context.

    Hope that helps,
    All the best,
    Rob G