Umbraco 7.12.4会员板块访问报错:LastActivityDate属性不支持
咱们先来拆解下你遇到的问题:你用Umbraco 7.12.4,通过AD LDS实例同时验证后台用户和会员,但在访问后台会员板块时抛出了以下异常:
System.NotSupportedException: The property 'LastActivityDate' is not supported by the Active Directory membership provider
这个问题的核心其实和AD LDS本身无关——标准的ActiveDirectoryMembershipProvider(不管对接完整AD还是AD LDS)都不支持LastActivityDate属性,因为AD体系里没有专门存储用户活跃时间的字段,而Umbraco的会员管理界面在加载时会默认尝试读取这个属性,从而触发异常。
问题根源确认
先看你的Web.config配置,你为UmbracoMembershipProvider指定了ActiveDirectoryMembershipProvider,而Umbraco后台的会员管理逻辑会调用这个提供者的GetUser方法,尝试获取LastActivityDate属性,而AD的会员提供者明确不支持这个属性,所以直接抛出了不支持的异常。
<providers> <add name="BackofficeMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" attributeMapUsername="userPrincipalName" connectionUsername="username@example.com" connectionPassword="password" connectionProtection="None" /> <add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" /> <add name="UmbracoMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" attributeMapUsername="userPrincipalName" connectionUsername="username@example.com" connectionPassword="password" enableSearchMethods="true" connectionProtection="None"/> </providers>
可行的解决方案
方案一:自定义会员提供者(推荐)
创建一个自定义的MembershipProvider,包装ActiveDirectoryMembershipProvider,重写那些会访问LastActivityDate的方法,返回一个默认值来避免异常。步骤如下:
- 创建一个类库项目,添加一个继承自
ActiveDirectoryMembershipProvider的类:
using System; using System.Web.Security; namespace YourCustomNamespace { public class AdLdsUmbracoMembershipProvider : ActiveDirectoryMembershipProvider { public override MembershipUser GetUser(string username, bool userIsOnline) { var user = base.GetUser(username, userIsOnline); // 重写LastActivityDate为默认值,避免Umbraco读取时抛出异常 if (user != null) { user = new MembershipUser( Name, user.UserName, user.ProviderUserKey, user.Email, user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut, user.CreationDate, DateTime.Now, // 替换为当前时间或你需要的默认值 user.LastLoginDate, user.LastPasswordChangedDate, user.LastLockoutDate ); } return user; } public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { var user = base.GetUser(providerUserKey, userIsOnline); if (user != null) { user = new MembershipUser( Name, user.UserName, user.ProviderUserKey, user.Email, user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut, user.CreationDate, DateTime.Now, user.LastLoginDate, user.LastPasswordChangedDate, user.LastLockoutDate ); } return user; } } }
编译类库,将生成的DLL放到Umbraco网站的
bin目录下。修改Web.config中的
UmbracoMembershipProvider配置,指向你自定义的提供者:
<add name="UmbracoMembershipProvider" type="YourCustomNamespace.AdLdsUmbracoMembershipProvider, YourAssemblyName" connectionStringName="ADConnectionString" attributeMapUsername="userPrincipalName" connectionUsername="username@example.com" connectionPassword="password" enableSearchMethods="true" connectionProtection="None"/>
方案二:临时修改会员板块视图(不推荐)
如果你不想自定义提供者,可以尝试修改Umbraco后台会员视图的代码,但不推荐,因为这会修改Umbraco核心文件,后续升级会很麻烦。具体来说,找到后台会员列表的视图文件(通常在~/umbraco/Views/members/index.cshtml),移除所有涉及LastActivityDate的代码逻辑。
额外注意事项
- 后台用户的
BackofficeMembershipProvider用AD LDS是没问题的,因为Umbraco后台用户管理逻辑不会强制读取LastActivityDate属性,只有会员板块会触发这个问题。 - 确保你的AD LDS连接配置正确,
connectionUsername和connectionPassword有足够的权限读取AD LDS中的用户信息。
内容的提问来源于stack exchange,提问作者Josh Withee

