I'm doing some custom infrastructure for auto-generating specific bundles for individual views, and have a case where I need to get the Layout value for each view while iterating them as files.
I've tried var view = new RazorView(new ControllerContext(), actionView.FullName, null, true, null);
but this is taking the LayoutPath as an input, and it is indeed resulting in an empty string on the LayoutPath property of the RazorView if I give null for that parameter, so it's not parsing the file for the value.
Could there be any other way to solve this in a similar manner, or would my best/only option be to just parse the text of the raw file (and _ViewStart)?
This is only done once at application start, so the performance is currently not an issue.
Alright, after a lot of source debugging and an epic battle with the internal access modifier, I have a working solution without having to render the whole page. I don't expect anyone else ever having the need for this, but anyway:
var httpContext = new HttpContextWrapper(new HttpContext(new HttpRequest("", "http://dummyurl", ""), new HttpResponse(new StreamWriter(new MemoryStream()))));
var page = Activator.CreateInstance(BuildManager.GetCompiledType(ReverseMapPath(actionView.FullName))) as WebViewPage;
page.Context = httpContext;
page.PushContext(new WebPageContext(), new StreamWriter(new MemoryStream()));
page.Execute();
var layoutFileFullName = page.Layout;
// If page does not have a Layout defined, search for _ViewStart
if (string.IsNullOrEmpty(layoutFileFullName))
{
page.VirtualPath = ReverseMapPath(actionView.FullName);
var startpage = StartPage.GetStartPage(page, "_ViewStart", new string[] {"cshtml"});
startpage.Execute();
layoutFileFullName = startpage.Layout;
}
Tada!
Ps. ReverseMapPath is a any arbitrary function to resolve the relative path of a full file name, see for example Getting relative virtual path from physical path