【问题标题】:Umbraco 7 Partial View Macro RenderingUmbraco 7 局部视图宏渲染
【发布时间】:2014-02-20 05:43:54
【问题描述】:

在 Umbraco 7.0.3 I 中:

  1. 使用宏容器的属性编辑器创建了一个名为宏容器的数据类型
  2. 创建的文档类型称为联系表单,属性称为正文,类型为宏容器
  3. 创建了名为 _contactForm.cshtml 的局部视图(在 Views\MacroPartials 中)
  4. 使用 MVC 部分视图 _contactFrom.cshtml 创建了名为 Contact Form 的宏
  5. 添加了名为“联系我们”的联系表单类型的内容
  6. 在我的联系我们页面中的宏容器属性中添加了联系表单宏

然后我有一个Surface Controller,我用一些AJAX 调用它来显示页面(更具体地说是页面的Body 属性):

public class JsController : SurfaceController
{
    public ActionResult GetPage(int id)
    {
        var page = new Node(id);

        if (page == null || page.GetProperty("body") == null)
            return Content(@"Hmm, something went wrong. Unable to find what you're looking for.");

        return Content(page.GetProperty("body").Value);
    }
}

这个设置几乎可以工作,但问题是返回的不是渲染的表单,而是:

<!--?UMBRACO_MACRO macroAlias="ContactForm" /-->

所以现在我需要渲染这个宏\表单\部分视图...我认为我可能需要在控制器中执行此操作,但如果我可以在另一侧(通过 Javascript)执行此操作,则可以作为好。我可以在控制器中调用 Umbraco 函数来根据页面 id 和宏别名呈现宏吗?

【问题讨论】:

    标签: c# ajax asp.net-mvc-4 umbraco7 surface-controller


    【解决方案1】:

    所以在花了几个小时对Umbraco 团队制作这个过程的愚蠢程度感到愤怒之后,阅读了this 和this 之类的线程,我终于想出了一个相当丑陋但有效的方法......事情本来可以如果PublishedContentRequest 类构造函数不是internal,那就简单多了!

    无论如何,这就是我必须做的: 1) 扩展EnsurePublishedContentRequestAttribute

    public class CreatePublishedContentRequestAttribute
        : EnsurePublishedContentRequestAttribute
    {
        public CreatePublishedContentRequestAttribute() : base(0) { }
    
        protected override void ConfigurePublishedContentRequest(
            PublishedContentRequest publishedContentRequest,
            ActionExecutedContext filterContext)
        {
            var contentId = filterContext.RouteData.Values["id"];
            int id = 0;
    
            if (contentId != null && int.TryParse(contentId.ToString(), out id))
            {
                var content = UmbracoContext.ContentCache.GetById(id);
                publishedContentRequest.PublishedContent = content;
    
                var defaultLanguage = Language.GetAllAsList().FirstOrDefault();
                publishedContentRequest.Culture = (defaultLanguage == null)
                    ? CultureInfo.CurrentUICulture
                    : new CultureInfo(defaultLanguage.CultureAlias);
    
                publishedContentRequest.ConfigureRequest();
    
                HttpContext.Current.Session["PublishedContentRequest"]
                    = publishedContentRequest;
            }
        }
    }
    

    2) 重定向到使用此属性修饰的操作,该属性重定向回我的 GetPage 操作并从 Session 检索 PCR。现在我们可以渲染我们的宏了:

    public ActionResult GetPage(int id)
    {
        var publishedContent = UmbracoContext.ContentCache.GetById(id);
        if (publishedContent == null || publishedContent.GetProperty("body") == null)
        { return Content(@"Unable to find what you're looking for."); }
    
        if (UmbracoContext.PublishedContentRequest == null
            && Session["PublishedContentRequest"] == null)
        { return RedirectToAction("CreatePublishedContentRequest", new { id }); }
    
        UmbracoContext.PublishedContentRequest =
            (PublishedContentRequest) Session["PublishedContentRequest"];
        Session["PublishedContentRequest"] = null;
    
        UmbracoContext.HttpContext.Items["pageID"] = id;
    
        return Content(GetHtmlContent(publishedContent));
    }
    
    [CreatePublishedContentRequest]
    public ActionResult CreatePublishedContentRequest(int id)
    {
        return RedirectToAction("GetPage", new { id });
    }
    
    private string GetHtmlContent(IPublishedContent publishedContent)
    {
        string content = publishedContent.GetProperty("body").Value.ToString();
        if (string.IsNullOrEmpty(content) || !content.Contains("UMBRACO_MACRO"))
        { return content;}
    
        int startIndex = content.IndexOf("macroAlias=") + 12;
        int length = content.LastIndexOf('"') - startIndex;
        var macroAlias = content.Substring(startIndex, length);
    
        return (Umbraco.RenderMacro(macroAlias) ?? new HtmlString("")).ToString();
    }
    

    这行得通,但这是一些非常老套的东西。如果Umbraco 团队创建了PublishedContentRequest 构造函数public,这可能会更干净。当然,可能有更好的方法来做到这一点,如果是这样,我全神贯注。

    【讨论】:

    • PublishedContentRequest 类构造函数现在在较新的 Umbraco 版本中公开,但我找不到此用例的适当用法。
    【解决方案2】:

    难道不能使用 umbraco.library.RenderMacroContent 吗?

    【讨论】:

    • 没有经过测试的代码示例的注释不是很有用。
    【解决方案3】:

    您的控制器名称需要在其名称中包含“Surface”。

    JsSurfaceController
    

    另外,将 [HttpPost] 属性添加到 ActionResult 方法中。

    http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers http://our.umbraco.org/documentation/Reference/Mvc/forms

    【讨论】:

    • 这些建议都不需要,甚至是错误的。 [HttpPost] 仅在我有 2 个具有相同名称的方法或者我试图阻止 GET 流量时才需要,我不是,实际上现在只有 GET 流量流向它......“表面”交易是只是一个建议……实际上并不需要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多