它与此类似 – https://examples.wufoo.com/forms/workshop-registration/
我需要用户能够自定义页面设计.
不仅要上传自定义css,还要自定义HTML页面模板.
假设用户应该完全控制Layout的自定义webform页面的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我能够从数据库加载View,但它只返回如下文本:
@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’的第一个参数’ (你错过了使用指令或程序集引用吗?)“
当我将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’”
UPDATE3:
我试着使用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,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); } } }
在这种情况下,我得到一个根本没有被解析的视图,这是我在Web浏览器中得到的:
@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> -->
解决方法
这里有几个问题.只需搜索VirtualPathProvider
更新(从我的评论到问题讨论)
>必须使用HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider())在Application_Start中注册VirtualPathProvider;>必须为您当前无法提供服务的所有文件调用基类.这是必需的,因为只能有一个VirtualPathProvider. (否则会看到很多奇怪的错误)> @model指令在您提供的文件中不起作用.您必须使用@inherits System.Web.Mvc.WebViewPage< YourNameSpace.YourModelName>代替.> IIRC您还需要覆盖GetCacheDependency并为您自己的资源返回null.