如何在Kentico门户设计模式下输出Repeater的原生JSON页面
我之前在Kentico里遇到过完全一样的需求,给你几个可行的方案,既能保留门户设计界面的可管理性,又能输出纯JSON内容:
方案一:ASPX+空白门户模板组合(推荐)
这个方案既保留了Kentico设计界面中Web部件的可编辑性,又能彻底清除所有冗余页面包装:
创建空白ASPX页面模板
新建一个ASPX文件(比如JSONPortalTemplate.aspx),不要继承任何母版页,只保留门户占位符:<%@ Page Language="C#" AutoEventWireup="true" CodeFile="JSONPortalTemplate.aspx.cs" Inherits="JSONPortalTemplate" %> <cms:PortalPlaceholder ID="plcMain" runat="server" />修改代码后置文件
在对应的.aspx.cs文件中,通过页面生命周期事件清除默认输出并设置JSON响应头:using System.IO; using System.Web.UI; public partial class JSONPortalTemplate : CMS.PortalEngine.Web.UI.PortalTemplatePage { protected void Page_PreRender(object sender, EventArgs e) { // 设置响应类型为JSON Response.ContentType = "application/json"; // 清除页面默认的输出缓冲区(去掉ASP.NET表单、空HTML结构) Response.Clear(); // 找到页面中的Repeater Web部件(假设你给它的ID是rptJSONData) var repeater = plcMain.FindControl("rptJSONData") as CMS.PortalEngine.Web.UI.RepeaterWebPart; if (repeater != null) { // 将Repeater的输出渲染到字符串 StringWriter sw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(sw); repeater.RenderControl(hw); // 输出纯JSON内容 Response.Write(sw.ToString()); } // 终止响应,防止后续任何冗余输出 Response.End(); } }配置Repeater的JSON模板
在Kentico设计界面中,给这个页面添加Repeater Web部件,配置好数据源(比如文档类型、自定义查询),然后修改Repeater的模板为纯JSON格式:<HeaderTemplate>[</HeaderTemplate> <ItemTemplate> { "id": <%# Eval("DocumentID") %>, "title": "<%# Eval("DocumentName").ToString().Replace("\"", "\\\"") %>", "content": "<%# Eval("DocumentContent").ToString().Replace("\"", "\\\"").Replace("\n", "\\n") %>" }<%# Container.ItemIndex != (repeater.DataSource as System.Data.DataView).Count - 1 ? "," : "" %> </ItemTemplate> <FooterTemplate>]</FooterTemplate>这里要注意转义JSON中的特殊字符(比如双引号、换行符),避免生成无效的JSON。
应用模板并测试
在Kentico中创建页面时选择这个ASPX模板,保存后访问页面,就能得到纯JSON输出了,管理员还能随时在设计界面修改Repeater的数据源、字段或模板。
方案二:自定义JSON Repeater Web部件(纯门户模式)
如果不想依赖ASPX模板,你可以自定义一个继承自Repeater的Web部件,让它直接输出JSON并终止响应:
创建自定义Web部件类
在你的Kentico项目中添加一个类文件,代码如下:using CMS.PortalEngine.Web.UI; using System.IO; using System.Web.UI; public class JSONRepeaterWebPart : RepeaterWebPart { protected override void Render(HtmlTextWriter writer) { // 覆盖默认渲染逻辑 Response.ContentType = "application/json"; Response.Clear(); // 渲染Repeater的JSON内容到字符串 StringWriter sw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(sw); base.Render(hw); // 输出JSON并终止响应 Response.Write(sw.ToString()); Response.End(); } }注册Web部件到Kentico
在Kentico的Web部件库中注册这个自定义Web部件,之后就能在门户设计界面中像普通Repeater一样添加它,配置数据源和JSON模板即可。注意:如果后续需要添加其他Web部件,这个方案因为用了
Response.End()会导致其他Web部件无法输出。如果需要多个Web部件的内容整合到JSON中,你可以去掉Response.End(),同时给页面设置一个完全空白的母版页(没有HTML头部、body、表单),让所有Web部件都输出JSON片段,最后组合成完整的JSON结构。
方案三:ASHX Handler(无设计界面管理)
如果上述方案对你来说太复杂,直接用ASP.NET ASHX Handler也是个简单的选择,不过会失去Kentico设计界面的可管理性:
创建一个ASHX文件(比如ContentJSON.ashx),用Kentico API获取数据并生成JSON:
using System.Web; using CMS.DocumentEngine; using CMS.SiteProvider; using Newtonsoft.Json; public class ContentJSON : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/json"; // 用Kentico API获取数据(示例:获取当前站点的所有新闻文档) var newsItems = DocumentHelper.GetDocuments("CMS.News") .OnCurrentSite() .Published() .Select(n => new { ID = n.DocumentID, Title = n.DocumentName, Summary = n.NewsSummary }) .ToList(); // 序列化为JSON并输出 string json = JsonConvert.SerializeObject(newsItems); context.Response.Write(json); } public bool IsReusable => false; }
这个方法不需要依赖Kentico的门户模式,直接通过API获取数据,但管理员无法在Kentico界面中修改数据逻辑,适合不需要频繁调整的场景。
内容的提问来源于stack exchange,提问作者John K

