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

Umbraco 11中会员绑定班级切换的Razor视图实现问询

Umbraco 11 Razor视图实现会员绑定的班级切换方案

核心说明

Umbraco Forms 10+(对应Umbraco 11)已废弃UmbracoFormsStorage这类直接实例化的存储类,全部改用依赖注入的服务接口。无需手动实例化存储类,通过@inject引入官方服务即可操作表单和记录。

步骤1:注入正确的服务

在Razor视图顶部添加所需服务注入:

@inject Umbraco.Forms.Core.Services.IFormService FormService
@inject Umbraco.Forms.Core.Services.IRecordService RecordService
@inject Umbraco.Cms.Core.IPublishedContentQuery PublishedContentQuery

步骤2:获取当前会员的班级关联记录

需先找到当前会员在目标表单中提交的记录,从中提取绑定的班级ID。假设表单中用memberId字段存储会员ID(若无此字段,建议添加隐藏字段自动填充会员ID),完整修正代码如下:

完整Razor代码示例

@inherits UmbracoViewPage<SiteBuilderBaseViewModel>
@using USNSiteBuilder.Core.Models
@using Umbraco.Cms.Core.Security
@using Umbraco.Forms.Core.Models
@using Umbraco.Forms.Core.Services;
@using Umbraco.Cms.Core.Models.PublishedContent;

@inject IMemberManager MemberManager
@inject IFormService FormService
@inject IRecordService RecordService
@inject IPublishedContentQuery PublishedContentQuery

@{
    Layout = "USNMaster.cshtml";
    Usnstyle websiteStyle = (Usnstyle)Model.WebsiteStyle;

    var currentMember = await MemberManager.GetCurrentMemberAsync();
    List<IPublishedContent> userClasses = new List<IPublishedContent>();
    string selectedClassId = string.Empty;

    // 从Session读取当前选中的班级(切换状态存储)
    if (HttpContext.Session.TryGetValue("SelectedClassId", out byte[] classIdBytes))
    {
        selectedClassId = System.Text.Encoding.UTF8.GetString(classIdBytes);
    }

    if (currentMember != null)
    {
        // 目标表单GUID(去除前缀"umbraco_form_")
        var formGuid = Guid.Parse("2234732813ed4ada88a0370f2630e351");
        var targetForm = FormService.GetForm(formGuid);

        if (targetForm != null)
        {
            // 查询当前会员提交的表单记录
            var memberRecords = RecordService.GetRecordsByForm(formGuid)
                .Where(r => r.RecordFields.Any(f => 
                    f.Alias == "memberId" && 
                    f.Values.FirstOrDefault()?.ToString() == currentMember.Key.ToString()))
                .ToList();

            foreach (var record in memberRecords)
            {
                // 提取绑定的班级ID列表
                if (record.RecordFields.TryGetValue("registeredClasses", out var classField))
                {
                    var classIdsStr = classField.Values.FirstOrDefault()?.ToString();
                    if (!string.IsNullOrEmpty(classIdsStr))
                    {
                        var classIds = classIdsStr.Split(',', StringSplitOptions.RemoveEmptyEntries);
                        foreach (var classId in classIds)
                        {
                            if (Guid.TryParse(classId, out Guid contentGuid))
                            {
                                var classNode = PublishedContentQuery.Content(contentGuid);
                                if (classNode != null)
                                {
                                    userClasses.Add(classNode);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

@if (userClasses.Any())
{
    <div class="class-switcher">
        <h3>我的班级</h3>
        <!-- 班级切换按钮组 -->
        <div class="switch-buttons">
            @foreach (var classNode in userClasses)
            {
                var isSelected = classNode.Key.ToString() == selectedClassId;
                <form method="post" asp-action="SetSelectedClass" asp-controller="ClassSwitch">
                    <input type="hidden" name="classId" value="@classNode.Key" />
                    <button type="submit" class="btn @(isSelected ? "active" : "")">
                        @classNode.Value<string>("klassensNamn")
                    </button>
                </form>
            }
        </div>

        <!-- 当前选中班级详情 -->
        @if (!string.IsNullOrEmpty(selectedClassId) && Guid.TryParse(selectedClassId, out Guid selectedGuid))
        {
            var selectedClass = userClasses.FirstOrDefault(c => c.Key == selectedGuid);
            if (selectedClass != null)
            {
                <div class="class-details">
                    <h4>@selectedClass.Value<string>("klassensNamn")</h4>
                    <p>学年:@selectedClass.Value<string>("aarskull")</p>
                    <p>学校:@selectedClass.Value<string>("skolansNamn")</p>
                    <p>地址:@selectedClass.Value<string>("skolansAdress") @selectedClass.Value<string>("skolansPostnummer") @selectedClass.Value<string>("skolansPostort")</p>
                    <p>学生数:@selectedClass.Value<string>("antalElever")</p>
                    <p>教师:@selectedClass.Value<string>("pedagogensNamn")</p>
                </div>
            }
        }
    </div>
}
else
{
    <p>你还未绑定任何班级,请先完成注册。</p>
}

步骤3:添加班级切换的Surface Controller(推荐)

为避免在Razor中写过多POST逻辑,建议创建Surface Controller处理切换提交:

using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Web.Common.Controllers;

public class ClassSwitchController : SurfaceController
{
    private readonly IMemberManager _memberManager;

    public ClassSwitchController(IMemberManager memberManager)
    {
        _memberManager = memberManager;
    }

    [HttpPost]
    public IActionResult SetSelectedClass(string classId)
    {
        var currentMember = _memberManager.GetCurrentMemberAsync().Result;
        if (currentMember != null && Guid.TryParse(classId, out Guid classGuid))
        {
            // 方式1:临时存储到Session
            HttpContext.Session.SetString("SelectedClassId", classId);

            // 方式2:永久存储到会员属性(需先在会员类型中添加selectedClassId字段)
            // await _memberManager.UpdateMemberAsync(currentMember, new Dictionary<string, object>
            // {
            //     {"selectedClassId", classId}
            // });
        }

        // 重定向回原页面
        return RedirectToCurrentUmbracoPage();
    }
}

关键注意事项

  1. 会员与表单关联:确保表单中有存储会员ID的字段(如隐藏字段,默认值设为@CurrentMember.Key),才能准确关联会员和班级记录。
  2. 服务注入规则:Umbraco 11中所有Forms操作必须通过依赖注入服务,禁止直接实例化存储类。
  3. 切换状态存储:可选择Session(临时状态)或会员属性(永久状态)保存选中班级,按需选择。
  4. Request.Form的限制:Request.Form仅在POST请求时有效,之前尝试无效是因为页面为GET请求,无法获取表单字段值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:40:01