I am attempting to build a preview functionality that allows the user to see the page as if it were in the live site. The thing I want to do is load that external layout file without having to copy the views or setup the global asax in the local project.
Maybe I am asking this wrong. Virtualpathprovider allows me to render a view as a string. The issue with this, is I want to render my layout page from a different project. This said view, has many different routes and scripts and css style, is in a live
version of the website and I would like to be able to show a preview without having to add the same routes and scripts and pretty much every file into my administration project.
Here is what I have so far, but I am lost as how to load my layout this way.
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
namespace VirtualPathProviderExample.Core {
public class ExampleVirtualPathProvider : VirtualPathProvider {
private readonly string testAspxContent = "<%@ Page Language=\"C#\" MasterPageFile=\"~/Views/Shared/Site.Master\" Inherits=\"System.Web.Mvc.ViewPage\" %><asp:Content ID=\"indexTitle\" ContentPlaceHolderID=\"TitleContent\" runat=\"server\">Test Page</asp:Content><asp:Content ID=\"indexContent\" ContentPlaceHolderID=\"MainContent\" runat=\"server\"><h2><%= Html.Encode(ViewData[\"Message\"]) %></h2><br /><p>This is file by the name of <strong>~/Views/Home/Test.aspx</strong></p><p>This is a page that does not exist in anywhere but still it's there :D by means of VirtualPathProvider.</p></asp:Content>";
List<VirtualFile> virtualFiles = new List<VirtualFile>();
public ExampleVirtualPathProvider() {
virtualFiles.Add(new SimpleVirtualFile("~/Views/Home/Test.aspx", testAspxContent));
}
public override bool FileExists(string virtualPath) {
List<VirtualFile> files = (from f in virtualFiles where f.VirtualPath.Equals(virtualPath) select f).ToList();
if (files.Count > 0)
return true;
else
return base.FileExists(virtualPath);
}
private class SimpleVirtualFile : VirtualFile {
private string content;
public SimpleVirtualFile(string filename, string content)
: base(filename) {
this.content = content;
}
public override Stream Open() {
ASCIIEncoding encoding = new ASCIIEncoding();
return new MemoryStream(encoding.GetBytes(content), false);
}
}
public override VirtualFile GetFile(string virtualPath) {
List<VirtualFile> files = (from f in virtualFiles where f.VirtualPath.Equals(virtualPath) select f).ToList();
if (files.Count > 0) {
return files[0];
} else
return base.GetFile(virtualPath);
}
public override bool DirectoryExists(string virtualDir) {
return base.DirectoryExists(virtualDir);
}
public override VirtualDirectory GetDirectory(string virtualDir) {
return base.GetDirectory(virtualDir);
}
}
}
I guess, long story short, I should probably wire up the site to accept parameters on some authenticated section of the site.
I certain cannot do this because I get a virtualpath error.
'http:/www.xxx.com/views/shared/xxx/_layout.cshtml' is not a valid virtual path.
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: 'http:/www.xxx.com/views/shared/xxx/_layout.cshtml' is not a valid virtual path. Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
has to be in the same project. The views have to be able to compile together. There are ways to get layouts to compile across multiple projects in the same solution (Orchard CMS does this) but you'll have to write a bunch of custom code to make it happen.
as to be in the same project. The views have to be able to compile together. There are ways to get layouts to compile across multiple projects in the same solution (Orchard CMS does this) but you'll have to write a bunch of custom code to make it happen.
What if my layout has custom controller calls? Won't these fail?
Make a VirtualPathProvider that handles virtual paths that start with a magic token and passes all other paths to its
Previous property. For example:
public override VirtualFile GetFile(string virtualPath) {
if (virtualPath.StartsWith("~/MySpecialTemplateServer"))
return new MyServerVirtualFile(virtualPath);
else
return Previous.GetFile(virtualPath);
}
Hope this helpful
Regards
Young Yang
Please mark the replies as answers if they help or unmark if not.
Feedback to us
I have tried doing virtual path but I am missing a few pieces of information. What is ~/myspecialtemplateserver? Is this a virtual directory in iis? When I return this file, can I specify it in my razor view as my layout?
Such that Layout = GetFile("webserver/iisFolder/interestingLayouts")
Xequence
Contributor
4313 Points
1528 Posts
mvc3 use external layout page
Apr 03, 2012 04:43 PM|LINK
I am attempting to build a preview functionality that allows the user to see the page as if it were in the live site. The thing I want to do is load that external layout file without having to copy the views or setup the global asax in the local project.
Credentials
Xequence
Contributor
4313 Points
1528 Posts
Re: mvc3 use external layout page
Apr 03, 2012 06:00 PM|LINK
Maybe I am asking this wrong. Virtualpathprovider allows me to render a view as a string. The issue with this, is I want to render my layout page from a different project. This said view, has many different routes and scripts and css style, is in a live version of the website and I would like to be able to show a preview without having to add the same routes and scripts and pretty much every file into my administration project.
Here is what I have so far, but I am lost as how to load my layout this way.
using System; using System.IO; using System.Text; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Hosting; namespace VirtualPathProviderExample.Core { public class ExampleVirtualPathProvider : VirtualPathProvider { private readonly string testAspxContent = "<%@ Page Language=\"C#\" MasterPageFile=\"~/Views/Shared/Site.Master\" Inherits=\"System.Web.Mvc.ViewPage\" %><asp:Content ID=\"indexTitle\" ContentPlaceHolderID=\"TitleContent\" runat=\"server\">Test Page</asp:Content><asp:Content ID=\"indexContent\" ContentPlaceHolderID=\"MainContent\" runat=\"server\"><h2><%= Html.Encode(ViewData[\"Message\"]) %></h2><br /><p>This is file by the name of <strong>~/Views/Home/Test.aspx</strong></p><p>This is a page that does not exist in anywhere but still it's there :D by means of VirtualPathProvider.</p></asp:Content>"; List<VirtualFile> virtualFiles = new List<VirtualFile>(); public ExampleVirtualPathProvider() { virtualFiles.Add(new SimpleVirtualFile("~/Views/Home/Test.aspx", testAspxContent)); } public override bool FileExists(string virtualPath) { List<VirtualFile> files = (from f in virtualFiles where f.VirtualPath.Equals(virtualPath) select f).ToList(); if (files.Count > 0) return true; else return base.FileExists(virtualPath); } private class SimpleVirtualFile : VirtualFile { private string content; public SimpleVirtualFile(string filename, string content) : base(filename) { this.content = content; } public override Stream Open() { ASCIIEncoding encoding = new ASCIIEncoding(); return new MemoryStream(encoding.GetBytes(content), false); } } public override VirtualFile GetFile(string virtualPath) { List<VirtualFile> files = (from f in virtualFiles where f.VirtualPath.Equals(virtualPath) select f).ToList(); if (files.Count > 0) { return files[0]; } else return base.GetFile(virtualPath); } public override bool DirectoryExists(string virtualDir) { return base.DirectoryExists(virtualDir); } public override VirtualDirectory GetDirectory(string virtualDir) { return base.GetDirectory(virtualDir); } } }I guess, long story short, I should probably wire up the site to accept parameters on some authenticated section of the site.
I certain cannot do this because I get a virtualpath error.
@model SF.Library.WebContent.ContentPageEdit @{ //ViewBag.Title = TempData["title"].ToString() + System.Configuration.ConfigurationManager.AppSettings["AppendAllPageTitles"].ToString(); Layout = "http://www.mysite.com/views/shared/_layout.cshtml"; } @{ ViewBag.Title = "Preview"; } <h2>Preview</h2> <div class="faq"> @{ var displayMessage = TempData["DisplayMessage"]; if (displayMessage != null) { if (displayMessage.ToString().ToLower().Contains("error")) { <div> <p> <font color="red">@displayMessage</font></p> </div> } else { <div> <p>@displayMessage</p> </div> } } } @Html.Raw(HttpUtility.HtmlDecode(@Model.ContentBody)) </div>Credentials
Xequence
Contributor
4313 Points
1528 Posts
Re: mvc3 use external layout page
Apr 03, 2012 06:09 PM|LINK
my error:
Server Error in '/' Application.
'http:/www.xxx.com/views/shared/xxx/_layout.cshtml' is not a valid virtual path.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: 'http:/www.xxx.com/views/shared/xxx/_layout.cshtml' is not a valid virtual path.
Source Error:
Stack Trace:
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
Credentials
ryanw51
Contributor
2363 Points
511 Posts
Re: mvc3 use external layout page
Apr 03, 2012 07:37 PM|LINK
You can't load a layout page from another domain. The layout page has to be contained within the solution.
ignatandrei
All-Star
135077 Points
21664 Posts
Moderator
MVP
Re: mvc3 use external layout page
Apr 03, 2012 09:16 PM|LINK
You can not see directly any view in the views folder. Rather, make an action that returns a view.
Xequence
Contributor
4313 Points
1528 Posts
Re: mvc3 use external layout page
Apr 03, 2012 09:54 PM|LINK
What if I am on the same domain?
Credentials
ryanw51
Contributor
2363 Points
511 Posts
Re: mvc3 use external layout page
Apr 04, 2012 02:33 AM|LINK
has to be in the same project. The views have to be able to compile together. There are ways to get layouts to compile across multiple projects in the same solution (Orchard CMS does this) but you'll have to write a bunch of custom code to make it happen.
Xequence
Contributor
4313 Points
1528 Posts
Re: mvc3 use external layout page
Apr 04, 2012 01:48 PM|LINK
What if my layout has custom controller calls? Won't these fail?
Credentials
Young Yang -...
All-Star
21343 Points
1818 Posts
Microsoft
Re: mvc3 use external layout page
Apr 10, 2012 06:47 AM|LINK
Hi
Make a VirtualPathProvider that handles virtual paths that start with a magic token and passes all other paths to its Previous property. For example:
public override VirtualFile GetFile(string virtualPath) { if (virtualPath.StartsWith("~/MySpecialTemplateServer")) return new MyServerVirtualFile(virtualPath); else return Previous.GetFile(virtualPath); }Hope this helpful
Regards
Young Yang
Feedback to us
Develop and promote your apps in Windows Store
Xequence
Contributor
4313 Points
1528 Posts
Re: mvc3 use external layout page
Apr 10, 2012 01:50 PM|LINK
I have tried doing virtual path but I am missing a few pieces of information. What is ~/myspecialtemplateserver? Is this a virtual directory in iis? When I return this file, can I specify it in my razor view as my layout?
Such that Layout = GetFile("webserver/iisFolder/interestingLayouts")
or
Layout = GetFile("remoteServer/iisFolder/christmasLayout")
Credentials