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(); } }
关键注意事项
- 会员与表单关联:确保表单中有存储会员ID的字段(如隐藏字段,默认值设为
@CurrentMember.Key),才能准确关联会员和班级记录。 - 服务注入规则:Umbraco 11中所有Forms操作必须通过依赖注入服务,禁止直接实例化存储类。
- 切换状态存储:可选择Session(临时状态)或会员属性(永久状态)保存选中班级,按需选择。
- Request.Form的限制:
Request.Form仅在POST请求时有效,之前尝试无效是因为页面为GET请求,无法获取表单字段值。
内容的提问来源于stack exchange,提问作者michumeliora
相关产品推荐
相关产品推荐

