4

我在限制要在 ContentArea 中插入哪种块时遇到问题。我想要的是 SliderBlock 的 ContentArea 属性只能插入一个 SlideItemBlock。

[ContentType(...)]
public class SlideItemBlock : BlockData
{
    [Required]
    Display(Name = "Image")]
    public virtual string Image { get; set;}
}

[ContentType(...)]
public class SliderBlock : BlockData
{
    [Required]
    [Display(Name = "Slides")]
    public virtual ContentArea Slides { get; set; }
    //Should only accept insertion of SlideItemBlock
}

或者这是实现我试图限制编辑器不拖放错误块类型的错误方法?

到目前为止,我可以创建一个 SliderBlock 并在其中插入一个 SlideItemBlocks。如果然后我将创建的 SliderBlock 插入到新的 SliderBlock 中,我会得到一个永远的循环,它会破坏网站。这就是我想要控制的。

4

5 回答 5

5

如果您使用的是 EPiServer 7.5,则内置限制您可以在内容区域中使用的块。有关详细信息,请查看此博客文章:限制内容区域中允许的类型

博客文章中的代码示例:

  [EditorDescriptorRegistration(TargetType = typeof(ContentArea), UIHint = "Gallery")]
  public class ImageGalleryEditorDescriptor : EditorDescriptor
  {    
     public ImageGalleryEditorDescriptor()    
     {    
        // Setup the types that are allowed to be dragged and dropped into the content        
        // area; in this case only images are allowed to be added.        
        AllowedTypes = new Type[] { typeof(IContentImage) };         

        // Unfortunetly the ContentAreaEditorDescriptor is located in the CMS module        
        // and thus can not be inherited from; these settings are copied from that        
        // descriptor. These settings determine which editor and overlay should be        
        // used by this property in edit mode.        
        ClientEditingClass = "epi-cms.contentediting.editors.ContentAreaEditor";        
        OverlayConfiguration.Add("customType", "epi-cms.widget.overlay.ContentArea");    
    }
  }
于 2013-12-04T20:13:48.177 回答
4

从 EpiServer 8 开始,有一个名为 [AllowedTypes] 的新属性。这是现在限制区块的最佳方式。它克服了 [AvailableContentTypes] 的许多限制。当您将块拖入内容区域时,验证确实有效。

一个示例代码片段是

[AllowedTypes(new []{ typeof(SlideBlock) })]
public virtual ContentArea Slides { get; set; }

这里有一个很好的代码示例How To Restrict The Blocks Allowed Within A Content Area Episerver

这也是 EpiWorld 上的一个http://world.episerver.com/blogs/Ben-McKernan/Dates/2015/2/the-new-and-improved-allowed-types/

于 2015-08-06T21:35:50.620 回答
1

你们中的一些人尚未升级到 7.5,正如 Frederik 建议的那样,我们创建了以下属性来执行此操作。

using EPiServer.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;

namespace xxx.Com.Core.Attributes
{
    [AttributeUsage(AttributeTargets.Property)]
    public class OurAvailableContentTypesAttribute : ValidationAttribute
    {
        public Type[] Include { get; set; }
        public Type[] Exclude { get; set; }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return true;
            }

            if (!(value is ContentArea))
            {
                throw new ValidationException("OurAvailableContentTypesAttribute is intended only for use with ContentArea properties");
            }

            var contentArea = value as ContentArea;

            var notAllowedcontentNames = new List<string>();

            if (contentArea != null)
            {
                if (Include != null)
                {
                    var notAllowedContent = contentArea.Contents.Where(x => !ContainsType(Include, x.GetType()));
                    if (notAllowedContent.Any())
                    {
                        notAllowedcontentNames.AddRange(notAllowedContent.Select(x => string.Format("{0} ({1})", x.Name, x.ContentLink.ID)));
                    }
                }
                if (Exclude != null)
                {
                    var notAllowedContent = contentArea.Contents.Where(x => ContainsType(Exclude, x.GetType()));
                    if (notAllowedContent.Any())
                    {
                        notAllowedcontentNames.AddRange(notAllowedContent.Select(x => string.Format("{0} ({1})", x.Name, x.ContentLink.ID)));
                    }
                }
            }

            if (notAllowedcontentNames.Any())
            {
                ErrorMessage = "contains invalid content items :";
                foreach (var notAllowedcontentName in notAllowedcontentNames)
                {
                    ErrorMessage += " " + notAllowedcontentName + ",";
                }
                ErrorMessage = ErrorMessage.TrimEnd(',');

                return false;
            }
            return true;
        }

        private bool ContainsType(Type[] include, Type type)
        {
            return include.Any(inc => inc.IsAssignableFrom(type));
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var result = base.IsValid(value, validationContext);
            if (result != null && !string.IsNullOrEmpty(result.ErrorMessage))
            {
                result.ErrorMessage = string.Format("{0} {1}", validationContext.DisplayName, ErrorMessage);
            }
            return result;
        }
    }
}

那么这个的用法是

public class OurBlock : BlockData
    {
        [CultureSpecific]
        [Editable(true)]
        [Display(Name = "",
            Description = "",
            GroupName = SiteConstants.GroupNames.ContentArea,
            Order = 1)]
        [OurAvailableContentTypes(Include = new[] { typeof(OurImageBlock)  })]
        public virtual ContentArea ImageContentArea { get; set; }

高温高压

亚当

于 2013-12-18T16:00:48.113 回答
0

创建一个验证类并从 EPiServer.validation 实现 IValidate 接口。对此的验证保留在 PageData 和 BlockData 类之外。

这应该是您正在寻找的

using System.Collections.Generic;
using System.Linq;
using EPiServer.Validation;

public class SliderBlockValidator : IValidate<SliderBlock>
{
    public IEnumerable<ValidationError> Validate(SliderBlock instance)
    {
        var errors = new List<ValidationError>();
        if (instance.Slides != null &&
            instance.Slides.Contents.Any(x => x.GetType().BaseType != typeof (SlideItemBlock)))
        {
            errors.Add(new ValidationError()
                {
                    ErrorMessage = "Only SlideItemBlocks are allowed in this area",
                    PropertyName = "Slides",
                    Severity = ValidationErrorSeverity.Error,
                    ValidationType = ValidationErrorType.StorageValidation
                });
        }

        return errors;
    }
}

更多阅读http://sdkbeta.episerver.com/SDK-html-Container/?path=/SdkDocuments/CMS/7/Knowledge%20Base/Developer%20Guide/Validation/Validation.htm&vppRoot=/SdkDocuments//CMS/7 /知识%20Base/开发者%20指南/

如果您已升级到 EPi 7.5,则可以使用 AllowedTypes 注释

[AllowedTypes(new [] {typeof(SlideItemBlock)})]
public virtual ContentArea Slides { get; set; }

我不知道您是否能够使用后面的解决方案自定义任何消息。有一些已知的限制

  • 在页面上编辑时,限制不适用于叠加。这是一个已修复的错误,将在几周后发布补丁。
  • 没有服务器验证。目前,该属性仅在 UI 中添加限制。我们希望能够尽快添加对服务器验证的支持,这也可以验证您的自定义属性。
  • 在内容区域中创建本地块时不进行验证。如果您使用新功能将本地块添加到内容区域,则当前在创建新块时不会过滤内容类型。

在http://world.episerver.com/Blogs/Linus-Ekstrom/Dates/2013/12/Restriction-of-content-types-in-properties/阅读更多信息

总而言之,第一个解决方案目前是更好的解决方案。

于 2014-01-09T12:12:12.747 回答
-1

您可以向内容区域属性添加验证属性以限制允许的块类型。有关详细示例,请参阅此链接

然后使用 AvailableContentTypes 属性,您可以限制为仅允许 SlideItemBlock 类型。

    [Required]
    [Display(Name = "Slides")]
    [AvailableContentTypes(Include = new []{typeof(SlideItemBlock)})]
    public virtual ContentArea Slides { get; set; }
于 2013-11-27T23:21:38.847 回答