You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Umbraco Surface Controller疑问及动态按钮实现咨询

Umbraco Surface Controller 问题与动态按钮实现咨询

一、Surface Controller 404 问题

我刚接触Umbraco,对Surface Controller文档中的黄色高亮语句存在疑问。

以下是我的代码:

using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.Controllers;
using Umbraco.Cms.Web.Website.Controllers;
using UmbracoTest.Infrastructure;
using UmbracoTest.Model;

namespace UmbracoTest.Controllers
{
  public class SectionOptionsController : SurfaceController
  {
    public SectionOptionsController(IUmbracoContextAccessor umbracoContextAccessor, 
    IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches 
    appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider 
    publishedUrlProvider) : base(umbracoContextAccessor, databaseFactory, services, 
    appCaches, profilingLogger, publishedUrlProvider)
    {
    }

    [HttpPost]
    public async Task<IEnumerable<DummyModel>> GetAllDataFromDBAsync()
    {
        //returns list of data
    }
   }
 }

使用Postman调用接口 https://localhost:44327/Umbraco/surface/SectionOptions/GetAllDataFromDBAsync 时返回404,预期应返回数据列表。

二、动态按钮场景实现方案咨询

需要实现以下需求:

  • UI中有一个可在不同内容页面复用的动态按钮
  • 点击按钮后显示数据库中的对应数据表格
  • 动态按钮需接收id/标识,以此确定显示哪组数据
  • id/标识由内容编辑人员在各内容页面根据数据需求配置

问题解答与实现方案

1. Surface Controller 404 问题排查与解决

Surface Controller的核心特性是和Umbraco页面绑定,若要做纯数据接口,更适合用UmbracoApiController,以下是具体调整方案:

  • 替换控制器继承类:将SurfaceController改为UmbracoApiController,路由格式变为https://localhost:44327/Umbraco/Api/SectionOptions/GetAllDataFromDBAsync
  • 修正返回类型:Surface Controller的Action需返回IActionResult(如JsonResult),而非直接返回集合,修改后的Action示例:
[HttpPost]
public async Task<IActionResult> GetAllDataFromDBAsync()
{
    var data = // 数据获取逻辑
    return Json(data);
}

若坚持使用Surface Controller,需确保请求关联到某个Umbraco页面(携带页面上下文),否则路由无法匹配。

2. 动态按钮场景实现方案

步骤1:配置后台属性
  • 在Umbraco后台创建数据类型(如文本框/下拉列表),用于编辑人员输入数据组ID
  • 在需要复用按钮的文档类型中添加该属性,命名为DataGroupId
步骤2:创建可复用Partial View

创建~/Views/Partials/DynamicDataButton.cshtml,代码如下:

@inherits UmbracoViewPage
@{
    var dataGroupId = Model.Value<string>("DataGroupId");
}

<button id="load-data-btn" data-group-id="@dataGroupId">加载数据表格</button>
<div id="data-table-container"></div>

<script>
    document.getElementById('load-data-btn').addEventListener('click', async function() {
        const groupId = this.dataset.groupId;
        if (!groupId) {
            alert('请配置数据组ID');
            return;
        }
        
        try {
            const response = await fetch('/Umbraco/Api/SectionOptions/GetDataByGroupId', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ groupId })
            });
            
            if (response.ok) {
                const data = await response.json();
                // 渲染表格
                let tableHtml = '<table><thead><tr><th>字段1</th><th>字段2</th></tr></thead><tbody>';
                data.forEach(item => {
                    tableHtml += `<tr><td>${item.Field1}</td><td>${item.Field2}</td></tr>`;
                });
                tableHtml += '</tbody></table>';
                document.getElementById('data-table-container').innerHTML = tableHtml;
            } else {
                alert('加载数据失败');
            }
        } catch (error) {
            console.error(error);
            alert('加载数据出错');
        }
    });
</script>
步骤3:创建数据接口控制器

修改控制器为UmbracoApiController,添加按ID查询的Action:

using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Web.Common.Controllers;
using UmbracoTest.Infrastructure;
using UmbracoTest.Model;

namespace UmbracoTest.Controllers
{
    public class SectionOptionsController : UmbracoApiController
    {
        private readonly IUmbracoDatabaseFactory _databaseFactory;

        public SectionOptionsController(IUmbracoContextAccessor umbracoContextAccessor, 
            IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, 
            IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider) 
            : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
        {
            _databaseFactory = databaseFactory;
        }

        [HttpPost]
        public async Task<IEnumerable<DummyModel>> GetDataByGroupId([FromBody] dynamic request)
        {
            var groupId = request.groupId.ToString();
            using var db = _databaseFactory.CreateDatabase();
            // 按groupId查询数据的逻辑
            var data = await db.FetchAsync<DummyModel>("WHERE GroupId = @0", groupId);
            return data;
        }
    }
}
步骤4:在页面中复用组件

在需要显示按钮的模板或页面中,引用Partial View即可:

@Html.Partial("~/Views/Partials/DynamicDataButton.cshtml", Model)

内容的提问来源于stack exchange,提问作者Eduwow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:13:21