【发布时间】:2011-10-28 12:56:01
【问题描述】:
我在带有 Razor 视图的 ASP.NET MVC3 中有在线表单构建器应用程序。 和这个类似——https://examples.wufoo.com/forms/workshop-registration/
我需要用户能够自定义页面设计。 不仅可以上传自定义css,还可以自定义HTML页面模板。 假设用户应该完全控制其自定义 Web 表单页面的 Layout 的 HTML。除了包含在布局中的表单之外,用户应该能够编辑页面上的任何 HTML。
我不确定如何使用 Razor 和 ASP.NET MVC 3 做到这一点。 是否可以:
- 从数据库中以字符串或其他方式加载布局
- 将一些自定义标签(如“FORM1_INCLUDE”)替换为 @Html.Partial("some_non_customizable_layout_for_form1")
- 将结果用作用户表单页面的有效布局文件
也许 1-3 不是满足我需要的最佳方式。 对于带有 Razor 视图的 ASP.NET MVC 3 中这种用户定义的页面布局方法,您有什么建议?
更新 1 使用 VirtualPathProvider 我能够从数据库加载视图,但它只返回如下文本:
@inherits System.Web.Mvc.WebViewPage
<body>
@Html.EditorFor(z => z.Customer)
</body>
并且根本不处理任何 Razor 语法。 它可能有什么问题?
已解决:
需要将此行作为 Application_Start() 方法中的第一行:
HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider());
更新 2 Custom View Provider 在 Global.asax.cs 中注册为:
protected void Application_Start()
{
HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
MyVirtualPathProvider 代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using System.IO;
using System.Text;
namespace new_frontend
{
public class MyVirtualPathProvider : VirtualPathProvider
{
public override bool FileExists(string virtualPath)
{
var td = FindTemplate(virtualPath);
if (td == null)
{
return true;
//return base.FileExists(virtualPath);
}
else
{
return true;
}
}
public override VirtualFile GetFile(string virtualPath)
{
var td = FindTemplate(virtualPath);
if (td == null)
{
return new MyVirtualFile(virtualPath, "");
//return base.GetFile(virtualPath);
}
else
{
return new MyVirtualFile(virtualPath, td.ContentStep1);
}
}
private Facade.Dto.TemplateData FindTemplate(string virtualPath)
{
string prefix = "Template#";
int id = 0;
Facade.Dto.TemplateData td = null;
string fileName = System.IO.Path.GetFileNameWithoutExtension(virtualPath);
if (fileName.StartsWith(prefix))
Int32.TryParse(fileName.Substring(prefix.Length), out id);
if (id > 0)
td = Facade.FrontEndServices.GetTemplate(id);
return td;
}
}
public class MyVirtualFile : VirtualFile
{
private byte[] data;
public MyVirtualFile(string virtualPath, string body)
: base(virtualPath)
{ // 'System.Web.WebPages.ApplicationStartPage
string _body = /*body +*/ @"
@inherits System.Web.Mvc.WebViewPage
@using (Ajax.BeginForm(""Submit"", new AjaxOptions { UpdateTargetId = ""main"" }))
{
}
<!-- <PERSONAL_INFO> -->
<div id=""personal_info"" class=""op2-block"">
</div>
<!-- <PERSONAL_INFO> -->";
this.data = Encoding.UTF8.GetBytes(_body);
}
public override System.IO.Stream Open()
{
return new MemoryStream(data);
}
}
}
现在对于上面定义为字符串的 Razor 视图代码,我得到了这个异常:
“编译器错误消息:CS1061:‘System.Web.Mvc.AjaxHelper’不包含‘BeginForm’的定义,并且没有扩展方法‘BeginForm’接受‘System.Web.Mvc’类型的第一个参数.AjaxHelper' 可以找到(您是否缺少 using 指令或程序集引用?)"
当我将 Razor View 代码更改为:
string _body = /*body +*/ @"
@using System.Web.WebPages;
@using System.Web.Mvc;
@using System.Web.Mvc.Ajax;
@using System.Web.Mvc.Html;
@using System.Web.Routing;
@inherits System.Web.Mvc.WebViewPage<dynamic>
@using (Ajax.BeginForm(""Submit"", new AjaxOptions { UpdateTargetId = ""main"" }))
{
}
<!-- <PERSONAL_INFO> -->
<div id=""ppg_op2_personal_info"" class=""op2-block"">
</div>
<!-- <PERSONAL_INFO> -->";
我得到一个不同的错误:
类型“ASP._Page__appstart_cshtml”不继承自“System.Web.WebPages.ApplicationStartPage”
当我改变时
@inherits System.Web.Mvc.WebViewPage
到
@inherits System.Web.WebPages.ApplicationStartPage
为了修复上面的错误,我得到了一个新的:
“编译器错误消息:CS0103:名称 'Ajax' 在当前上下文中不存在”
更新3: 我尝试使用 base.XXX:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using System.IO;
using System.Text;
namespace new_frontend
{
public class MyVirtualPathProvider : VirtualPathProvider
{
public override bool FileExists(string virtualPath)
{
var td = FindTemplate(virtualPath);
if (td == null)
{
//return true;
return base.FileExists(virtualPath);
}
else
{
return true;
}
}
public override VirtualFile GetFile(string virtualPath)
{
var td = FindTemplate(virtualPath);
if (td == null)
{
//return new MyVirtualFile(virtualPath, "");
return base.GetFile(virtualPath);
}
else
{
return new MyVirtualFile(virtualPath, td.ContentStep1);
}
}
private Facade.Dto.TemplateData FindTemplate(string virtualPath)
{
string prefix = "Template#";
int id = 0;
Facade.Dto.TemplateData td = null;
string fileName = System.IO.Path.GetFileNameWithoutExtension(virtualPath);
if (fileName.StartsWith(prefix))
Int32.TryParse(fileName.Substring(prefix.Length), out id);
if (id > 0)
td = Facade.FrontEndServices.GetTemplate(id);
return td;
}
}
public class MyVirtualFile : VirtualFile
{
private byte[] data;
public MyVirtualFile(string virtualPath, string body)
: base(virtualPath)
{ // 'System.Web.WebPages.ApplicationStartPage
string _body = /*body +*/ @"
@inherits System.Web.Mvc.WebViewPage<PPG.Facade.Dto.NewOrderPageData>
@using (Ajax.BeginForm(""Submit"", new AjaxOptions { UpdateTargetId = ""main"" }))
{
}
<!-- <PERSONAL_INFO> -->
<div id=""personal_info"" class=""op2-block"">
</div>
<!-- <PERSONAL_INFO> -->";
this.data = Encoding.UTF8.GetBytes(_body);
}
public override System.IO.Stream Open()
{
return new MemoryStream(data);
}
}
}
在这种情况下,我得到一个根本没有解析的视图,这是我在网络浏览器中得到的:
@using System.Web.WebPages;
@using System.Web.Mvc;
@using System.Web.Mvc.Ajax;
@using System.Web.Mvc.Html;
@using System.Web.Routing;
@inherits System.Web.Mvc.WebViewPage<PPG.Facade.Dto.NewOrderPageData>
@using (Ajax.BeginForm("Submit", new AjaxOptions { UpdateTargetId = "main" }))
{
}
<!-- <PERSONAL_INFO> -->
<div id="ppg_op2_personal_info" class="op2-block">
</div>
<!-- <PERSONAL_INFO> -->
【问题讨论】:
-
您如何使用您的视图?你不应该直接使用你的提供者,而是注册它而不是默认的。
-
@gauffin 我创建了 UPDATE2 来回答关于视图使用的问题。
-
VirtualPathProvider 只能有一个。您需要为您无法处理的所有文件调用
base.XXXX。另外:您的所有视图都必须继承@inherits System.Web.Mvc.WebViewPage<Namespace.YourModelName>才能进行强类型化。 -
base.XXXX - 当然。但这与上述问题无关。 @inherits System.Web.Mvc.WebViewPage
这是我尝试的第一件事。上面描述的问题发生在强类型视图和没有它们的情况下。 -
这个错误:Type 'ASP.Page_appstart_cshtml' does not inherit from 'System.Web.WebPages.ApplicationStartPage 很奇怪。当我使用
@inherits System.Web.Mvc.WebViewPage<Namespace.AnyModel>或仅使用@inherits System.Web.Mvc.WebViewPage时会发生这种情况
标签: asp.net-mvc asp.net-mvc-3 razor