gpt4 book ai didi

asp.net-mvc - ASP MVC3 - 如何从数据库加载页面的自定义用户定义布局?

转载 作者:行者123 更新时间:2023-12-04 11:58:36 25 4
gpt4 key购买 nike

我在带有 Razor View 的 ASP.NET MVC3 中有在线表单生成器应用程序。
与此类似 - https://examples.wufoo.com/forms/workshop-registration/

我需要用户能够自定义页面设计。
不仅要上传自定义css,还要自定义HTML页面模板。
假设用户应该完全控制其自定义 Web 表单页面的布局 HTML。除了包含在布局中的表单之外,用户应该能够编辑页面上的任何 HTML。

我不确定如何使用 Razor 和 ASP.NET MVC 3 来做到这一点。
是否有可能:

  • 从数据库的某处加载布局作为字符串或其他
  • 将一些自定义标签(如“FORM1_INCLUDE”)替换为
    @Html.Partial("some_non_customizable_layout_for_form1")
  • 将结果用作用户表单页面的有效布局文件

  • 也许 1-3 不是做我需要的最好的方法。
    对于带有 Razor View 的 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
    自定义 View 提供程序在 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 View 代码,我得到了这个异常:

    “编译器错误消息:CS1061:‘System.Web.Mvc.AjaxHelper’不包含‘BeginForm’的定义,并且找不到接受‘System.Web.Mvc.AjaxHelper’类型的第一个参数的扩展方法‘BeginForm’ (您是否缺少 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);
    }
    }
    }

    在这种情况下,我得到了一个根本没有解析的 View ,这就是我在 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> -->

    最佳答案

    您应该创建一个从数据库中获取自定义 View 的虚拟路径提供程序。

    这里有几个关于它们的问题。只需搜索 VirtualPathProvider

    更新(从我对问题讨论的评论)

  • VirtualPathProvider 必须使用 HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider()); 在 Application_Start 中注册。
  • 必须为您当前无法提供的所有文件调用基类。这是必需的,因为只能有一个 VirtualPathProvider . (否则你会看到很多奇怪的错误)
  • @model指令在您提供的文件中不起作用。您必须使用 @inherits System.Web.Mvc.WebViewPage<YourNameSpace.YourModelName>反而。
  • IIRC 你还需要覆盖 GetCacheDependency并返回 null为您自己的资源。
  • 关于asp.net-mvc - ASP MVC3 - 如何从数据库加载页面的自定义用户定义布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7929561/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com