2013-07-04 35 views
1

我製作了帶有ImageUrl屬性和Description屬性的ImageBlock。 ImageUrl是必需的。EPiserver 7在可選塊內需要屬性

[ContentType(
    DisplayName = "Image", 
    Description = "Image with description and caption", 
    GUID = "387A029C-F193-403C-89C9-375A2A6BF028", 
    AvailableInEditMode = false)] 
public class ImageBlock : BaseBlock 
{ 
    [Required] 
    [UIHint(UIHint.Image)]  
    [Display(
     Name = "Image Url", 
     Description = "", 
     GroupName = SystemTabNames.Content, 
     Order = 10)]  
    public virtual Url ImageUrl { get; set; } 

    [Display(
     Name = "Image Description", 
     Description = "A description of the image", 
     GroupName = SystemTabNames.Content, 
     Order = 20)]  
    public virtual string Description { get; set; } 

} 

我的ArticlePage使用ImageBlock作爲它的Image屬性,但它不需要在文章中有圖像。但是,如果編輯選擇了圖像,則應該需要url。

[Display(
    Name = "Image", 
    Description = "", 
    GroupName = SystemTabNames.Content, 
    Order = 20)] 
public virtual ImageBlock Image { get; set; } 

但是,當我創建一個ArticlePage的新實例時,系統會提示您提供EPiServer聲稱所需的ImageUrl。我錯過了什麼嗎?

回答

2

我發現了一種構建自定義屬性的方法,如果設置了除所需的塊屬性之外的任何其他值,則該自定義屬性將檢查是否出現錯誤。所以在我的情況下,如果一個編輯器爲Image Description輸入一個值,並嘗試發佈而不指定ImageUrl,則會顯示一條錯誤消息。

的代碼看起來是這樣的:

public class RequiredBlockPropertyAttribute : ValidationAttribute 
{ 
    private string _failedOnProperty = string.Empty; 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     return ValidateBlock(value, validationContext) 
      ? ValidationResult.Success 
      : new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
    } 

    private bool ValidateBlock(object value, ValidationContext validationContext) 
    { 
     var type = validationContext.ObjectType.BaseType; 
     if (type == null) 
      return true; 

     var properties = type.GetProperties().Where(prop => 
      prop.DeclaringType != null 
      && prop.DeclaringType.IsSubclassOf(typeof(BlockData))); 

     foreach (var property in properties) 
     { 
      if (!property.Name.Equals(validationContext.DisplayName)) 
      { 
       var val = property.GetValue(validationContext.ObjectInstance, null); 
       if (val != null && (value == null || IsDateTimeMinValue(value))) 
       { 
        _failedOnProperty = property.Name; 
        return false; 
       } 
      } 
     } 

     return true; 
    } 

    private static bool IsDateTimeMinValue(object value) 
    { 
     DateTime t; 
     DateTime.TryParse(value.ToString(), out t); 

     return t == DateTime.MinValue; 

    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(ErrorMessageString, name, _failedOnProperty); 
    } 

和塊的使用:

[RequiredBlockProperty(
     ErrorMessage = "{1} cannot be set without {0} defined")] 
    [UIHint(UIHint.Image)]  
    [Display(
     Name = "Image Url", 
     Description = "", 
     GroupName = SystemTabNames.Content, 
     Order = 10)]  
    public virtual Url ImageUrl { get; set; }