在Umbraco 7.0.3 I中:
- 使用宏容器的属性编辑器创建了一个名为宏容器的数据类型
- 已创建名为Contact Form的文档类型,其属性名为Body,类型为宏容器
- 已创建名为_contactForm.cshtml的局部视图(在Views\MacroPartials中)
- 使用MVC创建名为Contact Form的宏部分视图_contactFrom.chtml
- 添加了名为"联系我们"的联系表格类型的内容
- 在我的"联系我们"页面中,将"联系表格"宏添加到名为"正文"的"宏容器"属性中
然后我有一个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" /-->
所以现在我需要呈现这个宏\窗体\局部视图。。。我认为我可能需要在Controller中完成,但如果我能在另一端(通过Javascript)完成,那也会很好。我可以在控制器中调用Umbraco函数来基于页面id和宏别名呈现宏吗?
因此,在花了几个小时对Umbraco
团队做出的这个过程是多么愚蠢感到愤怒之后,我终于找到了一种相当丑陋但有效的方法。。。如果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
,这可能会干净得多。当然,也许有更好的方法可以做到这一点,如果是这样的话,我洗耳恭听。
难道不能使用umbraco.library.RenderMacroContent吗?
控制器名称中需要包含"Surface"。
JsSurfaceController
另外,将[HttpPost]属性添加到ActionResult方法中。
http://our.umbraco.org/documentation/Reference/Mvc/surface-controllershttp://our.umbraco.org/documentation/Reference/Mvc/forms