views:

183

answers:

2

I have a separate utility class that is called in the controller, and i need to access a file inside the Views folder. Inside the the Views{controller} are a couple of sub folders that contain the different views. What I'm looking for is something similar to using:

HttpContext.Current.Request.PhysicalApplicationPath

to get the physical folder on the drive.

I tried using:

HttpContext.Current.Request.MapPath(HttpContext.Current.Request.Path);

but that just maps the requested route to a physical path that doesn't actually exits (ie. if i request '/Cars/Models/123' it will return 'C:\AppPath\Cars\Models\123\')

Any ideas?

A: 

The framework is opinionated so I'd use the same search algorithm the framework uses. Find the root of the app, then look in the views folder. It should be either in the folder associated with the controller in question or in the shared folder. Use the RouteValueDictionary to get access to the controller.

tvanfosson
how do i populate a RouteValueDictionary object with the current route?
prototypef
The RouteValueDictionary is a property of the Controller (RouteData). You don't need to populate it, it comes populated with your route parameters for free. Just extract the values and pass them onto your utility method.
tvanfosson
A: 

After messing around with RouteValueDictionary, RouteData, RequestContext and all sorts of Route classes, I was almost ready to give up and hardcode my way in. I started this project a while ago so i had forgotten about the customizations to the WebFormViewEngine class i had done. I'm gonna go ahead and post my solution, even though i realize it may not be the most elegant, secure or practical (in terms of best practices).

First of all i had extendend the WebFormViewEngine class and overridden the FindView method:

public class CustomViewEngine : WebFormViewEngine
{
 public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
 {
  ViewEngineResult result = null;
  var request = controllerContext.HttpContext.Request;

  // modify stuff here

  result = base.FindView(controllerContext, viewName, masterName, useCache);

  return result;
 }
}

What i did was add a static property to my utility class, like so:

public static string CurrentViewPath { get; set; }

and modified the FindView method to capture the ViewEngineResult and get the ViewPath:

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
  ViewEngineResult result = null;
  var request = controllerContext.HttpContext.Request;

  // modify stuff here

  result = base.FindView(controllerContext, viewName, masterName, useCache);

  System.Web.Mvc.WebFormView wfvView = (System.Web.Mvc.WebFormView)result.View;
  HelperFunctions.CurrentViewPath = wfvView.ViewPath.Replace(viewName + ".aspx","");

  return result;
}

this gave me the virtual path to the view, which is just what i needed. the only thing left to do was go back to the utility class and use the HttpContext.Current.Request.MapPath method to get the full physical path of where the current view file is:

string ViewPath = HttpContext.Current.Request.MapPath(CurrentViewPath);

And bingo!

It is sort of a roundabout hackish way to do this, bu hey, if it works...

Thanks for the help and useful suggestions everyone.

prototypef