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

Umbraco 8中GetDirtyProperties与IsPropertyDirty方法异常求助

Umbraco 8.2.2 解决ContentService.Saving脏属性误判问题

解决思路

直接绕过Umbraco自带的GetDirtyProperties()或IsPropertyDirty()方法,手动对比属性的原始值与当前值,针对容易误判的属性类型做专属处理。

具体实现

  1. 获取原始值与当前值
    通过content.GetOriginalValue(propertyAlias)拿到属性修改前的原始值,用content.GetValue(propertyAlias)获取当前提交的值。
  2. 分类型精准对比
    • 文本类属性:将null统一转为空字符串,若原始值和当前值均为空则不算脏状态,否则直接对比字符串内容。
    • 多节点选择器(MNTP):这类属性存储为逗号分隔的节点ID字符串,先处理空值为空白字符串,再拆分ID并排序后对比——避免因ID顺序变动被误判为修改。
  3. 封装通用判断方法
    把对比逻辑封装成可复用的方法:
private bool IsPropertyActuallyDirty(IContent content, string propertyAlias)
{
    var originalValue = content.GetOriginalValue(propertyAlias);
    var currentValue = content.GetValue(propertyAlias);

    // 统一处理null为空字符串
    var originalStr = originalValue?.ToString() ?? string.Empty;
    var currentStr = currentValue?.ToString() ?? string.Empty;

    // 多节点选择器特殊处理
    var propertyType = content.PropertyTypes.First(x => x.Alias == propertyAlias);
    if (propertyType.EditorAlias == "Umbraco.MultiNodeTreePicker")
    {
        // 拆分ID并排序,避免顺序差异导致误判
        var originalIds = string.IsNullOrEmpty(originalStr) 
            ? new List<int>() 
            : originalStr.Split(',').Select(int.Parse).OrderBy(x => x).ToList();
        var currentIds = string.IsNullOrEmpty(currentStr) 
            ? new List<int>() 
            : currentStr.Split(',').Select(int.Parse).OrderBy(x => x).ToList();
        
        return !originalIds.SequenceEqual(currentIds);
    }

    // 文本类直接对比字符串
    return originalStr != currentStr;
}
  1. 在Saving事件中应用自定义判断
    遍历预先定义的属性列表,用上述方法检查是否存在真修改的属性,再执行日志等操作:
public void Initialize()
{
    ContentService.Saving += ContentService_Saving;
}

private void ContentService_Saving(IContentService sender, ContentSavingEventArgs e)
{
    // 替换成你需要监控的属性别名列表
    var watchPropertyAliases = new List<string> { "articleTitle", "contentBody", "relatedArticles" };

    foreach (var content in e.SavedEntities)
    {
        bool hasModifiedProperty = watchPropertyAliases.Any(alias => IsPropertyActuallyDirty(content, alias));

        if (hasModifiedProperty)
        {
            // 这里执行你的日志记录或其他业务操作
            // 示例:LogHelper.Info(typeof(YourEventHandler), $"内容 {content.Name}(ID:{content.Id})的目标属性已修改");
        }
    }
}

额外提醒

  • 若还有其他易误判的属性类型(如媒体选择器、日期时间),可在IsPropertyActuallyDirty方法中扩展对应对比逻辑,比如日期需注意时间精度问题。
  • Umbraco 8.2.2版本的GetOriginalValue方法可可靠获取修改前的原始值,不会出现自带脏属性判断的误判问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:10:20