首页 > 解决方案 > Episerver – 为什么要绕过属性设置器?

问题描述

似乎内容模型设置器在从内部创建时仅被调用一次

SetDefaultValues(ContentType contentType)

我进行了一些测试:

1.创建新区块

  1. 尝试使用来自 的某些值设置属性SetDefaultValues
  2. 由于 setter 实现,使用了其他值。
[ContentType(DisplayName = "SetterTestsBlock", GUID = "43ca7e93-6982-4b95-b073-c42af6ad2315", Description = "")]
public class SetterTestsBlock : BlockData
{
  public virtual string SomeVirtualStringProperty
  {
    get => this.GetPropertyValue(t => t.SomeVirtualStringProperty);
    set { this.SetPropertyValue(t => t.SomeVirtualStringProperty, "Ahoj1"); }      
  }

  public string SomeStringProperty
  {
    get => this.GetPropertyValue(t => t.SomeStringProperty);
    set { this.SetPropertyValue(t => t.SomeStringProperty, "Ahoj2"); }    
  }

  public override void SetDefaultValues(ContentType contentType)
  {
    SomeVirtualStringProperty = "Čau1";
    SomeStringProperty = "Čau2";
  }
} 

结果在意料之中

在此处输入图像描述

2. 再次创建新区块

  1. 让 setter 抛出异常。
[ContentType(DisplayName = "SetterTestsBlock", GUID = "43ca7e93-6982-4b95-b073-c42af6ad2315", Description = "")]
public class SetterTestsBlock : BlockData
{
  public virtual string SomeVirtualStringProperty
  {
    get => this.GetPropertyValue(t => t.SomeVirtualStringProperty);
    //set { this.SetPropertyValue(t => t.SomeVirtualStringProperty, "Ahoj1"); }
    //set { }
    set { throw new Exception(); }
  }

  public string SomeStringProperty
  {
    get => this.GetPropertyValue(t => t.SomeStringProperty);
    //set { this.SetPropertyValue(t => t.SomeStringProperty, "Ahoj2"); }
    //set { }
    set { throw new Exception(); }
  }

  //public override void SetDefaultValues(ContentType contentType)
  //{
  //    SomeVirtualStringProperty = "Čau1";
  //    SomeStringProperty = "Čau2";
  //}
} 

这次的结果也是相当可期的

  1. 没有默认值覆盖调用=没有默认值,resp。没有例外。

在此处输入图像描述

3. 从测试 2 发布更改以阻止

  1. 在 CMS Web 界面中输入一些值。
  2. 发布更改。

在此处输入图像描述

这个结果并不那么令人期待

  1. CMS 未显示任何错误,因此未引发异常。

在此处输入图像描述

概括

  1. 仅从SetDefaultValues(ContentType contentType)方法调用属性设置器(在块首次创建期间)。
  2. 观察到的行为不依赖于属性虚拟性(virtual修饰符)。

问题

想象一下下面的代码说明的情况。

[ContentType(DisplayName = "RealUsageSimulation", GUID = "12737925-ab51-4f63-9144-cd4632244a1c", Description = "")]
public class RealUsageSimulation : BlockData
{
  public string SomeStrPropWithDependency
  {
    get => this.GetPropertyValue(t => t.SomeStrPropWithDependency);
    set
    {
      this.SetPropertyValue(t => t.SomeStrPropWithDependency, GetDbStoreFormValue());
        
      string GetDbStoreFormValue()
      {  
         return string.Join(
           ",",
           value
             .Split(new[] { '♦', '♣', '♠'}, StringSplitOptions.RemoveEmptyEntries)
             .Select(x => x.Trim()));
      }
    }
  }
}

由于摘要设置器逻辑中描述的问题基本上是无用的。

我在某些地方错了吗?

我知道如何以其他适当的方式解决这个问题。我只是想知道为什么不调用 setter。

标签: episerver

解决方案


例如,在编辑模式下通过编辑内容来保存内容时,不会通过模型类的属性保存属性值(请记住:即使从代码中删除了内容类型类也可以保存内容)。

之所以调用 setter,SetDefaultValues是因为您的代码使用了类属性。

ContentSaving对于您的情况,在保存内容时连接事件以更改任何属性值可能更合适。


推荐阅读